Ignore:
Timestamp:
Apr 8, 2017, 12:27:13 AM (8 years ago)
Author:
Ben Rietbroek
Message:

Improved method of locating the Master LVM-sector [v1.1.1-testing]

This potentially fixes 'LOAD ERROR' issues with USB sticks present.

The old method assumed the fixed locations 255,127 and 63, expressed
as non-LBA sectors but converted to LBA when doing the sector loads.
The above locations are *OS/2 Geometry* and have actually no relation
to how the BIOS views the geometery of the disk.

Then there was also a bug, where the 63 value was overwritten with the
BIOS SPT queried using INT13X, to try that value in case none of the
above had a valid LVM-sector. To make a long story short: this could
go very bad when USB sticks were present at boot time or with disks
present that use OS/2 extended geometry and normal geometry in some
particular order.

The new method uses LBA addressing to scan from LBA sector 254 downwards
and, when a valid LVM-sector is found, also veryfies it is found at the
LBA location it should be, which is derived from the OS/2 geometry of
the LVM-sector itself.

Note that this new method is not used in this commit yet, but will be
integrated in upcoming commits that improve more disk handling aspects.

CAUTION:
This is a testbuild !
AirBoot uses the BIOS to access disks and a small coding error can trash
partition tables or other vital disk structures. You are advised to make
backups of TRACK0 and EBRs before using this testbuild. More info at:
https://rousseaux.github.io/netlabs.air-boot/pdf/AirBoot-v1.1.0-manual.pdf

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/bootcode/regular/driveio.asm

    r114 r115  
    852852
    853853DriveIO_WriteSectorLBA      EndP
     854
     855
     856
     857
     858;##############################################################################
     859;# The Master LVM sector is *not* necessarily located at the end of the BIOS
     860;# view of TRACK0. Its location depends on the *OS/2 geometry* active when the
     861;# disk was partitioned. For disks < 502MiB this will most likely be LBA sector
     862;# 62, but for disks >502MiB, *extended* OS/2 geometry was used and DANIS506
     863;# uses SPT=127 for disks < 1TiB while IBMS506 uses  SPT=255.
     864;# When a huge disk < 1TiB was partitioned with IBMS506, thus using SPT=255,
     865;# and the driver was later changed to DANIS506, DANI uses SPT=255, eventhough
     866;# the disk < 1TiB. Whether it is DANI that is LVM aware or something else
     867;# (maybe LVM itself) that makes DANI use the correct geometry has yet to be
     868;# investigated.
     869;#
     870;# Related geometry issues are also present with USB sticks, which can get
     871;# assigned a geometry by OS/2, which can depend if the stick was partitioned
     872;# on foreign systems or not, or even OS/2 manufacturing a geometry that is not
     873;# the same as the BIOS reports to us here. In both cases, fixed disks and
     874;# removable disks, the geometry recorded in the BPB of a partition can also
     875;# influence the geometry that OS/2 assigns. This is the case when 'preparing'
     876;# disks for LVM use, in which case BPB values could be incorporated.
     877;#
     878;# What this all boils down to, is that the geometry reported by the BIOS is
     879;# of no practical use, especially not when taking BIOS USB MSD emulation into
     880;# account. These are among the reasons why AirBoot needs to use LBA addressing
     881;# when handling LVM stuff and why LBA use cannot be disabled in the SETUP
     882;# anymore.
     883;#
     884;# So, a Master LVM sector can be present on any sector from LBA 254 downwards
     885;# and the only way to locate the correct one is to scan all the way down and,
     886;# if one is found, do proper validation on its values, because it may also be
     887;# a 'phantom' LVM sector left over from previous partition layouts.
     888;# Most of such 'phantoms' can be filtered out by verifying the location of
     889;# the found sector against the OS/2 geometry it specifies itself, which means
     890;# it must be located at the LBA of the SPT-1 it specifies.
     891;##############################################################################
     892;# ACTION   : Locates the Master LVM sector on the specified disk
     893;# ----------------------------------------------------------------------------
     894;# EFFECTS  : None
     895;# ----------------------------------------------------------------------------
     896;# IN       : DL    - BIOS disk number of drive to search
     897;# ----------------------------------------------------------------------------
     898;# OUT      : CF=1  - found
     899;#          : BX:AX - LBA address of LVM sector if found, 0 otherwise
     900;##############################################################################
     901DriveIO_LocateMasterLVMSector   Proc    Near    uses cx dx si di ds es
     902
     903IFDEF   AUX_DEBUG
     904        IF 1
     905        pushf
     906        pusha
     907            push    si
     908            mov     si, offset $+5
     909            jmp     @F
     910            db      10,'DriveIO_LocateMasterLVMSector:',10,0
     911            @@:
     912            call    AuxIO_Print
     913            pop     si
     914            ;~ call    DEBUG_DumpRegisters
     915            ;~ call    AuxIO_DumpSector
     916            ;~ call    AuxIO_DumpParagraph
     917            ;~ call    AuxIO_TeletypeNL
     918        popa
     919        popf
     920        ENDIF
     921ENDIF
     922
     923        ; LBA address to start scanning down from
     924        mov     cx, 255
     925
     926        ; Make sure ES==DS
     927        push    ds
     928        pop     es
     929
     930    DriveIO_LocateMasterLVMSector_next:
     931        clc                             ; Indicate Master LVM sector not found
     932        jcxz    DriveIO_LocateMasterLVMSector_done
     933
     934        ; Clear the sector buffer
     935        mov     bx, cx                  ; Save our precious sector LBA
     936        mov     cx, 100h                ; Clear 256 words is 512 bytes
     937        mov     di, offset [TmpSector]  ; Offset of buffer
     938        xor     ax, ax                  ; Value to sture
     939        cld                             ; Increment DI each time
     940        rep     stosw                   ; Store the value
     941        mov     cx, bx                  ; Restore our precious sector LBA
     942
     943        ; Now read the LBA sector specified in CX
     944        xor     bx, bx                  ; LBA high, CX already has LBA low
     945        mov     di, ds                  ; Segment of temp buffer
     946        mov     si, offset [TmpSector]  ; Offset of temp buffer
     947        call    DriveIO_ReadSectorLBA   ; Read the sector
     948        lahf
     949        dec     cx                      ; Prepare LBA of next sector to read
     950        sahf                            ; Restore CF
     951        ; No need to do any LVM sector validation when read error, read next
     952        jc      DriveIO_LocateMasterLVMSector_next
     953
     954        ; See if the read sector has a valid signature and checksum
     955        call    LVM_ValidateSector
     956
     957        ; NC indicates invalid or none-LVM sector, read next
     958        jnc     DriveIO_LocateMasterLVMSector_next
     959
     960        ; We have found a valid LVM sector !
     961        ; So it contains the OS/2 geometry for the disk.
     962        ; That means this LVM sector itself must be located on the last sector
     963        ; of the SPT value its OS/2 geometery specifies, which, in LBA terms
     964        ; is LVM SPT-1 -- let's check that...
     965        mov     bx, offset [TmpSector]          ; Offset of the loaded LVM sector
     966        mov     al, [bx+LocLVM_Secs]            ; Get the LVM SPT value (<=255)
     967        dec     al                              ; Adjust to LVM LBA
     968        mov     ah, cl                          ; Get next LVM LBA to search
     969        inc     ah                              ; This one was found here
     970        cmp     al, ah                          ; If same, LVM LBA location OK
     971        call    DEBUG_DumpRegisters
     972        jne     DriveIO_LocateMasterLVMSector_next
     973
     974        ; The LVM sector we found is at the location it should be on disk,
     975        ; so it's almost 99% sure this is the correct one.
     976        ; Now we should compare the start and sizes of the partitions in the
     977        ; MBR with the partitions specified in this LVM record.
     978        ; We'll implement that later after some more research.
     979        ; For now we assume this is the correct Master LVM sector for the disk.
     980        inc     cx      ; CX was prepared to read next, correct that
     981        stc             ; Indicate we have found a Master LVM sector
     982
     983    DriveIO_LocateMasterLVMSector_done:
     984        mov     bx, 0   ; A Master LVM sector always has high LBA=0
     985        mov     ax, cx  ; Low LBA of Master LVM sector
     986
     987        ; We leave it up to the caller to store the value in a proper place
     988        ret
     989DriveIO_LocateMasterLVMSector   EndP
    854990
    855991
Note: See TracChangeset for help on using the changeset viewer.