VirtualBox

Changeset 102270 in vbox


Ignore:
Timestamp:
Nov 23, 2023 12:40:38 AM (12 months ago)
Author:
vboxsync
Message:

bs3kit: Fixed some issues with loading of a fake 63.5 MB floppy. Added optional checksumming of the images we load (disabled by default, as it's slow in IEM). bugref:10371

Location:
trunk/src/VBox/ValidationKit/bootsectors/bs3kit
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/VBoxBs3Linker.cpp

    r102181 r102270  
    6767    uint32_t        uLoadAddr;
    6868    uint32_t        offInImage;
    69     void           *pvBits;
     69    uint8_t        *pbBits;
    7070    RTLDRMOD        hLdrMod;
    7171} BS3LNKINPUT;
     
    8888    char            szName[RT_FLEXIBLE_ARRAY];
    8989} BS3LNKIMPORTNAME;
    90 
    9190
    9291
     
    121120}
    122121
     122
    123123/**
    124124 * @callback_method_impl{FNRTSTRSPACECALLBACK}
     
    216216    if (cbImage != ~(size_t)0)
    217217    {
    218         void *pvBits = RTMemAlloc(cbImage);
    219         if (pvBits)
     218        void *pbBits = (uint8_t *)RTMemAlloc(cbImage);
     219        if (pbBits)
    220220        {
    221221            BS3LNKIMPORTSTATE State = { pOutput, NULL, 0, 0, 0 };
    222             rc = RTLdrGetBits(hLdrMod, pvBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmImportCallback, pOutput);
     222            rc = RTLdrGetBits(hLdrMod, pbBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmImportCallback, pOutput);
    223223            if (RT_SUCCESS(rc))
    224224            {
     
    254254                /* Populate the string table with exports. */
    255255                size_t const offExportStrings = State.cbStrings;
    256                 rc = RTLdrEnumSymbols(hLdrMod, 0, pvBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmOutputExportStrings, &State);
     256                rc = RTLdrEnumSymbols(hLdrMod, 0, pbBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmOutputExportStrings, &State);
    257257                size_t const cbStrings        = State.cbStrings;
    258258                if (RT_SUCCESS(rc) && cbStrings < _64K)
     
    271271                            "start_exports:\n");
    272272                    State.cbStrings = offExportStrings;
    273                     rc = RTLdrEnumSymbols(hLdrMod, 0, pvBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmOutputExportTable, &State);
     273                    rc = RTLdrEnumSymbols(hLdrMod, 0, pbBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmOutputExportTable, &State);
    274274                    AssertRC(rc);
    275275                    fprintf(pOutput, "\n");
     
    291291                            "        dd      start_strings - start_entry\n"
    292292                            "        dd      1               ; offDllName\n"
     293                            "        dd      0               ; uChecksum\n"
    293294                            , BS3HIGHDLLENTRY_MAGIC, cbImage, cbImage, State.cImports, State.cExports, (unsigned)cbStrings);
    294295                    rcExit = RTEXITCODE_SUCCESS;
     
    301302            else
    302303                rcExit = RTMsgErrorExitFailure("RTLdrGetBits failed: %Rrc", rc);
    303             RTMemFree(pvBits);
     304            RTMemFree(pbBits);
    304305        }
    305306        else
     
    399400        {
    400401            paInputs[i].cbBits = RT_ALIGN_32(paInputs[i].cbFile, 512);
    401             paInputs[i].pvBits = RTMemAllocZ(paInputs[i].cbBits);
    402             if (!paInputs[i].pvBits)
     402            paInputs[i].pbBits = (uint8_t *)RTMemAllocZ(paInputs[i].cbBits);
     403            if (!paInputs[i].pbBits)
    403404                return RTMsgErrorExitFailure("Out of memory (%#x)\n", paInputs[i].cbBits);
    404             size_t cbRead = fread(paInputs[i].pvBits, sizeof(uint8_t), paInputs[i].cbFile, paInputs[i].pFile);
     405            size_t cbRead = fread(paInputs[i].pbBits, sizeof(uint8_t), paInputs[i].cbFile, paInputs[i].pFile);
    405406            if (cbRead != paInputs[i].cbFile)
    406407                return RTMsgErrorExitFailure("Error reading '%s' (got %d bytes, wanted %u).",
     
    423424
    424425            paInputs[i].cbBits = RT_ALIGN_32((uint32_t)cbImage, 4096); /* Bs3InitHighDlls_rm depend on the 4KiB alignment.  */
    425             paInputs[i].pvBits = RTMemAllocZ(paInputs[i].cbBits);
    426             if (!paInputs[i].pvBits)
     426            paInputs[i].pbBits = (uint8_t *)RTMemAllocZ(paInputs[i].cbBits);
     427            if (!paInputs[i].pbBits)
    427428                return RTMsgErrorExitFailure("Out of memory (%#x)\n", paInputs[i].cbBits);
    428429
    429430            /* Locate the entry for this high dll in the base image. */
    430             BS3HIGHDLLENTRY *pHighDllEntry = LocateHighDllEntry((uint8_t *)paInputs[1].pvBits, paInputs[1].cbFile,
     431            BS3HIGHDLLENTRY *pHighDllEntry = LocateHighDllEntry(paInputs[1].pbBits, paInputs[1].cbFile,
    431432                                                                RTPathFilename(paInputs[i].pszFile));
    432433            AssertReturn(pHighDllEntry, RTEXITCODE_FAILURE);
     434            if (   pHighDllEntry->cbLoaded  != paInputs[i].cbBits
     435                || pHighDllEntry->cbInImage != paInputs[i].cbBits)
     436                return RTMsgErrorExitFailure("HighDllEntry fields cbLoaded=%#x and/or cbInImage=%#x differs from cbBits=%#x!",
     437                                             pHighDllEntry->cbLoaded, pHighDllEntry->cbInImage, paInputs[i].cbBits);
    433438
    434439            /* Get the fixed up image bits. */
    435             rc = RTLdrGetBits(paInputs[i].hLdrMod, paInputs[i].pvBits, uHiLoadAddr, ResolveHighDllImportCallback, pHighDllEntry);
     440            rc = RTLdrGetBits(paInputs[i].hLdrMod, paInputs[i].pbBits, uHiLoadAddr, ResolveHighDllImportCallback, pHighDllEntry);
    436441            if (RT_FAILURE(rc))
    437442                return RTMsgErrorExitFailure("RTLdrGetBits failed on '%s': %Rrc", paInputs[i].pszFile, rc);
     
    445450                const char * const pszSymbol = (const char *)&pszzStrings[paExports[iExport].offName];
    446451                RTLDRADDR          Value     = 0;
    447                 rc = RTLdrGetSymbolEx(paInputs[i].hLdrMod, paInputs[i].pvBits, uHiLoadAddr, UINT32_MAX, pszSymbol, &Value);
     452                rc = RTLdrGetSymbolEx(paInputs[i].hLdrMod, paInputs[i].pbBits, uHiLoadAddr, UINT32_MAX, pszSymbol, &Value);
    448453                if (RT_SUCCESS(rc))
    449454                    paExports[iExport].offFlat = (uint32_t)Value;
     
    456461            pHighDllEntry->offInImage = off;
    457462            pHighDllEntry->uLoadAddr  = uHiLoadAddr;
     463            pHighDllEntry->uChecksum  = Bs3CalcChecksum(BS3_CALC_CHECKSUM_INITIAL_VALUE, paInputs[i].pbBits, paInputs[i].cbBits);
    458464            paInputs[i].uLoadAddr     = uHiLoadAddr;
    459465            uHiLoadAddr += paInputs[i].cbBits;
     466#if 0
     467            RTMsgInfo("offInImage=%#RX32 / sector #%u LB %#x\n", paInputs[i].offInImage, paInputs[i].offInImage / 512, paInputs[i].cbBits);
     468            uint32_t uChecksum = BS3_CALC_CHECKSUM_INITIAL_VALUE;
     469            for (unsigned j = 0, cSectors = paInputs[i].cbBits / 512; j < cSectors; j++)
     470                RTMsgInfo("sector #%u: %#010RX32 %#010RX32\n", j,
     471                          uChecksum = Bs3CalcChecksum(uChecksum, &paInputs[i].pbBits[j * 512], 512),
     472                          Bs3CalcChecksum(BS3_CALC_CHECKSUM_INITIAL_VALUE, &paInputs[i].pbBits[j * 512], 512));
     473            if (uChecksum != pHighDllEntry->uChecksum)
     474                return RTMsgErrorExitFailure("Checksum calculation error: %#x, expected %#x", uChecksum, pHighDllEntry->uChecksum);
     475#endif
    460476        }
    461477        Assert(!(off & 0x1ff));
     
    467483
    468484    /*
    469      * Patch the BPB with base image sector count.
     485     * Patch the BPB with base image sector count and image checksum.
    470486     */
    471     PBS3BOOTSECTOR pBs = (PBS3BOOTSECTOR)paInputs[0].pvBits;
     487    PBS3BOOTSECTOR pBs = (PBS3BOOTSECTOR)paInputs[0].pbBits;
    472488    if (   memcmp(pBs->abLabel,  RT_STR_TUPLE(BS3_LABEL))  == 0
    473489        && memcmp(pBs->abFSType, RT_STR_TUPLE(BS3_FSTYPE)) == 0
    474490        && memcmp(pBs->abOemId,  RT_STR_TUPLE(BS3_OEMID))  == 0)
     491    {
    475492        pBs->cLargeTotalSectors = (paInputs[0].cbBits + paInputs[1].cbBits) / 512;
     493        pBs->cTotalSectors      = RT_MIN(paInputs[1].cbBits, _1M) / 512;
     494        pBs->dwSerialNumber     = Bs3CalcChecksum(BS3_CALC_CHECKSUM_INITIAL_VALUE, paInputs[1].pbBits,
     495                                                  pBs->cTotalSectors * 512); /* dwSerialNumber is misaligned */
     496    }
    476497    else
    477498        return RTMsgErrorExitFailure("Didn't find magic strings in the first file (%s).", paInputs[0].pszFile);
     
    483504    {
    484505        Assert(ftell(pOutput) == (int32_t)paInputs[i].offInImage);
    485         ssize_t cbWritten = fwrite(paInputs[i].pvBits, sizeof(uint8_t), paInputs[i].cbBits, pOutput);
     506        ssize_t cbWritten = fwrite(paInputs[i].pbBits, sizeof(uint8_t), paInputs[i].cbBits, pOutput);
    486507        if (cbWritten != (ssize_t)paInputs[i].cbBits)
    487508            return RTMsgErrorExitFailure("fwrite failed (%zd vs %zu)", cbWritten, paInputs[i].cbBits);
     
    588609                                    if (cSectors > 0)
    589610                                    {
    590                                         aInputs[cInputs].pvBits  = NULL;
     611                                        aInputs[cInputs].pbBits  = NULL;
    591612                                        aInputs[cInputs].cbBits  = 0;
    592613                                        aInputs[cInputs].hLdrMod = NIL_RTLDRMOD;
     
    675696        if (aInputs[i].hLdrMod != NIL_RTLDRMOD)
    676697            RTLdrClose(aInputs[i].hLdrMod);
    677         if (aInputs[i].pvBits)
    678             RTMemFree(aInputs[i].pvBits);
     698        if (aInputs[i].pbBits)
     699            RTMemFree(aInputs[i].pbBits);
    679700    }
    680701
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-bootsector.asm

    r98103 r102270  
    5151;*      Defined Constants And Macros                                                                                             *
    5252;*********************************************************************************************************************************
    53 ;; Enabled faster loading.
     53;; Enables faster loading.
    5454%define BS3KIT_BOOTSECTOR_FASTER_LOAD
    55 ;; Enabled load progress dots.
     55;; Enables load progress dots.
    5656%define BS3KIT_BOOTSECTOR_LOAD_DOTS
     57;; Enables support for fake 63.5 MB floppies with 255 sectors, 2 heads and 255 tracks.
     58%define BS3KIT_BOOTSECTOR_SUPPORT_63_5MB_FLOPPIES
    5759
    5860;; Halts on failure location. For debugging.
     
    9597g_cRootDirEntries:                      ; 011h
    9698        dw 0
    97 g_cTotalSectors:                        ; 013h
     99g_cTotalSectors:                        ; 013h - We (ab)use this for the number of checksumed sectors.
    98100        dw 0
    99101g_bMediaDescriptor:                     ; 015h
     
    115117g_bExtendedSignature:                   ; 026h
    116118        db 0x29
    117 g_dwSerialNumber:                       ; 027h
     119g_dwSerialNumber:                       ; 027h - We (ab)use this for the base image checksum.
    118120        dd 0x0a458634
    119121g_abLabel:                              ; 02bh
     
    125127
    126128;
    127 ; Where to real init code starts.
     129; Where the real init code starts.
    128130;
    129131bs3InitCode:
    130132        cli
    131133
     134%if 0 ; This does not work, we clear it wholesale below
    132135%ifdef BS3KIT_BOOTSECTOR_SAVE_INITIAL_STATE
    133136        ; save the registers.
     
    135138        mov     [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.ds], ds
    136139%endif
    137 
    138         ; set up the DS segment reister so we can skip the CS prefix when saving more prefixes..
    139         mov     ax, 0
     140%endif
     141
     142        ; set up the DS segment register so we can skip the CS prefix when saving more prefixes..
     143        mov     ax, 0                   ; no xor ax,ax as that messes with the eflags
    140144        mov     ds, ax
    141145
     146%if 0 ; This does not work, we clear it wholesale below
    142147%ifdef BS3KIT_BOOTSECTOR_SAVE_INITIAL_STATE
    143148        mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rdi], di
     
    148153        mov     [di + BS3REGCTX.es], es
    149154        mov     [di + BS3REGCTX.rbp], bp
     155%endif
    150156%endif
    151157
     
    190196
    191197        ; 1. bit 15-bit was fixed to 1 in pre-286 CPUs, and fixed to 0 in 286+.
     198%if 0 ; 3 vs 2 bytes
    192199        mov     ax, [bp - 2]
     200%else
     201        pop     ax
     202        push    ax
     203%endif
    193204        test    ah, 080h                ; always set on pre 286, clear on 286 and later
    194205        jnz     .pre_80286
     
    197208.detect_286_or_386plus:
    198209CPU 286
    199         mov     ah, (X86_EFL_IOPL | X86_EFL_NT) >> 8
     210        mov     ah, (X86_EFL_IOPL | X86_EFL_NT) >> 8 ; OR'ing would be safer, but costs a byte and nothing should be set anyway.
    200211        push    ax
    201212        popf
     
    212223CPU 8086
    213224%ifdef BS3KIT_BOOTSECTOR_SAVE_INITIAL_STATE
     225        mov     [di - 0x70 + BS3REGCTX.rflags], ax
    214226        mov     [di - 0x70 + BS3REGCTX.rbx], bx
    215227        mov     [di - 0x70 + BS3REGCTX.rdx], dx
     
    266278        mov     [di - 0x70 + BS3REGCTX.cr4], eax
    267279.no_cr4:
     280%else
     281        popf                            ; (restores IOPL+NT)
    268282%endif
    269283        ; Make sure caching is enabled and alignment is off.
     
    356370.ok_geometry_call:
    357371%endif
    358         and     cl, 63                  ; only the sector count.
     372%ifndef BS3KIT_BOOTSECTOR_SUPPORT_63_5MB_FLOPPIES
     373        and     cl, 63                  ; only the sector count. (63.5MB has 255 sectors, so don't do this!)
     374%endif
    359375        mov     bMaxSector, cl
    360376        mov     bMaxHead, dh
    361377        mov     dl, bSavedDiskNo
    362 
    363 %if 0 ; bMaxSector=0x12 (18); bMaxHead=0x01; bMaxCylinder=0x4f (79)
     378                                  ;63*2*0xff*512 = 0xFB0400 (16 450 560)
     379%if 0 ; DEBUG ; bMaxSector=0x12 (18); bMaxHead=0x01; bMaxCylinder=0x4f (79)
    364380        mov al, 'S'
    365381        call bs3PrintChrInAl
     
    389405        xor     dh, dh                  ; dh/head=0
    390406.the_load_loop:
    391  %if 0
     407 %if 0 ; DEBUG
    392408        mov al, 'c'
    393409        call bs3PrintChrInAl
     
    451467        xor     dh, dh                  ; dh/head=0
    452468.the_load_loop:
    453  %if 0
     469 %if 0 ; DEBUG
    454470        mov al, 'c'
    455471        call bs3PrintChrInAl
     
    464480        mov al, dh
    465481        call bs3PrintHexInAl
    466         mov al, ';'
     482        mov al, '#'
    467483        call bs3PrintChrInAl
    468484 %elifdef BS3KIT_BOOTSECTOR_LOAD_DOTS
     
    473489        sub     al, cl
    474490        inc     al
     491 %ifdef BS3KIT_BOOTSECTOR_SUPPORT_63_5MB_FLOPPIES
     492        cmp     al, 72                  ; The BIOS dislikes reading too many sectors at a time.
     493        jbe     .read_again             ; Look for 'num_sectors > 72' in PC/BIOS/floppy.c.
     494        mov     al, 72
     495 %endif
    475496.read_again:
    476497        cmp     si, ax
     
    478499        mov     ax, si
    479500.do_read:
     501 %if 0 ; DEBUG
     502        push    ax
     503        call bs3PrintHexInAl
     504        mov al, ';'
     505        call bs3PrintChrInAl
     506        pop     ax
     507 %endif
     508
    480509        mov     ah, 02h                 ; ah=read function
    481510        xor     bx, bx
     
    485514
    486515        cmp     ah, 9                   ; DMA 64KB crossing error
    487 %if 0 ; This hack doesn't work. If the FDC is in single sided mode we end up with a garbled image. Probably "missing" sides.
     516 %if 0 ; This hack doesn't work. If the FDC is in single sided mode we end up with a garbled image. Probably "missing" sides.
    488517        je      .read_one
    489518
     
    499528        jmp     .the_load_loop
    500529.read_one:
    501 %elifdef HLT_ON_FAILURE
     530 %elifdef HLT_ON_FAILURE
    502531        je      .read_one_ok
    503532        cli
    504533        hlt
    505534.read_one_ok:
    506 %else
     535 %else
    507536        jne     .failure
    508 %endif
     537 %endif
    509538        mov     ax, 1                   ; Retry reading a single sector.
    510539        jmp     .read_again
     
    513542.advance_sector:
    514543        inc     cl
     544 %ifdef BS3KIT_BOOTSECTOR_SUPPORT_63_5MB_FLOPPIES
     545        jz      .adv_sector             ; Wraparound is a 63.5 MB problem.
     546 %endif
    515547        cmp     cl, bMaxSector
    516548        jbe     .adv_addr
    517549
     550.adv_sector:
    518551        mov     cl, 1
    519552        inc     dh
     
    534567.done_reading:
    535568%endif ; BS3KIT_BOOTSECTOR_FASTER_LOAD
    536 %if 0
     569%if 0 ; DEBUG
    537570        mov     al, 'D'
    538571        call bs3PrintChrInAl
     
    544577%endif
    545578
     579%if 0 ; 3 vs 2 bytes
    546580        add     sp, 2*2
     581%else
     582        pop     dx
     583        pop     dx
     584%endif
    547585        pop     dx
    548586        pop     es
     
    581619        jmp .failure
    582620 %endif
     621%else
     622.failure:
     623        hlt
    583624%endif
    584625.s_szErrMsgEnd:
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-DiskQueryGeometry.asm

    r102157 r102270  
    161161
    162162        les     di, a_puMaxSector
     163        cmp     byte a_bDrive, 4            ; ASSUMES the first 4 drive are potentially BIG floppies.
     164        jge     .not_floppy_sectors
     165        mov     [es:di], cl                 ; For 63.5 MB the whole of CL is the sector number.
     166        mov     cl, 0                       ; CL does not contribute to the cylinder count, so zero it.
     167        jmp     .set_max_cylinder
     168.not_floppy_sectors:
    163169        mov     al, 3fh
    164170        and     al, cl
    165171        mov     [es:di], al
    166172
     173.set_max_cylinder:
    167174        les     di, a_puMaxCylinder
    168175        shr     cl, 6
     
    174181
    175182        mov     xDI, a_puMaxSector
     183        cmp     byte a_bDrive, 4            ; ASSUMES the first 4 drive are potentially BIG floppies.
     184        jge     .not_floppy_sectors
     185        mov     [xDI], cl                   ; For 63.5 MB the whole of CL is the sector number.
     186        mov     cl, 0                       ; CL does not contribute to the cylinder count, so zero it.
     187        jmp     .set_max_cylinder
     188.not_floppy_sectors:
    176189        mov     al, 3fh
    177190        and     al, cl
    178191        mov     [xDI], al
    179192
     193.set_max_cylinder:
    180194        mov     xDI, a_puMaxCylinder
    181195        shr     cl, 6
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-DiskRead.asm

    r102181 r102270  
    135135        mov     ah, 02h                     ; read
    136136        mov     al, a_cSectors
     137        mov     dh, a_uHead
     138        mov     dl, a_bDrive
     139        ; For 63.5MB support the entire CL is the sector number, so just treat floppies special.
     140        cmp     dl, 4                       ; ASSUMES the first 4 drive are potentially BIG floppies.
     141        jb      .floppy
    137142        mov     cx, a_uCylinder
    138143        xchg    ch, cl
    139144        shl     cl, 6
    140145        or      cl, a_uSector
    141         mov     dl, a_bDrive
    142         mov     dh, a_uHead
     146        jmp     .setup_addr
     147.floppy:
     148        mov     ch, a_uCylinder
     149        mov     cl, a_uSector
     150.setup_addr:
    143151        mov     bx, a_pvBuf
    144152        mov     di, a_pvBufSel
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitAll.c

    r102157 r102270  
    4242#include "bs3kit-template-header.h"
    4343#include "bs3-cmn-test.h"
     44#include "bs3kit-linker.h"
    4445#include <iprt/asm-amd64-x86.h>
    4546
     47
    4648BS3_MODE_PROTO_NOSB(void, Bs3EnteredMode,(void));
     49
     50
     51#ifdef BS3_WITH_LOAD_CHECKSUMS
     52/**
     53 * Verifies the base image checksum.
     54 */
     55static void bs3InitVerifyChecksum(void)
     56{
     57    BS3BOOTSECTOR const RT_FAR *pBootSector   = (BS3BOOTSECTOR const RT_FAR *)BS3_FP_MAKE(0, 0x7c00);
     58    uint32_t                    cSectors      = pBootSector->cTotalSectors;
     59    uint32_t const              cSectorsSaved = cSectors;
     60    uint16_t                    uCurSeg       = (BS3_ADDR_LOAD >> 4); /* ASSUMES 16 byte aligned load address! */
     61    uint32_t                    uChecksum     = BS3_CALC_CHECKSUM_INITIAL_VALUE;
     62    while (cSectors > 0)
     63    {
     64        uint8_t const *pbSrc = BS3_FP_MAKE(uCurSeg, 0);
     65        if (cSectors >= _32K / 512)
     66        {
     67            uChecksum = Bs3CalcChecksum(uChecksum, pbSrc, _32K);
     68            cSectors -= _32K / 512;
     69            uCurSeg  += 0x800;
     70        }
     71        else
     72        {
     73            uChecksum = Bs3CalcChecksum(uChecksum, pbSrc, (uint16_t)cSectors * 512);
     74            break;
     75        }
     76    }
     77    Bs3TestPrintf("base image checksum: %#RX32, expected %#RX32 over (%#RX32 sectors, uCurSeg=%#x) sizeof(size_t)=%d\n",
     78                  uChecksum, pBootSector->dwSerialNumber, cSectorsSaved, uCurSeg, sizeof(size_t));
     79    if (uChecksum != pBootSector->dwSerialNumber)
     80    {
     81        Bs3TestPrintf("base image checksum mismatch: %#RX32, expected %#RX32 over %#RX32 sectors\n",
     82                      uChecksum, pBootSector->dwSerialNumber, cSectorsSaved);
     83        Bs3Panic();
     84    }
     85}
     86#endif /* BS3_WITH_LOAD_CHECKSUMS */
    4787
    4888
     
    5191    uint8_t volatile BS3_FAR  *pcTicksFlpyOff;
    5292
     93#ifdef BS3_WITH_LOAD_CHECKSUMS
     94    /* This must be done before we modify anything in the loaded image. */
     95    bs3InitVerifyChecksum();
     96#endif
     97
    5398    /*
    5499     * Detect CPU first as the memory init code will otherwise use 386
     
    56101     */
    57102    Bs3CpuDetect_rm_far();
     103Bs3TestPrintf("#1\n");
    58104    Bs3InitMemory_rm_far();
     105Bs3TestPrintf("#2\n");
    59106    Bs3InitGdt_rm_far();
     107Bs3TestPrintf("#3\n");
    60108
    61109#ifdef BS3_INIT_ALL_WITH_HIGH_DLLS
     
    66114    Bs3InitHighDlls_rm_far();
    67115#endif
     116Bs3TestPrintf("#4\n");
    68117
    69118    /*
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitHighDlls.c

    r102181 r102270  
    5252{
    5353    unsigned const cHighDlls = (unsigned)(&g_Bs3HighDllTable_End - &g_aBs3HighDllTable[0]);
     54    Bs3TestPrintf("cHighDlls=%d g_uBs3CpuDetected=%#x Bs3InitHighDlls_rm_far=%p\n", cHighDlls, g_uBs3CpuDetected, &Bs3InitHighDlls_rm_far);
     55
    5456    if (   cHighDlls > 0
    5557        && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
    5658    {
    57         unsigned i;
    58 
    5959        /*
    60          * We need a buffer first of all. Using a 4K / PAGE_SIZE buffer let us
    61          * share calculations and variables with the allocation code.
     60         * Get the drive geometry. ASSUMES the bootsector hasn't been trashed yet!
    6261         */
    63         uint32_t      uFlatBuf;
    64         uint8_t       cBufSectors;
    65         uint16_t      cbBuf = 12*_1K; /* This is typically enough for a track (512*18 = 0x2400 (9216)). */
    66         void BS3_FAR *pvBuf = Bs3MemAlloc(BS3MEMKIND_REAL, cbBuf);
    67         if (!pvBuf)
     62        uint8_t const bDrive       = ((BS3BOOTSECTOR RT_FAR *)BS3_FP_MAKE(0,0x7c00))->bBootDrv;
     63        uint16_t      uMaxCylinder = 0;
     64        uint8_t       uMaxHead     = 0;
     65        uint8_t       uMaxSector   = 0;
     66        int rc = Bs3DiskQueryGeometry_rm(bDrive, &uMaxCylinder, &uMaxHead, &uMaxSector);
     67        Bs3TestPrintf("Bs3DiskQueryGeometry(%#x)-> C=%#x H=%#x S=%#x\n", bDrive, uMaxCylinder, uMaxHead, uMaxSector);
     68        if (rc == 0)
    6869        {
    69             cbBuf = _4K;
    70             pvBuf = Bs3MemAlloc(BS3MEMKIND_REAL, cbBuf);
    71             if (!pvBuf)
     70            uint16_t const cSectorsPerCylinder = uMaxSector * ((uint16_t)uMaxHead + 1);
     71            unsigned i;
     72
     73            /*
     74             * We need a buffer first of all. Using a 4K / PAGE_SIZE buffer let us
     75             * share calculations and variables with the allocation code.
     76             */
     77            uint32_t         uFlatBuf;
     78            uint8_t          cBufSectors;
     79            uint16_t         cbBuf = 12*_1K; /* This is typically enough for a track (512*18 = 0x2400 (9216)). */
     80            uint8_t BS3_FAR *pbBuf = (uint8_t BS3_FAR *)Bs3MemAlloc(BS3MEMKIND_REAL, cbBuf);
     81            if (!pbBuf)
    7282            {
    73                 Bs3TestPrintf("Failed to allocate 4 KiB memory buffer for loading high DLL(s)!\n");
    74                 Bs3Shutdown();
    75             }
    76         }
    77         cBufSectors = (uint8_t)(cbBuf / 512);
    78         uFlatBuf    = BS3_FP_REAL_TO_FLAT(pvBuf);
    79 
    80         /*
    81          * Iterate the high DLL table and load it all into memory.
    82          */
    83         for (i = 0; i < cHighDlls; i++)
    84         {
    85             const char RT_FAR * const pszzStrings  = (char RT_FAR *)&g_aBs3HighDllTable[i] + g_aBs3HighDllTable[i].offStrings;
    86             const char RT_FAR * const pszFilename  = &pszzStrings[g_aBs3HighDllTable[i].offFilename];
    87             uint16_t const            cPagesToLoad = (uint16_t)(g_aBs3HighDllTable[i].cbLoaded / _4K);
    88             uint16_t                  iPage;
    89             Bs3Printf("Loading dll '%s' at %#RX32 ...", pszFilename, g_aBs3HighDllTable[i].uLoadAddr);
    90 
    91             /*
    92              * Allocate the memory taken by the DLL.
    93              */
    94             iPage = Bs3SlabAllocFixed(&g_Bs3Mem4KUpperTiled.Core, g_aBs3HighDllTable[i].uLoadAddr, cPagesToLoad);
    95             if (iPage == 0 || iPage == UINT16_MAX)
    96             {
    97                 Bs3TestPrintf("Bs3SlabAllocFixed(,%#RX32, %#RX16) failed: %#RX16 (%s)\n",
    98                               g_aBs3HighDllTable[i].uLoadAddr, cPagesToLoad, iPage, pszFilename);
    99                 Bs3Shutdown();
    100             }
    101             /** @todo We don't have any memory management above 16MB... */
    102 
    103             /*
    104              * Load the DLL. This is where we ASSUME real-mode, pre-PIC setup,
    105              * and interrupts enabled as we need to use int13 for the actual
    106              * reading. We switch to 32-bit protected mode and copies the
    107              * chunk from pvBuf and to the actual load address.
    108              *
    109              * Note! When reading we must make sure to not switch head as the
    110              *       BIOS code messes up the result if it does the wraparound.
    111              */
    112             {
    113                 /* Get the drive geometry. ASSUMES the bootsector hasn't been trashed yet! */
    114                 uint16_t      cSectorsPerCylinder;
    115                 uint8_t const bDrive       = ((BS3BOOTSECTOR RT_FAR *)BS3_FP_MAKE(0,0x7c00))->bBootDrv;
    116                 uint16_t      uMaxCylinder = 0;
    117                 uint8_t       uMaxHead     = 0;
    118                 uint8_t       uMaxSector   = 0;
    119                 int rc = Bs3DiskQueryGeometry_rm(bDrive, &uMaxCylinder, &uMaxHead, &uMaxSector);
    120                 if (rc != 0)
     83                cbBuf = _4K;
     84                pbBuf = (uint8_t BS3_FAR *)Bs3MemAlloc(BS3MEMKIND_REAL, cbBuf);
     85                if (!pbBuf)
    12186                {
    122                     Bs3TestPrintf("Bs3DiskQueryGeometry(%#x) failed: %#x\n", bDrive, rc);
     87                    Bs3TestPrintf("Failed to allocate 4 KiB memory buffer for loading high DLL(s)!\n");
    12388                    Bs3Shutdown();
    12489                }
    125                 cSectorsPerCylinder = uMaxSector * ((uint16_t)uMaxHead + 1);
    126                 //Bs3TestPrintf("Bs3DiskQueryGeometry(%#x)-> C=%#x H=%#x S=%#x cSectorsPerCylinder=%#x\n",
    127                 //              bDrive, uMaxCylinder, uMaxHead, uMaxSector, cSectorsPerCylinder);
    128 
    129                 /* Load the image. */
     90            }
     91            cBufSectors = (uint8_t)(cbBuf / 512);
     92            uFlatBuf    = BS3_FP_REAL_TO_FLAT(pbBuf);
     93
     94            /*
     95             * Iterate the high DLL table and load it all into memory.
     96             */
     97            for (i = 0; i < cHighDlls; i++)
     98            {
     99                const char RT_FAR * const pszzStrings  = (char RT_FAR *)&g_aBs3HighDllTable[i] + g_aBs3HighDllTable[i].offStrings;
     100                const char RT_FAR * const pszFilename  = &pszzStrings[g_aBs3HighDllTable[i].offFilename];
     101                uint16_t const            cPagesToLoad = (uint16_t)(g_aBs3HighDllTable[i].cbLoaded / _4K);
     102                uint16_t                  iPage;
     103                Bs3Printf("Loading dll '%s' at %#RX32 ...", pszFilename, g_aBs3HighDllTable[i].uLoadAddr);
     104
     105                /*
     106                 * Allocate the memory taken by the DLL.
     107                 */
     108                iPage = Bs3SlabAllocFixed(&g_Bs3Mem4KUpperTiled.Core, g_aBs3HighDllTable[i].uLoadAddr, cPagesToLoad);
     109                if (iPage == 0 || iPage == UINT16_MAX)
    130110                {
    131                     uint32_t       cSectorsLeftToLoad = g_aBs3HighDllTable[i].cbInImage  / 512;
    132                     uint32_t       uCurFlatLoadAddr   = g_aBs3HighDllTable[i].uLoadAddr;
    133                     /* Calculate the current CHS position: */
    134                     uint32_t const uCurSectorInImage  = g_aBs3HighDllTable[i].offInImage / 512;
    135                     uint16_t       uCylinder          = uCurSectorInImage / cSectorsPerCylinder;
    136                     uint16_t const uRemainder         = uCurSectorInImage % cSectorsPerCylinder;
    137                     uint8_t        uHead              = uRemainder / uMaxSector;
    138                     uint8_t        uSector            = (uRemainder % uMaxSector) + 1;
    139                     while (cSectorsLeftToLoad > 0)
     111                    Bs3TestPrintf("Bs3SlabAllocFixed(,%#RX32, %#RX16) failed: %#RX16 (%s)\n",
     112                                  g_aBs3HighDllTable[i].uLoadAddr, cPagesToLoad, iPage, pszFilename);
     113                    Bs3Shutdown();
     114                }
     115                /** @todo We don't have any memory management above 16MB... */
     116
     117                /*
     118                 * Load the DLL. This is where we ASSUME real-mode, pre-PIC setup,
     119                 * and interrupts enabled as we need to use int13 for the actual
     120                 * reading. We switch to 32-bit protected mode and copies the
     121                 * chunk from pbBuf and to the actual load address.
     122                 *
     123                 * Note! When reading we must make sure to not switch head as the
     124                 *       BIOS code messes up the result if it does the wraparound.
     125                 */
     126                {
     127
     128                    /* Load the image. */
    140129                    {
    141                         /* Figure out how much we dare read.  Only up to the end of the track. */
    142                         uint8_t cSectors = uMaxSector + 1 - uSector;
    143                         if (cSectors > cBufSectors)
    144                             cSectors = cBufSectors;
    145                         if (cSectorsLeftToLoad < cSectors)
    146                             cSectors = (uint8_t)(cSectorsLeftToLoad);
    147 
    148                         //Bs3TestPrintf("Calling Bs3DiskRead(%#x,%#x,%#x,%#x,%#x,%p) [uCurFlatLoadAddr=%RX32]\n",
    149                         //              bDrive, uCylinder, uHead, uSector, cSectors, pvBuf, uCurFlatLoadAddr);
    150                         rc = Bs3DiskRead_rm(bDrive, uCylinder, uHead, uSector, cSectors, pvBuf);
    151                         if (rc != 0)
     130#ifdef BS3_WITH_LOAD_CHECKSUMS
     131# if 0 /* for debugging */
     132                        uint32_t       iCurSector         = 0;
     133# endif
     134                        uint32_t       uChecksum          = BS3_CALC_CHECKSUM_INITIAL_VALUE;
     135#endif
     136                        uint32_t       cSectorsLeftToLoad = g_aBs3HighDllTable[i].cbInImage  / 512;
     137                        uint32_t       uCurFlatLoadAddr   = g_aBs3HighDllTable[i].uLoadAddr;
     138                        /* Calculate the current CHS position: */
     139                        uint32_t const uCurSectorInImage  = g_aBs3HighDllTable[i].offInImage / 512;
     140                        uint16_t       uCylinder          = uCurSectorInImage / cSectorsPerCylinder;
     141                        uint16_t const uRemainder         = uCurSectorInImage % cSectorsPerCylinder;
     142                        uint8_t        uHead              = uRemainder / uMaxSector;
     143                        uint8_t        uSector            = (uRemainder % uMaxSector) + 1;
     144                        while (cSectorsLeftToLoad > 0)
    152145                        {
    153                             Bs3TestPrintf("Bs3DiskRead(%#x,%#x,%#x,%#x,%#x,) failed: %#x\n",
    154                                           bDrive, uCylinder, uHead, uSector, cBufSectors, rc);
     146                            /* Figure out how much we dare read.  Only up to the end of the track. */
     147                            uint8_t cSectors = uMaxSector + 1 - uSector;
     148                            if (cSectors > cBufSectors)
     149                                cSectors = cBufSectors;
     150                            if (cSectorsLeftToLoad < cSectors)
     151                                cSectors = (uint8_t)(cSectorsLeftToLoad);
     152
     153                            Bs3TestPrintf("Calling Bs3DiskRead(%#x,%#x,%#x,%#x,%#x,%p) [uCurFlatLoadAddr=%RX32]\n",
     154                                          bDrive, uCylinder, uHead, uSector, cSectors, pbBuf, uCurFlatLoadAddr);
     155                            rc = Bs3DiskRead_rm(bDrive, uCylinder, uHead, uSector, cSectors, pbBuf);
     156                            if (rc != 0)
     157                            {
     158                                Bs3TestPrintf("Bs3DiskRead(%#x,%#x,%#x,%#x,%#x,) failed: %#x\n",
     159                                              bDrive, uCylinder, uHead, uSector, cBufSectors, rc);
     160                                Bs3Shutdown();
     161                            }
     162
     163#ifdef BS3_WITH_LOAD_CHECKSUMS
     164                            /* Checksum what we just loaded. */
     165# if 0 /* For debugging. */
     166                            {
     167                                uint16_t j;
     168                                uint32_t uChecksumTmp = uChecksum;
     169                                for (j = 0; j < cSectors; j++, iCurSector++)
     170                                    Bs3TestPrintf("sector #%RU32:  %#RX32 %#010RX32\n", iCurSector,
     171                                                  uChecksumTmp = Bs3CalcChecksum(uChecksumTmp, &pbBuf[j * 512], 512),
     172                                                  Bs3CalcChecksum(BS3_CALC_CHECKSUM_INITIAL_VALUE, &pbBuf[j * 512], 512));
     173                                uChecksum = Bs3CalcChecksum(uChecksum, pbBuf, 512 * cSectors);
     174                                if (uChecksum != uChecksumTmp)
     175                                    Bs3TestPrintf("Checksum error: %#RX32, expected %#RX32!\n", uChecksum, uChecksumTmp);
     176                            }
     177# else
     178                            uChecksum = Bs3CalcChecksum(uChecksum, pbBuf, 512 * cSectors);
     179# endif
     180#endif
     181
     182                            /* Copy the page to where the DLL is being loaded.  */
     183                            Bs3MemCopyFlat_rm_far(uCurFlatLoadAddr, uFlatBuf, 512 * cSectors);
     184                            Bs3PrintChr('.');
     185
     186                            /* Advance */
     187                            uCurFlatLoadAddr   += cSectors * 512;
     188                            cSectorsLeftToLoad -= cSectors;
     189                            uSector            += cSectors;
     190                            if (!uSector || uSector > uMaxSector)
     191                            {
     192                                uSector        = 1;
     193                                uHead++;
     194                                if (uHead > uMaxHead)
     195                                {
     196                                    uHead      = 0;
     197                                    uCylinder++;
     198                                }
     199                            }
     200                        }
     201
     202#ifdef BS3_WITH_LOAD_CHECKSUMS
     203                        /* Verify the checksum. */
     204                        if (uChecksum != g_aBs3HighDllTable[i].uChecksum)
     205                        {
     206                            Bs3TestPrintf("Checksum mismatch for '%s': %#RX32 vs %#RX32\n",
     207                                          pszFilename, uChecksum, g_aBs3HighDllTable[i].uChecksum);
    155208                            Bs3Shutdown();
    156209                        }
    157 
    158                         /* Copy the page to where the DLL is being loaded.  */
    159                         Bs3MemCopyFlat_rm_far(uCurFlatLoadAddr, uFlatBuf, 512 * cSectors);
    160                         Bs3PrintChr('.');
    161 
    162                         /* Advance */
    163                         uCurFlatLoadAddr   += cSectors * 512;
    164                         cSectorsLeftToLoad -= cSectors;
    165                         uSector            += cSectors;
    166                         if (uSector > uMaxSector)
    167                         {
    168                             uSector        = 1;
    169                             uHead++;
    170                             if (uHead > uMaxHead)
    171                             {
    172                                 uHead      = 0;
    173                                 uCylinder++;
    174                             }
    175                         }
     210#endif
    176211                    }
    177212                }
    178213            }
     214
     215            Bs3Printf("\n");
     216            Bs3MemFree(pbBuf, cbBuf);
    179217        }
    180 
    181         Bs3Printf("\n");
    182         Bs3MemFree(pvBuf, cbBuf);
     218        else
     219        {
     220            Bs3TestPrintf("Bs3DiskQueryGeometry(%#x) failed: %#x\n", bDrive, rc);
     221            Bs3Shutdown();
     222        }
    183223    }
    184224}
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-linker.h

    r102181 r102270  
    5353    uint8_t     cFATs;                  /**< 010h */
    5454    uint16_t    cRootDirEntries;        /**< 011h */
    55     uint16_t    cTotalSectors;          /**< 013h */
     55    uint16_t    cTotalSectors;          /**< 013h - We (ab)use this for the checksum length in sectors. */
    5656    uint8_t     bMediaDescriptor;       /**< 015h */
    5757    uint16_t    cSectorsPerFAT;         /**< 016h */
     
    6363    uint8_t     bFlagsEtc;              /**< 025h */
    6464    uint8_t     bExtendedSignature;     /**< 026h */
    65     uint32_t    dwSerialNumber;         /**< 027h */
     65    uint32_t    dwSerialNumber;         /**< 027h - We (ab)use this for the base image checksum. */
    6666    char        abLabel[11];            /**< 02bh */
    6767    char        abFSType[8];            /**< 036h */
     
    104104    int32_t     offStrings;         /**< Relative address (to entry start) of the string table. */
    105105    uint32_t    offFilename;        /**< String table offset of the DLL name (sans path, with extension). */
     106    uint32_t    uChecksum;          /**< Simple checksum of all the on-disk image bits. */
    106107} BS3HIGHDLLENTRY;
    107108/** Magic value for BS3HIGHDLLENTRY. */
     
    125126
    126127
     128/** Initial value for Bs3CalcChecksum. */
     129#define BS3_CALC_CHECKSUM_INITIAL_VALUE 1
     130
     131/**
     132 * Calculates an Adler-32 checksum.
     133 */
     134DECLINLINE(uint32_t) Bs3CalcChecksum(uint32_t uChecksum, uint8_t const RT_FAR *pbSrc, size_t cbSrc)
     135{
     136    uint32_t uA = RT_LO_U16(uChecksum);
     137    uint32_t uB = RT_HI_U16(uChecksum);
     138
     139    while (cbSrc-- > 0)
     140    {
     141        uA = (uA + *pbSrc++) % 0xfff1;
     142        uB = (uA + uB)       % 0xfff1;
     143    }
     144
     145    return RT_MAKE_U32(uA, uB);
     146}
     147
    127148#endif /* !BS3KIT_INCLUDED_bs3kit_linker_h */
    128149
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette