![]() |
China DOS Union-- Unite DOS · Advance DOS · Grow DOS --Union site: www.cn-dos.net Forum site: www.cn-dos.net/forum |
| Guest | Log in | Register | Members | Search | China DOS Union |
|
中国DOS联盟论坛 The time now is 2026-10-31 06:31 |
47,815 topics / 349,930 posts / today 0 new / 48,290 members |
| DOS开发编程 & 发展交流 (开发室) » Detailed Explanation of DOS Boot Sector Code [repost] |
| Printable Version 2,119 / 0 |
| Floor1 ko20010214 | Posted 2003-06-01 00:00 |
| 版主 Posts 1,628 Credits 7,296 | |
|
If booting from a floppy disk, the DOS boot program is loaded directly into memory by the ROM BIOS; if booting from a hard disk, it is loaded by the hard disk's master boot program. But in both cases it is loaded to the absolute memory address 0000:7C00H. Therefore, the address of the first instruction of the DOS boot program must be 0000:7C00H.
What the DOS boot program does is as follows: 1>adjust the stack position 2>modify the disk parameter table and use the modified table to reset the disk system 3>calculate the position of the first sector of the root directory and the sector position of IO.SYS 4>read in the first sector of the root directory 5>check whether the first two entries of the root directory are IO.SYS and MSDOS.SYS 6>read the first three sectors of the IO.SYS file into memory at 0000:0700H 7>jump to 0000:0700H to execute IO.SYS, boot complete If any error occurs in any of the above steps, it displays the message "Non system disk or disk error..." and, after the user presses any key, attempts to boot again. The DOS boot program below was taken from a hard disk. It displays MSDOS5.0, but DOS's ver command reports version 6.22. The FAT table is naturally 16-bit. Explanation: (DX) indicates the value of register DX logical sector number uses sector 1 of head 0, track 0 as logical sector 0, rather than using the DOS boot sector as logical sector 0. Of course, for a floppy disk the two are the same, but for a hard disk they are different head number that is, the head number track number that is, the cylinder number (for a hard disk) physical sector number jointly specified by head number, track number, and sector number Offset Machine code Symbolic instruction Explanation ============================================================================ == 0000 EB3C JMP 003E ;skip the data area ;the following data is the manufacturer's OEM info and disk BPB table 0000 90 4D 53 44 4F 53-35 2E 30 00 02 08 01 00 .MSDOS5.0..... 0010 02 00 02 00 00 F8 CC 00-3F 00 10 00 3F 00 00 00 ........?...?... 0020 F1 59 06 00 80 00 29 E3-0B 3F 26 53 4C 4D 20 20 .Y....)..?&SLM 0030 20 20 20 20 20 20 46 41-54 31 36 20 20 20 FAT16 ---------------------------------------------------------------------------- -- 003E FA CLI 003F 33C0 XOR AX,AX 0041 8ED0 MOV SS,AX 0041 8ED0 MOV SS,AX 0043 BC007C MOV SP,7C00 ; initialize the stack 0046 16 PUSH SS 0047 07 POP ES ;(ES)=0000H 0048 BB7800 MOV BX,0078 ;the address of interrupt vector 1EH is 0000:0078H 004B 36 SS: ;(SS)=0000H 004C C537 LDS SI, ;take the contents of interrupt vector 1EH into DS:SI 004E 1E PUSH DS ;this interrupt vector points to an 11-byte disk parameter ;table 004F 56 PUSH SI ;after fetching it, push it onto the stack for saving 0050 16 PUSH SS 0051 53 PUSH BX ;save address 0000:0078H 0052 BF3E7C MOV DI,7C3E ;7C3E-7C00=003EH, that is offset 003EH; same ;below 0055 B90B00 MOV CX,000B ;the disk parameter table is 11 bytes total 0058 FC CLD 0059 F3 REPZ 005A A4 MOVSB ;copy the disk parameter table to 0000:7C3EH 005B 06 PUSH ES 005C 1F POP DS ;(DS)=0000H 005D C645FE0F MOV BYTE PTR ,0F ;modify "head settle time" in the parameter table 0061 8B0E187C MOV CX, ;take "sectors per track" from the BPB 0065 884DF9 MOV ,CL ;modify "sectors per track" in the parameter table 0068 894702 MOV ,AX ;(AX)=0000H, modify interrupt vector 1EH ;(segment) 006B C7073E7C MOV WORD PTR ,7C3E ;modify interrupt vector 1EH (offset), this ;way 1EH 006F FB STI ;the contents of the interrupt vector become 0000:7C3EH, pointing to the new disk parameter ;table 0070 CD13 INT 13 ;use the new disk parameter table to reset the disk 0072 7279 JB 00ED ;if error, jump to error handling ---------------------------------------------------------------------------- --- ; the following section calculates sector positions 0074 33C0 XOR AX,AX 0076 3906137C CMP ,AX ;offset 0013H is the total sector count of the DOS partition 007A 7408 JZ 0084 ;if zero, indicates a large hard disk? 007C 8B0E137C MOV CX, ;if not 0, take it out and put it at offset 0020H 0080 890E207C MOV ,CX ;this value is not used by this program; apparently prepared ;for IO.SYS 0084 A0107C MOV AL, ;take the number of FATs 0087 F726167C MUL WORD PTR ;multiply by the number of sectors occupied by one FAT 008B 03061C7C ADD AX, ;add the sectors before the DOS partition (hidden sectors, low ;part) 008F 13161E7C ADC DX, ; high ;part) 0093 03060E7C ADD AX, ;add the number of reserved sectors in the DOS partition (low ;part) 0097 83D200 ADC DX,+00 ; (high ;part) 009A A3507C MOV ,AX ;logical sector number of the first sector of the root directory (low part) 009D 8916527C MOV ,DX ; (high part) 00A1 A3497C MOV ,AX ;logical sector number of the first sector of IO.SYS is stored here (low ;part) 00A4 89164B7C MOV ,DX ; (high ;part) 00A8 B82000 MOV AX,0020 ;each root directory entry occupies 32 bytes 00AB F726117C MUL WORD PTR ;multiply by the number of entries in the root directory 00AF 8B1E0B7C MOV BX, ;take "bytes per sector" 00B3 03C3 ADD AX,BX ;these two instructions are for rounding up 00B5 48 DEC AX 00B6 F7F3 DIV BX ;divide by bytes per sector to get the number of sectors occupied ;by the root directory 00B8 0106497C ADD ,AX ;get the logical sector number of the first sector after the root directory (low ;part) 00BC 83164B7C00 ADC WORD PTR ,+00 ; (high ;part) ---------------------------------------------------------------------------- --- ;the following section looks for the system files IO.SYS and MSDOS.SYS in the root directory 00C1 BB0005 MOV BX,0500 ;offset value of the memory buffer 00C4 8B16527C MOV DX, ;take the logical sector number of the first sector of the root directory (high ;part) 00C8 A1507C MOV AX, ; (low ;part) 00CB E89200 CALL 0160 ;convert logical sector number to physical sector number 00CE 721D JB 00ED ;if error, jump to error handling 00D0 B001 MOV AL,01 00D2 E8AC00 CALL 0181 ;read one sector into memory (the first sector of the root directory) 00D5 7216 JB 00ED ;error handling 00D7 8BFB MOV DI,BX ;start address of the memory buffer 00D9 B90B00 MOV CX,000B ;compare 11 bytes 00DC BEE67D MOV SI,7DE6 ;offset 01E6 contains the string "IO SYS", length 11 ;bytes 00DF F3 REPZ 00E0 A6 CMPSB ;check whether the first entry is IO.SYS 00E1 750A JNZ 00ED ;if not, error 00E3 8D7F20 LEA DI, ;skip 32 bytes and it points to the second entry 00E6 B90B00 MOV CX,000B ;compare 11 bytes 00E9 F3 REPZ 00EA A6 CMPSB ;check whether the second entry is MSDOS.SYS 00EB 7418 JZ 0105 ;if yes, both files have been found, skip error handling ---------------------------------------------------------------------------- -- ;the following section performs error handling 00ED BE9E7D MOV SI,7D9E ;offset 019EH contains the string "Non system disk. ;.." 00F0 E85F00 CALL 0152 ;display the string 00F3 33C0 XOR AX,AX 00F5 CD16 INT 16 ;wait for any key to be pressed 00F7 5E POP SI 00F8 1F POP DS ;get the address of interrupt vector 1EH, 0000:0078H 00F9 8F04 POP 00FB 8F4402 POP ;restore the contents of interrupt vector 1EH 00FE CD19 INT 19 ;bootstrap 0100 58 POP AX 0101 58 POP AX 0102 58 POP AX ;clean up the stack 0103 EBE8 JMP 00ED ;attempt to boot again ---------------------------------------------------------------------------- -- ;the following reads the first 3 sectors of IO.SYS into memory at 0000:0700H 0105 8B471A MOV AX, ;take the starting cluster number of IO.SYS from the first entry ;in the root directory 0108 48 DEC AX 0109 48 DEC AX ;starting cluster number minus two 010A 8A1E0D7C MOV BL, ;take sectors per cluster 010E 32FF XOR BH,BH 0110 F7E3 MUL BX ;(starting cluster number - 2) multiplied by sectors per cluster 0112 0306497C ADD AX, ;after adding, get the logical sector number of the first sector ;of IO.SYS 0116 13164B7C ADC DX, 011A BB0007 MOV BX,0700 ;offset value of the memory buffer 011D B90300 MOV CX,0003 ;initial loop count, read 3 sectors 0120 50 PUSH AX ;push logical sector number (low part) 0121 52 PUSH DX ; (high part) 0122 51 PUSH CX ;push loop counter 0123 E83A00 CALL 0160 ;convert logical sector number to physical sector number 0126 72D8 JB 0100 ;error handling 0128 B001 MOV AL,01 012A E85400 CALL 0181 ;read one sector into the memory buffer 012D 59 POP CX ;pop loop count 012E 5A POP DX 012F 58 POP AX ;pop logical sector number 0130 72BB JB 00ED ;disk read error handling 0132 050100 ADD AX,0001 0135 83D200 ADC DX,+00 ;next sector 0138 031E0B7C ADD BX, ;move buffer pointer by one sector size 013C E2E2 LOOP 0120 ;loop to read three sectors 013E 8A2E157C MOV CH, ;take "disk media descriptor" and pass it to IO.SYS 0142 8A16247C MOV DL, ;take "drive number where the system files are located" 0146 8B1E497C MOV BX, ;take the logical sector number of the first sector of IO.SYS 014A A14B7C MOV AX, 014D EA00007000 JMP 0070:0000 ;execute IO.SYS, boot complete ---------------------------------------------------------------------------- -- ;subroutine to display a string 0152 AC LODSB ;take one character from the string 0153 0AC0 OR AL,AL 0155 7429 JZ 0180 ;if 0, end of string reached, return (shared RET instruction) 0157 B40E MOV AH,0E 0159 BB0700 MOV BX,0007 015C CD10 INT 10 ;display the character 015E EBF2 JMP 0152 ;loop to display the next one ---------------------------------------------------------------------------- ;subroutine to convert a logical sector number into a physical sector number 0160 3B16187C CMP DX, ;these two instructions are to avoid the divisor in the second division ;being 0164 7319 JNB 017F ;0 0166 F736187C DIV WORD PTR ;logical sector number divided by sectors per track, quotient (AX)= ;total tracks 016A FEC2 INC DL ;remainder (DX) plus one is the sector number, because sector ;numbers 016C 88164F7C MOV ,DL ;start from 1, not from 0 0170 33D2 XOR DX,DX 0172 F7361A7C DIV WORD PTR ;total track count (AX) divided again by number of heads, the resulting 0176 8816257C MOV ,DL ;remainder (DX)=head number 017A A34D7C MOV ,AX ;quotient (AX)=track number 017D F8 CLC 017E C3 RET ;normal return 017F F9 STC 0180 C3 RET ;abnormal return ---------------------------------------------------------------------------- - ;subroutine to read one sector 0181 B402 MOV AH,02 ;read function call 0183 8B164D7C MOV DX, ;the required input parameters are as follows: 0187 B106 MOV CL,06 ;(DL)=drive number 0189 D2E6 SHL DH,CL ;(DH)=head number 018B 0A364F7C OR DH, ;(CH)=track number 018F 8BCA MOV CX,DX ;(CL)=sector number (bits 6 and 7 are the high 2 bits of the track ;number) 0191 86E9 XCHG CH,CL ;(AL)=number of sectors to read 0193 8A16247C MOV DL, ;(ES:BX)=start address of the buffer 0197 8A36257C MOV DH, 019B CD13 INT 13 019D C3 RET ---------------------------------------------------------------------------- --- 0190 0D 0A .. 01A0 4E 6F 6E 2D 53 79 73 74-65 6D 20 64 69 73 6B 20 Non-System disk 01B0 6F 72 20 64 69 73 6B 20-65 72 72 6F 72 0D 0A 52 or disk error..R 01C0 65 70 6C 61 63 65 20 61-6E 64 20 70 72 65 73 73 eplace and press 01D0 20 61 6E 79 20 6B 65 79-20 77 68 65 6E 20 72 65 any key when re 01E0 61 64 79 0D 0A 00 49 4F-20 20 20 20 20 20 53 59 ady...IO SY 01F0 53 4D 53 44 4F 53 20 20-20 53 59 53 00 00 55 AA SMSDOS SYS..U. -- (This article was copied using the S-Term article copy script) ================================================== |
|
|
[ Contact the Union admin team -
中国DOS联盟 -
Standard version ] Sponsored by ifanr Inc | © 2001–2023 |