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