分享
 
 
 

Linux Kernel Internals(1)--Booting

王朝system·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

Next Previous Contents

--------------------------------------------------------------------------------

1. Booting

1.1 Building the Linux Kernel Image

This section explains the steps taken during compilation of the Linux kernel and the output produced at each stage. The build process depends on the architecture so I would like to emphasize that we only consider building a Linux/x86 kernel.

When the user types 'make zImage' or 'make bzImage' the resulting bootable kernel image is stored as arch/i386/boot/zImage or arch/i386/boot/bzImage respectively. Here is how the image is built:

C and assembly source files are compiled into ELF relocatable object format (.o) and some of them are grouped logically into archives (.a) using ar(1).

Using ld(1), the above .o and .a are linked into vmlinux which is a statically linked, non-stripped ELF 32-bit LSB 80386 executable file.

System.map is produced by nm vmlinux, irrelevant or uninteresting symbols are grepped out.

Enter directory arch/i386/boot.

Bootsector asm code bootsect.S is preprocessed either with or without -D__BIG_KERNEL__, depending on whether the target is bzImage or zImage, into bbootsect.s or bootsect.s respectively.

bbootsect.s is assembled and then converted into 'raw binary' form called bbootsect (or bootsect.s assembled and raw-converted into bootsect for zImage).

Setup code setup.S (setup.S includes video.S) is preprocessed into bsetup.s for bzImage or setup.s for zImage. In the same way as the bootsector code, the difference is marked by -D__BIG_KERNEL__ present for bzImage. The result is then converted into 'raw binary' form called bsetup.

Enter directory arch/i386/boot/compressed and convert /usr/src/linux/vmlinux to $tmppiggy (tmp filename) in raw binary format, removing .note and .comment ELF sections.

gzip -9 < $tmppiggy > $tmppiggy.gz

Link $tmppiggy.gz into ELF relocatable (ld -r) piggy.o.

Compile compression routines head.S and misc.c (still in arch/i386/boot/compressed directory) into ELF objects head.o and misc.o.

Link together head.o, misc.o and piggy.o into bvmlinux (or vmlinux for zImage, don't mistake this for /usr/src/linux/vmlinux!). Note the difference between -Ttext 0x1000 used for vmlinux and -Ttext 0x100000 for bvmlinux, i.e. for bzImage compression loader is high-loaded.

Convert bvmlinux to 'raw binary' bvmlinux.out removing .note and .comment ELF sections.

Go back to arch/i386/boot directory and, using the program tools/build, cat together bbootsect, bsetup and compressed/bvmlinux.out into bzImage (delete extra 'b' above for zImage). This writes important variables like setup_sects and root_dev at the end of the bootsector.

The size of the bootsector is always 512 bytes. The size of the setup must be greater than 4 sectors but is limited above by about 12K - the rule is:

0x4000 bytes >= 512 + setup_sects * 512 + room for stack while running bootsector/setup

We will see later where this limitation comes from.

The upper limit on the bzImage size produced at this step is about 2.5M for booting with LILO and 0xFFFF paragraphs (0xFFFF0 = 1048560 bytes) for booting raw image, e.g. from floppy disk or CD-ROM (El-Torito emulation mode).

Note that while tools/build does validate the size of boot sector, kernel image and lower bound of setup size, it does not check the *upper* bound of said setup size. Therefore it is easy to build a broken kernel by just adding some large ".space" at the end of setup.S.

1.2 Booting: Overview

The boot process details are architecture-specific, so we shall focus our attention on the IBM PC/IA32 architecture. Due to old design and backward compatibility, the PC firmware boots the operating system in an old-fashioned manner. This process can be separated into the following six logical stages:

BIOS selects the boot device.

BIOS loads the bootsector from the boot device.

Bootsector loads setup, decompression routines and compressed kernel image.

The kernel is uncompressed in protected mode.

Low-level initialisation is performed by asm code.

High-level C initialisation.

1.3 Booting: BIOS POST

The power supply starts the clock generator and asserts #POWERGOOD signal on the bus.

CPU #RESET line is asserted (CPU now in real 8086 mode).

%ds=%es=%fs=%gs=%ss=0, %cs=0xFFFF0000,%eip = 0x0000FFF0 (ROM BIOS POST code).

All POST checks are performed with interrupts disabled.

IVT (Interrupt Vector Table) initialised at address 0.

The BIOS Bootstrap Loader function is invoked via int 0x19, with %dl containing the boot device 'drive number'. This loads track 0, sector 1 at physical address 0x7C00 (0x07C0:0000).

1.4 Booting: bootsector and setup

The bootsector used to boot Linux kernel could be either:

Linux bootsector (arch/i386/boot/bootsect.S),

LILO (or other bootloader's) bootsector, or

no bootsector (loadlin etc)

We consider here the Linux bootsector in detail. The first few lines initialise the convenience macros to be used for segment values:

--------------------------------------------------------------------------------

29 SETUPSECS = 4 /* default nr of setup-sectors */

30 BOOTSEG = 0x07C0 /* original address of boot-sector */

31 INITSEG = DEF_INITSEG /* we move boot here - out of the way */

32 SETUPSEG = DEF_SETUPSEG /* setup starts here */

33 SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */

34 SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */

--------------------------------------------------------------------------------

(the numbers on the left are the line numbers of bootsect.S file) The values of DEF_INITSEG, DEF_SETUPSEG, DEF_SYSSEG and DEF_SYSSIZE are taken from include/asm/boot.h:

--------------------------------------------------------------------------------

/* Don't touch these, unless you really know what you're doing. */

#define DEF_INITSEG 0x9000

#define DEF_SYSSEG 0x1000

#define DEF_SETUPSEG 0x9020

#define DEF_SYSSIZE 0x7F00

--------------------------------------------------------------------------------

Now, let us consider the actual code of bootsect.S:

--------------------------------------------------------------------------------

54 movw $BOOTSEG, %ax

55 movw %ax, %ds

56 movw $INITSEG, %ax

57 movw %ax, %es

58 movw $256, %cx

59 subw %si, %si

60 subw %di, %di

61 cld

62 rep

63 movsw

64 ljmp $INITSEG, $go

65 # bde - changed 0xff00 to 0x4000 to use debugger at 0x6400 up (bde). We

66 # wouldn't have to worry about this if we checked the top of memory. Also

67 # my BIOS can be configured to put the wini drive tables in high memory

68 # instead of in the vector table. The old stack might have clobbered the

69 # drive table.

70 go: movw $0x4000-12, %di # 0x4000 is an arbitrary value >=

71 # length of bootsect + length of

72 # setup + room for stack;

73 # 12 is disk parm size.

74 movw %ax, %ds # ax and es already contain INITSEG

75 movw %ax, %ss

76 movw %di, %sp # put stack at INITSEG:0x4000-12.

--------------------------------------------------------------------------------

Lines 54-63 move the bootsector code from address 0x7C00 to 0x90000. This is achieved by:

set %ds:%si to $BOOTSEG:0 (0x7C0:0 = 0x7C00)

set %es:%di to $INITSEG:0 (0x9000:0 = 0x90000)

set the number of 16bit words in %cx (256 words = 512 bytes = 1 sector)

clear DF (direction) flag in EFLAGS to auto-increment addresses (cld)

go ahead and copy 512 bytes (rep movsw)

The reason this code does not use rep movsd is intentional (hint - .code16).

Line 64 jumps to label go: in the newly made copy of the bootsector, i.e. in segment 0x9000. This and the following three instructions (lines 64-76) prepare the stack at $INITSEG:0x4000-0xC, i.e. %ss = $INITSEG (0x9000) and %sp = 0x3FF4 (0x4000-0xC). This is where the limit on setup size comes from that we mentioned earlier (see Building the Linux Kernel Image).

Lines 77-103 patch the disk parameter table for the first disk to allow multi-sector reads:

--------------------------------------------------------------------------------

77 # Many BIOS's default disk parameter tables will not recognise

78 # multi-sector reads beyond the maximum sector number specified

79 # in the default diskette parameter tables - this may mean 7

80 # sectors in some cases.

81 #

82 # Since single sector reads are slow and out of the question,

83 # we must take care of this by creating new parameter tables

84 # (for the first disk) in RAM. We will set the maximum sector

85 # count to 36 - the most we will encounter on an ED 2.88.

86 #

87 # High doesn't hurt. Low does.

88 #

89 # Segments are as follows: ds = es = ss = cs - INITSEG, fs = 0,

90 # and gs is unused.

91 movw %cx, %fs # set fs to 0

92 movw $0x78, %bx # fs:bx is parameter table address

93 pushw %ds

94 ldsw %fs:(%bx), %si # ds:si is source

95 movb $6, %cl # copy 12 bytes

96 pushw %di # di = 0x4000-12.

97 rep # don't need cld -> done on line 66

98 movsw

99 popw %di

100 popw %ds

101 movb $36, 0x4(%di) # patch sector count

102 movw %di, %fs:(%bx)

103 movw %es, %fs:2(%bx)

--------------------------------------------------------------------------------

The floppy disk controller is reset using BIOS service int 0x13 function 0 (reset FDC) and setup sectors a

[1] [2] [3] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有