Changeset 102270 in vbox
- Timestamp:
- Nov 23, 2023 12:40:38 AM (12 months ago)
- Location:
- trunk/src/VBox/ValidationKit/bootsectors/bs3kit
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/VBoxBs3Linker.cpp
r102181 r102270 67 67 uint32_t uLoadAddr; 68 68 uint32_t offInImage; 69 void *pvBits;69 uint8_t *pbBits; 70 70 RTLDRMOD hLdrMod; 71 71 } BS3LNKINPUT; … … 88 88 char szName[RT_FLEXIBLE_ARRAY]; 89 89 } BS3LNKIMPORTNAME; 90 91 90 92 91 … … 121 120 } 122 121 122 123 123 /** 124 124 * @callback_method_impl{FNRTSTRSPACECALLBACK} … … 216 216 if (cbImage != ~(size_t)0) 217 217 { 218 void *p vBits =RTMemAlloc(cbImage);219 if (p vBits)218 void *pbBits = (uint8_t *)RTMemAlloc(cbImage); 219 if (pbBits) 220 220 { 221 221 BS3LNKIMPORTSTATE State = { pOutput, NULL, 0, 0, 0 }; 222 rc = RTLdrGetBits(hLdrMod, p vBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmImportCallback, pOutput);222 rc = RTLdrGetBits(hLdrMod, pbBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmImportCallback, pOutput); 223 223 if (RT_SUCCESS(rc)) 224 224 { … … 254 254 /* Populate the string table with exports. */ 255 255 size_t const offExportStrings = State.cbStrings; 256 rc = RTLdrEnumSymbols(hLdrMod, 0, p vBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmOutputExportStrings, &State);256 rc = RTLdrEnumSymbols(hLdrMod, 0, pbBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmOutputExportStrings, &State); 257 257 size_t const cbStrings = State.cbStrings; 258 258 if (RT_SUCCESS(rc) && cbStrings < _64K) … … 271 271 "start_exports:\n"); 272 272 State.cbStrings = offExportStrings; 273 rc = RTLdrEnumSymbols(hLdrMod, 0, p vBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmOutputExportTable, &State);273 rc = RTLdrEnumSymbols(hLdrMod, 0, pbBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmOutputExportTable, &State); 274 274 AssertRC(rc); 275 275 fprintf(pOutput, "\n"); … … 291 291 " dd start_strings - start_entry\n" 292 292 " dd 1 ; offDllName\n" 293 " dd 0 ; uChecksum\n" 293 294 , BS3HIGHDLLENTRY_MAGIC, cbImage, cbImage, State.cImports, State.cExports, (unsigned)cbStrings); 294 295 rcExit = RTEXITCODE_SUCCESS; … … 301 302 else 302 303 rcExit = RTMsgErrorExitFailure("RTLdrGetBits failed: %Rrc", rc); 303 RTMemFree(p vBits);304 RTMemFree(pbBits); 304 305 } 305 306 else … … 399 400 { 400 401 paInputs[i].cbBits = RT_ALIGN_32(paInputs[i].cbFile, 512); 401 paInputs[i].p vBits =RTMemAllocZ(paInputs[i].cbBits);402 if (!paInputs[i].p vBits)402 paInputs[i].pbBits = (uint8_t *)RTMemAllocZ(paInputs[i].cbBits); 403 if (!paInputs[i].pbBits) 403 404 return RTMsgErrorExitFailure("Out of memory (%#x)\n", paInputs[i].cbBits); 404 size_t cbRead = fread(paInputs[i].p vBits, 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); 405 406 if (cbRead != paInputs[i].cbFile) 406 407 return RTMsgErrorExitFailure("Error reading '%s' (got %d bytes, wanted %u).", … … 423 424 424 425 paInputs[i].cbBits = RT_ALIGN_32((uint32_t)cbImage, 4096); /* Bs3InitHighDlls_rm depend on the 4KiB alignment. */ 425 paInputs[i].p vBits =RTMemAllocZ(paInputs[i].cbBits);426 if (!paInputs[i].p vBits)426 paInputs[i].pbBits = (uint8_t *)RTMemAllocZ(paInputs[i].cbBits); 427 if (!paInputs[i].pbBits) 427 428 return RTMsgErrorExitFailure("Out of memory (%#x)\n", paInputs[i].cbBits); 428 429 429 430 /* 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, 431 432 RTPathFilename(paInputs[i].pszFile)); 432 433 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); 433 438 434 439 /* Get the fixed up image bits. */ 435 rc = RTLdrGetBits(paInputs[i].hLdrMod, paInputs[i].p vBits, uHiLoadAddr, ResolveHighDllImportCallback, pHighDllEntry);440 rc = RTLdrGetBits(paInputs[i].hLdrMod, paInputs[i].pbBits, uHiLoadAddr, ResolveHighDllImportCallback, pHighDllEntry); 436 441 if (RT_FAILURE(rc)) 437 442 return RTMsgErrorExitFailure("RTLdrGetBits failed on '%s': %Rrc", paInputs[i].pszFile, rc); … … 445 450 const char * const pszSymbol = (const char *)&pszzStrings[paExports[iExport].offName]; 446 451 RTLDRADDR Value = 0; 447 rc = RTLdrGetSymbolEx(paInputs[i].hLdrMod, paInputs[i].p vBits, uHiLoadAddr, UINT32_MAX, pszSymbol, &Value);452 rc = RTLdrGetSymbolEx(paInputs[i].hLdrMod, paInputs[i].pbBits, uHiLoadAddr, UINT32_MAX, pszSymbol, &Value); 448 453 if (RT_SUCCESS(rc)) 449 454 paExports[iExport].offFlat = (uint32_t)Value; … … 456 461 pHighDllEntry->offInImage = off; 457 462 pHighDllEntry->uLoadAddr = uHiLoadAddr; 463 pHighDllEntry->uChecksum = Bs3CalcChecksum(BS3_CALC_CHECKSUM_INITIAL_VALUE, paInputs[i].pbBits, paInputs[i].cbBits); 458 464 paInputs[i].uLoadAddr = uHiLoadAddr; 459 465 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 460 476 } 461 477 Assert(!(off & 0x1ff)); … … 467 483 468 484 /* 469 * Patch the BPB with base image sector count .485 * Patch the BPB with base image sector count and image checksum. 470 486 */ 471 PBS3BOOTSECTOR pBs = (PBS3BOOTSECTOR)paInputs[0].p vBits;487 PBS3BOOTSECTOR pBs = (PBS3BOOTSECTOR)paInputs[0].pbBits; 472 488 if ( memcmp(pBs->abLabel, RT_STR_TUPLE(BS3_LABEL)) == 0 473 489 && memcmp(pBs->abFSType, RT_STR_TUPLE(BS3_FSTYPE)) == 0 474 490 && memcmp(pBs->abOemId, RT_STR_TUPLE(BS3_OEMID)) == 0) 491 { 475 492 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 } 476 497 else 477 498 return RTMsgErrorExitFailure("Didn't find magic strings in the first file (%s).", paInputs[0].pszFile); … … 483 504 { 484 505 Assert(ftell(pOutput) == (int32_t)paInputs[i].offInImage); 485 ssize_t cbWritten = fwrite(paInputs[i].p vBits, sizeof(uint8_t), paInputs[i].cbBits, pOutput);506 ssize_t cbWritten = fwrite(paInputs[i].pbBits, sizeof(uint8_t), paInputs[i].cbBits, pOutput); 486 507 if (cbWritten != (ssize_t)paInputs[i].cbBits) 487 508 return RTMsgErrorExitFailure("fwrite failed (%zd vs %zu)", cbWritten, paInputs[i].cbBits); … … 588 609 if (cSectors > 0) 589 610 { 590 aInputs[cInputs].p vBits = NULL;611 aInputs[cInputs].pbBits = NULL; 591 612 aInputs[cInputs].cbBits = 0; 592 613 aInputs[cInputs].hLdrMod = NIL_RTLDRMOD; … … 675 696 if (aInputs[i].hLdrMod != NIL_RTLDRMOD) 676 697 RTLdrClose(aInputs[i].hLdrMod); 677 if (aInputs[i].p vBits)678 RTMemFree(aInputs[i].p vBits);698 if (aInputs[i].pbBits) 699 RTMemFree(aInputs[i].pbBits); 679 700 } 680 701 -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-bootsector.asm
r98103 r102270 51 51 ;* Defined Constants And Macros * 52 52 ;********************************************************************************************************************************* 53 ;; Enable dfaster loading.53 ;; Enables faster loading. 54 54 %define BS3KIT_BOOTSECTOR_FASTER_LOAD 55 ;; Enable dload progress dots.55 ;; Enables load progress dots. 56 56 %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 57 59 58 60 ;; Halts on failure location. For debugging. … … 95 97 g_cRootDirEntries: ; 011h 96 98 dw 0 97 g_cTotalSectors: ; 013h 99 g_cTotalSectors: ; 013h - We (ab)use this for the number of checksumed sectors. 98 100 dw 0 99 101 g_bMediaDescriptor: ; 015h … … 115 117 g_bExtendedSignature: ; 026h 116 118 db 0x29 117 g_dwSerialNumber: ; 027h 119 g_dwSerialNumber: ; 027h - We (ab)use this for the base image checksum. 118 120 dd 0x0a458634 119 121 g_abLabel: ; 02bh … … 125 127 126 128 ; 127 ; Where t oreal init code starts.129 ; Where the real init code starts. 128 130 ; 129 131 bs3InitCode: 130 132 cli 131 133 134 %if 0 ; This does not work, we clear it wholesale below 132 135 %ifdef BS3KIT_BOOTSECTOR_SAVE_INITIAL_STATE 133 136 ; save the registers. … … 135 138 mov [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.ds], ds 136 139 %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 140 144 mov ds, ax 141 145 146 %if 0 ; This does not work, we clear it wholesale below 142 147 %ifdef BS3KIT_BOOTSECTOR_SAVE_INITIAL_STATE 143 148 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.rdi], di … … 148 153 mov [di + BS3REGCTX.es], es 149 154 mov [di + BS3REGCTX.rbp], bp 155 %endif 150 156 %endif 151 157 … … 190 196 191 197 ; 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 192 199 mov ax, [bp - 2] 200 %else 201 pop ax 202 push ax 203 %endif 193 204 test ah, 080h ; always set on pre 286, clear on 286 and later 194 205 jnz .pre_80286 … … 197 208 .detect_286_or_386plus: 198 209 CPU 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. 200 211 push ax 201 212 popf … … 212 223 CPU 8086 213 224 %ifdef BS3KIT_BOOTSECTOR_SAVE_INITIAL_STATE 225 mov [di - 0x70 + BS3REGCTX.rflags], ax 214 226 mov [di - 0x70 + BS3REGCTX.rbx], bx 215 227 mov [di - 0x70 + BS3REGCTX.rdx], dx … … 266 278 mov [di - 0x70 + BS3REGCTX.cr4], eax 267 279 .no_cr4: 280 %else 281 popf ; (restores IOPL+NT) 268 282 %endif 269 283 ; Make sure caching is enabled and alignment is off. … … 356 370 .ok_geometry_call: 357 371 %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 359 375 mov bMaxSector, cl 360 376 mov bMaxHead, dh 361 377 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) 364 380 mov al, 'S' 365 381 call bs3PrintChrInAl … … 389 405 xor dh, dh ; dh/head=0 390 406 .the_load_loop: 391 %if 0 407 %if 0 ; DEBUG 392 408 mov al, 'c' 393 409 call bs3PrintChrInAl … … 451 467 xor dh, dh ; dh/head=0 452 468 .the_load_loop: 453 %if 0 469 %if 0 ; DEBUG 454 470 mov al, 'c' 455 471 call bs3PrintChrInAl … … 464 480 mov al, dh 465 481 call bs3PrintHexInAl 466 mov al, ' ;'482 mov al, '#' 467 483 call bs3PrintChrInAl 468 484 %elifdef BS3KIT_BOOTSECTOR_LOAD_DOTS … … 473 489 sub al, cl 474 490 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 475 496 .read_again: 476 497 cmp si, ax … … 478 499 mov ax, si 479 500 .do_read: 501 %if 0 ; DEBUG 502 push ax 503 call bs3PrintHexInAl 504 mov al, ';' 505 call bs3PrintChrInAl 506 pop ax 507 %endif 508 480 509 mov ah, 02h ; ah=read function 481 510 xor bx, bx … … 485 514 486 515 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. 488 517 je .read_one 489 518 … … 499 528 jmp .the_load_loop 500 529 .read_one: 501 %elifdef HLT_ON_FAILURE530 %elifdef HLT_ON_FAILURE 502 531 je .read_one_ok 503 532 cli 504 533 hlt 505 534 .read_one_ok: 506 %else535 %else 507 536 jne .failure 508 %endif537 %endif 509 538 mov ax, 1 ; Retry reading a single sector. 510 539 jmp .read_again … … 513 542 .advance_sector: 514 543 inc cl 544 %ifdef BS3KIT_BOOTSECTOR_SUPPORT_63_5MB_FLOPPIES 545 jz .adv_sector ; Wraparound is a 63.5 MB problem. 546 %endif 515 547 cmp cl, bMaxSector 516 548 jbe .adv_addr 517 549 550 .adv_sector: 518 551 mov cl, 1 519 552 inc dh … … 534 567 .done_reading: 535 568 %endif ; BS3KIT_BOOTSECTOR_FASTER_LOAD 536 %if 0 569 %if 0 ; DEBUG 537 570 mov al, 'D' 538 571 call bs3PrintChrInAl … … 544 577 %endif 545 578 579 %if 0 ; 3 vs 2 bytes 546 580 add sp, 2*2 581 %else 582 pop dx 583 pop dx 584 %endif 547 585 pop dx 548 586 pop es … … 581 619 jmp .failure 582 620 %endif 621 %else 622 .failure: 623 hlt 583 624 %endif 584 625 .s_szErrMsgEnd: -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-DiskQueryGeometry.asm
r102157 r102270 161 161 162 162 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: 163 169 mov al, 3fh 164 170 and al, cl 165 171 mov [es:di], al 166 172 173 .set_max_cylinder: 167 174 les di, a_puMaxCylinder 168 175 shr cl, 6 … … 174 181 175 182 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: 176 189 mov al, 3fh 177 190 and al, cl 178 191 mov [xDI], al 179 192 193 .set_max_cylinder: 180 194 mov xDI, a_puMaxCylinder 181 195 shr cl, 6 -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-DiskRead.asm
r102181 r102270 135 135 mov ah, 02h ; read 136 136 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 137 142 mov cx, a_uCylinder 138 143 xchg ch, cl 139 144 shl cl, 6 140 145 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: 143 151 mov bx, a_pvBuf 144 152 mov di, a_pvBufSel -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitAll.c
r102157 r102270 42 42 #include "bs3kit-template-header.h" 43 43 #include "bs3-cmn-test.h" 44 #include "bs3kit-linker.h" 44 45 #include <iprt/asm-amd64-x86.h> 45 46 47 46 48 BS3_MODE_PROTO_NOSB(void, Bs3EnteredMode,(void)); 49 50 51 #ifdef BS3_WITH_LOAD_CHECKSUMS 52 /** 53 * Verifies the base image checksum. 54 */ 55 static 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 */ 47 87 48 88 … … 51 91 uint8_t volatile BS3_FAR *pcTicksFlpyOff; 52 92 93 #ifdef BS3_WITH_LOAD_CHECKSUMS 94 /* This must be done before we modify anything in the loaded image. */ 95 bs3InitVerifyChecksum(); 96 #endif 97 53 98 /* 54 99 * Detect CPU first as the memory init code will otherwise use 386 … … 56 101 */ 57 102 Bs3CpuDetect_rm_far(); 103 Bs3TestPrintf("#1\n"); 58 104 Bs3InitMemory_rm_far(); 105 Bs3TestPrintf("#2\n"); 59 106 Bs3InitGdt_rm_far(); 107 Bs3TestPrintf("#3\n"); 60 108 61 109 #ifdef BS3_INIT_ALL_WITH_HIGH_DLLS … … 66 114 Bs3InitHighDlls_rm_far(); 67 115 #endif 116 Bs3TestPrintf("#4\n"); 68 117 69 118 /* -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitHighDlls.c
r102181 r102270 52 52 { 53 53 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 54 56 if ( cHighDlls > 0 55 57 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386) 56 58 { 57 unsigned i;58 59 59 /* 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! 62 61 */ 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) 68 69 { 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) 72 82 { 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) 121 86 { 122 Bs3TestPrintf(" Bs3DiskQueryGeometry(%#x) failed: %#x\n", bDrive, rc);87 Bs3TestPrintf("Failed to allocate 4 KiB memory buffer for loading high DLL(s)!\n"); 123 88 Bs3Shutdown(); 124 89 } 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) 130 110 { 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. */ 140 129 { 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) 152 145 { 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); 155 208 Bs3Shutdown(); 156 209 } 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 176 211 } 177 212 } 178 213 } 214 215 Bs3Printf("\n"); 216 Bs3MemFree(pbBuf, cbBuf); 179 217 } 180 181 Bs3Printf("\n"); 182 Bs3MemFree(pvBuf, cbBuf); 218 else 219 { 220 Bs3TestPrintf("Bs3DiskQueryGeometry(%#x) failed: %#x\n", bDrive, rc); 221 Bs3Shutdown(); 222 } 183 223 } 184 224 } -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-linker.h
r102181 r102270 53 53 uint8_t cFATs; /**< 010h */ 54 54 uint16_t cRootDirEntries; /**< 011h */ 55 uint16_t cTotalSectors; /**< 013h */55 uint16_t cTotalSectors; /**< 013h - We (ab)use this for the checksum length in sectors. */ 56 56 uint8_t bMediaDescriptor; /**< 015h */ 57 57 uint16_t cSectorsPerFAT; /**< 016h */ … … 63 63 uint8_t bFlagsEtc; /**< 025h */ 64 64 uint8_t bExtendedSignature; /**< 026h */ 65 uint32_t dwSerialNumber; /**< 027h */65 uint32_t dwSerialNumber; /**< 027h - We (ab)use this for the base image checksum. */ 66 66 char abLabel[11]; /**< 02bh */ 67 67 char abFSType[8]; /**< 036h */ … … 104 104 int32_t offStrings; /**< Relative address (to entry start) of the string table. */ 105 105 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. */ 106 107 } BS3HIGHDLLENTRY; 107 108 /** Magic value for BS3HIGHDLLENTRY. */ … … 125 126 126 127 128 /** Initial value for Bs3CalcChecksum. */ 129 #define BS3_CALC_CHECKSUM_INITIAL_VALUE 1 130 131 /** 132 * Calculates an Adler-32 checksum. 133 */ 134 DECLINLINE(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 127 148 #endif /* !BS3KIT_INCLUDED_bs3kit_linker_h */ 128 149
Note:
See TracChangeset
for help on using the changeset viewer.