Linux Kernel Internals cld ljmp SINITSEG,Sgo o远yo thVe op o in the vector table. The old stack might have clobbered the movw s0x4000-12,d 456 多ax,8d ax and es already contain INITSEG put stack at INITSEG:0x4000-12. The lines 54-63 move the bootsector code from address Ox7C00 to 0x90000.This is achieved by 1 set %ds:%si to SBOOTSEG:0(0x7C0:0=0x7C00) 2.set %es:%di to SINITSEG:0(0x9000:0=0x90000) 3.set the number of 16bit words in %cx(256 words=512 bytes=1 sector) 4.clear DF(direction)flag in EFLAGS to auto-increment addresses(cld) 5.go ahead and copy 512 bytes(rep movsw) The reason this code does not use"rep movsd"is intentional (hint-codel6). The line 64 jumps to the label "go:"in the newly made copy of the bootsector,i.e.in the segment 0x9000. This and the following three instructions(lines 64-76)prepare the stack at SINITSEG:0x4000-12,i.e.%ss= SINITSEG(0x9000)and %sp=0x3FEE(0x4000-12).This is where the limit on setup size comes from that we mentioned earlier(see Building the Linux Kernel Image). The lines77-103 patch the disk parameter table for the first disk to allow multi-sector reads in RAM most we ighdoean't hurt.tow does. Segmentareafo11ow:dsesscs-INITSEG,fs0, 91 movw set fs to 0 1.4 Booting:bootsector and setup 561 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. The lines 54−63 move the bootsector code from address 0x7C00 to 0x90000. This is achieved by: 1. set %ds:%si to $BOOTSEG:0 (0x7C0:0 = 0x7C00) 2. set %es:%di to $INITSEG:0 (0x9000:0 = 0x90000) 3. set the number of 16bit words in %cx (256 words = 512 bytes = 1 sector) 4. clear DF (direction) flag in EFLAGS to auto−increment addresses (cld) 5. go ahead and copy 512 bytes (rep movsw) The reason this code does not use "rep movsd" is intentional (hint − .code16). The line 64 jumps to the label "go:" in the newly made copy of the bootsector, i.e. in the segment 0x9000. This and the following three instructions (lines 64−76) prepare the stack at $INITSEG:0x4000−12, i.e. %ss = $INITSEG (0x9000) and %sp = 0x3FEE (0x4000−12). This is where the limit on setup size comes from that we mentioned earlier (see Building the Linux Kernel Image). The 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 recognize 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 Linux Kernel Internals 1.4 Booting: bootsector and setup 5