wok-current diff BootProg/stuff/boot32.asm @ rev 25564
Up memtest (6.20)
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Thu May 11 15:58:49 2023 +0000 (14 months ago) |
parents | f40d97a52c42 |
children | dfb00254cc7c |
line diff
1.1 --- a/BootProg/stuff/boot32.asm Mon Apr 03 16:35:42 2023 +0000 1.2 +++ b/BootProg/stuff/boot32.asm Thu May 11 15:58:49 2023 +0000 1.3 @@ -25,6 +25,14 @@ 1.4 ;; instruction and lets the BIOS continue bootstrap. ;; 1.5 ;; ;; 1.6 ;; ;; 1.7 +;; Known Limitation: ;; 1.8 +;; ~~~~~~~~~~~~~~~~~ ;; 1.9 +;; - Need a up to date field bpbHiddenSectors to work in a partition ; ;; 1.10 +;; most formatters don't update it correcly in extended partitions. ;; 1.11 +;; ;; 1.12 +;; - Requires i80386 or better CPU. ;; 1.13 +;; ;; 1.14 +;; ;; 1.15 ;; Known Bugs: ;; 1.16 ;; ~~~~~~~~~~~ ;; 1.17 ;; - All bugs are fixed as far as I know. The boot sector has been tested ;; 1.18 @@ -86,13 +94,15 @@ 1.19 NonMirroredFATs equ 1 ; +18 bytes 1.20 ReadRetry equ 1 ; +7 bytes 1.21 LBA48bits equ 1 ; +15 bytes 1.22 -CHSsupport equ 1 ; +27 bytes max 16MB, 32MB or 8GB 1.23 -CHSupTo32MB equ 1 ; +6 bytes 1.24 -CHSupTo8GB equ 1 ; +14 bytes 1.25 +CHSsupport equ 1 ; +27 bytes max 8GB 1.26 +CHSgeometryCheck equ 1 ; +18 bytes 1.27 +CHSsanityCheck equ 1 ; +5 bytes 1.28 SectorOf512Bytes equ 0 ; -5 bytes 1.29 Always2FATs equ 0 ; -4 bytes 1.30 +WaitForKey equ 0 ; +5 bytes 1.31 1.32 [BITS 16] 1.33 +[CPU 386] 1.34 1.35 ImageLoadSeg equ 60h ; <=07Fh because of "push byte ImageLoadSeg" instructions 1.36 StackSize equ 512 1.37 @@ -115,14 +125,14 @@ 1.38 ;; BPB1 starts here ;; 1.39 ;;;;;;;;;;;;;;;;;;;;;; 1.40 1.41 -bpbBytesPerSector DW 0 ; 0x0B 1.42 -bpbSectorsPerCluster DB 0 ; 0x0D 1.43 -bpbReservedSectors DW 0 ; 0x0E 1.44 -bpbNumberOfFATs DB 0 ; 0x10 1.45 -bpbRootEntries DW 0 ; 0x11 1.46 -bpbTotalSectors DW 0 ; 0x13 1.47 -bpbMedia DB 0 ; 0x15 1.48 -bpbSectorsPerFAT DW 0 ; 0x16 1.49 +bpbBytesPerSector DW 0 ; 0x0B 512, 1024, 2048 or 4096 1.50 +bpbSectorsPerCluster DB 0 ; 0x0D 1, 2, 4, 8, 16, 32, 64 or 128 1.51 +bpbReservedSectors DW 0 ; 0x0E 32 1.52 +bpbNumberOfFATs DB 0 ; 0x10 2 1.53 +bpbRootEntries DW 0 ; 0x11 0 1.54 +bpbTotalSectors DW 0 ; 0x13 0 1.55 +bpbMedia DB 0 ; 0x15 F8, F0 1.56 +bpbSectorsPerFAT DW 0 ; 0x16 0 1.57 bpbSectorsPerTrack DW 0 ; 0x18 1.58 bpbHeadsPerCylinder DW 0 ; 0x1A 1.59 bpbHiddenSectors DD 0 ; 0x1C 1.60 @@ -145,7 +155,7 @@ 1.61 bsreserved times 12 DB 0 ; 0x34 1.62 bsDriveNumber DB 0 ; 0x40 1.63 bsreserved1 DB 0 ; 0x41 1.64 -bsExtendedBootSignature DB 0 ; 0x42 1.65 +bsExtendedBootSignature DB 0 ; 0x42 29 1.66 bsVolumeSerialNumber DD 0 ; 0x43 1.67 bsVolumeLabel times 11 DB " " ; 0x47 "NO NAME " 1.68 bsFileSystemName times 8 DB " " ; 0x52 "FAT32 " 1.69 @@ -200,23 +210,44 @@ 1.70 %else 1.71 push byte main 1.72 %endif 1.73 - push es 1.74 - pop ds 1.75 retf 1.76 1.77 %if ExtraBootSector != 0 1.78 %macro MovedCode 0 1.79 %endif 1.80 main: 1.81 - xor ebx, ebx 1.82 %if ExtraBootSector != 0 1.83 add al, 32 1.84 - mov es, ax 1.85 - mov eax, [bx(bpbHiddenSectors)] 1.86 - inc eax 1.87 - %if LBA48bits != 0 1.88 - mov [bx(HiLBA)], bx 1.89 - %endif 1.90 + push ax 1.91 +%endif 1.92 +;;;;;;;;;;;;;;;;;;;;;;;;;; 1.93 +;; Get drive parameters ;; 1.94 +;; Update heads count ;; 1.95 +;; for current BIOS ;; 1.96 +;;;;;;;;;;;;;;;;;;;;;;;;;; 1.97 + 1.98 +%if CHSgeometryCheck != 0 1.99 + mov ah, 8 ; update AX,BL,CX,DX,DI, and ES registers 1.100 + int 13h ; may destroy SI,BP, and DS registers 1.101 +%endif 1.102 + push cs 1.103 + pop ds 1.104 + xor ebx, ebx 1.105 + 1.106 +%if CHSgeometryCheck != 0 1.107 + and cx, byte 3Fh 1.108 + je BadParams ; verify updated and validity 1.109 + mov [bx(bpbSectorsPerTrack)], cx 1.110 + mov cl, dh 1.111 + inc cx 1.112 + mov [bx(bpbHeadsPerCylinder)], cx 1.113 + xor cx, cx 1.114 +BadParams: 1.115 +%endif 1.116 +%if ExtraBootSector != 0 1.117 + pop es 1.118 + mul ebx ; edx:eax = 0 1.119 + inc ax 1.120 call ReadSectorBoot 1.121 push ds 1.122 pop ss 1.123 @@ -258,9 +289,9 @@ 1.124 mov cl, NameLength 1.125 mov si, ProgramName ; ds:si -> program name 1.126 repe cmpsb 1.127 -%if CheckAttrib != 0 1.128 VolumeLabel equ 8 1.129 SubDirectory equ 10h 1.130 +%if CheckAttrib != 0 1.131 jnz SkipFindName 1.132 test byte [es:di], VolumeLabel+SubDirectory 1.133 SkipFindName: 1.134 @@ -277,6 +308,10 @@ 1.135 ErrFind: 1.136 call Error ; end of root directory (dir end reached) 1.137 db "File not found." 1.138 +%if ExtraBootSector != 0 1.139 +%endm 1.140 +%macro BootFileName 0 1.141 +%endif 1.142 FindNameFound: 1.143 push word [es:di+14h-11] 1.144 push word [es:di+1Ah-11] 1.145 @@ -331,7 +366,7 @@ 1.146 jmp short Run 1.147 %if ExtraBootSector != 0 1.148 %endm 1.149 -%macro BootFileName 0 1.150 +%macro BootCode 0 1.151 %endif 1.152 1.153 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.154 @@ -400,9 +435,11 @@ 1.155 int 10h 1.156 cmp al, '.' 1.157 jne puts 1.158 +%if WaitForKey != 0 1.159 cbw 1.160 int 16h ; wait for a key... 1.161 int 19h ; bootstrap 1.162 +%endif 1.163 1.164 Stop: 1.165 hlt 1.166 @@ -428,7 +465,7 @@ 1.167 mov bp, [bx(bpbBytesPerSector)] 1.168 shr bp, 4 ; bp = paragraphs per sector 1.169 %endif 1.170 - mov dx, 1 ; adjust LBA for next sector 1.171 + inc eax ; adjust LBA for next sector 1.172 inc cx 1.173 loop ReadSectorLBA 1.174 1.175 @@ -444,17 +481,17 @@ 1.176 1.177 imul si, dx, byte 4 ; si=entry # in sector, clear C 1.178 %if NonMirroredFATs != 0 1.179 - cwde 1.180 + cdq 1.181 or dl, byte [bx(bsExtendedFlags)] 1.182 jns MirroredFATs ; Non-mirrored FATs ? 1.183 and dl, 0Fh 1.184 imul edx, dword [bx(bsSectorsPerFAT32)] ; we need to read the active one 1.185 add eax, edx 1.186 MirroredFATs: 1.187 - cwde 1.188 + cdq 1.189 %else 1.190 %if LBA48bits != 0 1.191 - xor dx, dx 1.192 + cdq 1.193 %endif 1.194 %endif 1.195 call ReadSectorLBAfromFAT ; read 1 FAT32 sector 1.196 @@ -475,45 +512,48 @@ 1.197 movzx ecx, byte [bx(bpbSectorsPerCluster)] ; 8..128 1.198 mul ecx ; edx:eax=sector number in data area 1.199 add eax, edi 1.200 -%if LBA48bits != 0 1.201 - adc dx, bx 1.202 -%endif 1.203 1.204 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.205 ;; Reads a sector form the start of FAT ;; 1.206 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.207 1.208 ReadSectorLBAfromFAT: 1.209 - add eax, [bx(bpbHiddenSectors)] 1.210 %if LBA48bits != 0 1.211 - adc dx, bx 1.212 - mov word [bx(HiLBA)], dx 1.213 + push dx 1.214 %endif 1.215 mov dx, [bx(bpbReservedSectors)] 1.216 + add eax, edx 1.217 +ReadSectorLBAfromFAT: 1.218 + pop dx ; 16TB FAT32 max 1.219 + adc dx, bx 1.220 +ReadSectorBoot: 1.221 + mov [bx(HiLBA)], dx 1.222 +%endif 1.223 1.224 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.225 ;; Reads a sector using BIOS Int 13h fn 42h ;; 1.226 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.227 -;; Input: EAX = LBA ;; 1.228 -;; CX = sector count ;; 1.229 +;; Input: EAX+EDX = LBA ;; 1.230 ;; ES:BX -> buffer address ;; 1.231 +;; Keep: ESI = next cluster ;; 1.232 +;; EDI = data cluster ;; 1.233 +;; BP = paragraphs / sector ;; 1.234 +;; CX = sector count ;; 1.235 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.236 1.237 ReadSectorLBA: 1.238 - add eax, edx 1.239 %if LBA48bits != 0 1.240 - adc word [bx(HiLBA)], bx 1.241 + mov dx, [bx(HiLBA)] 1.242 +%else 1.243 + xor dx, dx ; 2TB FAT32 max 1.244 +ReadSectorBoot: 1.245 %endif 1.246 -ReadSectorBoot: 1.247 - mov dx, [bx(DriveNumber)] ; restore BIOS boot drive number 1.248 - pusha 1.249 + pushad 1.250 1.251 - push bx 1.252 -%if LBA48bits != 0 1.253 - push word [bx(HiLBA)] ; 48-bit LBA 1.254 -%else 1.255 - push bx 1.256 -%endif 1.257 + add eax, [bx(bpbHiddenSectors)] 1.258 + adc dx, bx ; 2TB partition offset max 1.259 + 1.260 + push edx 1.261 push eax 1.262 push es 1.263 push bx 1.264 @@ -521,58 +561,56 @@ 1.265 push byte 16 ; packet size byte = 16, reserved byte = 0 1.266 1.267 %if CHSsupport != 0 1.268 - %if CHSupTo8GB != 0 1.269 - push eax 1.270 - pop cx ; save low LBA 1.271 - pop ax ; get high LBA 1.272 - cwd ; clear dx (assume LBA offset <1TB) 1.273 - idiv word [bx(bpbSectorsPerTrack)] ; up to 8GB disks, avoid divide error 1.274 - 1.275 - xchg ax, cx ; restore low LBA, save high LBA / SPT 1.276 - %else 1.277 ; Busybox mkdosfs creates fat32 for floppies. 1.278 ; Floppies may support CHS only. 1.279 - %if CHSupTo32MB != 0 1.280 - xor dx, dx ; clear dx (LBA offset <32MB) 1.281 - %else 1.282 - cwd ; clear dx (LBA offset <16MB) 1.283 - %endif 1.284 - xor cx, cx ; high LBA / SPT = 0 1.285 + %if LBA48bits != 0 1.286 +; The following check is only useful with bpbSectorsPerTrack < 8 with disk > 4TB... 1.287 +; setnz dl ; force cylinder overflow without divide error 1.288 %endif 1.289 - idiv word [bx(bpbSectorsPerTrack)] 1.290 - ; ax = LBA / SPT 1.291 - ; dx = LBA % SPT = sector - 1 1.292 + movzx ecx, word [bx(bpbSectorsPerTrack)] 1.293 + idiv ecx 1.294 + ; eax = LBA / SPT 1.295 + ; edx = LBA % SPT = sector - 1 1.296 inc dx 1.297 - 1.298 - xchg cx, dx ; restore high LBA / SPT, save sector no. 1.299 - idiv word [bx(bpbHeadsPerCylinder)] 1.300 - ; ax = (LBA / SPT) / HPC = cylinder 1.301 - ; dx = (LBA / SPT) % HPC = head 1.302 + push dx ; save sector no. 1.303 + cdq 1.304 + mov cx, word [bx(bpbHeadsPerCylinder)] 1.305 + idiv ecx 1.306 + pop cx 1.307 + ; eax = (LBA / SPT) / HPC = cylinder 1.308 + ; dl = (LBA / SPT) % HPC = head 1.309 1.310 xchg ch, al ; clear al 1.311 ; ch = LSB 0...7 of cylinder no. 1.312 - %if CHSupTo8GB != 0 || CHSupTo32MB != 0 1.313 - shr ax, 2 1.314 - or cl, al 1.315 + %if CHSsanityCheck != 0 1.316 + shl eax, 6 1.317 + %else 1.318 + shl ax, 6 1.319 + %endif 1.320 + or cl, ah 1.321 ; cl = MSB 8...9 of cylinder no. + sector no. 1.322 - %endif 1.323 mov dh, dl 1.324 ; dh = head no. 1.325 - mov dl, [bx(DriveNumber)] ; restore BIOS boot drive number 1.326 %endif 1.327 1.328 ReadSectorRetry: 1.329 + mov dl, [bx(DriveNumber)] ; restore BIOS boot drive number 1.330 mov si, sp 1.331 mov ah, 42h ; ah = 42h = extended read function no. 1.332 int 13h ; extended read sectors (DL, DS:SI) 1.333 jnc ReadSuccess ; CF = 0 if no error 1.334 1.335 %if CHSsupport != 0 1.336 + %if CHSsanityCheck != 0 1.337 + cmp eax, 0FFFFh ; max cylinder = 1023 1.338 + ja SkipCHS 1.339 + %endif 1.340 mov ax, 201h ; al = sector count = 1 1.341 ; ah = 2 = read function no. 1.342 int 13h ; read sectors (AL, CX, DX, ES:BX) 1.343 1.344 jnc ReadSuccess ; CF = 0 if no error 1.345 +SkipCHS: 1.346 %endif 1.347 %if ReadRetry != 0 1.348 %if CHSsupport != 0 1.349 @@ -592,11 +630,13 @@ 1.350 ReadSuccess: 1.351 1.352 popa ; sp += 16 1.353 - popa 1.354 + popad 1.355 + mov dx, [bx(DriveNumber)] ; restore BIOS boot drive number 1.356 ret 1.357 1.358 %if ExtraBootSector != 0 1.359 MovedCode 1.360 + BootCode 1.361 %endif 1.362 1.363 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.364 @@ -616,11 +656,11 @@ 1.365 ;; End of the sector ID ;; 1.366 ;;;;;;;;;;;;;;;;;;;;;;;;;; 1.367 1.368 - dw 0AA55h ; BIOS checks for this ID 1.369 + dw 0AA55h ; BIOS checks for this ID 1.370 1.371 %if ExtraBootSector != 0 1.372 - dd 61415252h ; "RRaA" 1.373 - BootFileName 1.374 - times (996-($-$$)) db 0 1.375 -; dd 41617272h ; "rrAa" 1.376 + dd 61415252h ; "RRaA" 1.377 + BootFileName 1.378 + times (996-($-$$)) db 0 1.379 +; dd 41617272h ; "rrAa" 1.380 %endif