Changeset 102285 in vbox for trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitHighDlls.c
- Timestamp:
- Nov 24, 2023 2:37:50 AM (15 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitHighDlls.c
r102277 r102285 47 47 extern BS3HIGHDLLENTRY BS3_FAR_DATA BS3_DATA_NM(g_aBs3HighDllTable)[]; 48 48 extern BS3HIGHDLLENTRY BS3_FAR_DATA BS3_DATA_NM(g_Bs3HighDllTable_End); 49 50 51 52 /** 53 * Load the DLL. This is where we ASSUME real-mode, pre-PIC setup, 54 * and interrupts enabled as we need to use int13 for the actual 55 * reading. We switch to 32-bit protected mode and copies the 56 * chunk from pbBuf and to the actual load address. 57 * 58 * Note! When reading we must make sure to not switch head as the 59 * BIOS code messes up the result if it does the wraparound. 60 */ 61 static void bs3InitHighDllLoadImage(BS3HIGHDLLENTRY RT_FAR * const pHighDllEntry, const char RT_FAR * const pszFilename, 62 uint8_t BS3_FAR * const pbBuf, uint8_t const cBufSectors, uint32_t const uFlatBuf, 63 uint8_t const bDrive, uint8_t const uMaxHead, uint8_t const uMaxSector, 64 uint16_t const cSectorsPerCylinder) 65 { 66 int rc; 67 #ifdef BS3_WITH_LOAD_CHECKSUMS 68 # if 0 /* for debugging */ 69 uint32_t iCurSector = 0; 70 # endif 71 uint32_t uChecksum = BS3_CALC_CHECKSUM_INITIAL_VALUE; 72 #endif 73 uint32_t cSectorsLeftToLoad = pHighDllEntry->cbInImage / 512U; 74 uint32_t uCurFlatLoadAddr = pHighDllEntry->uLoadAddr; 75 /* Calculate the current CHS position: */ 76 uint32_t const uCurSectorInImage = pHighDllEntry->offInImage / 512U; 77 uint16_t uCylinder = uCurSectorInImage / cSectorsPerCylinder; 78 uint16_t const uRemainder = uCurSectorInImage % cSectorsPerCylinder; 79 uint8_t uHead = uRemainder / uMaxSector; 80 uint8_t uSector = (uRemainder % uMaxSector) + 1; 81 while (cSectorsLeftToLoad > 0) 82 { 83 /* Figure out how much we dare read. Only up to the end of the track. */ 84 uint8_t cSectors = uMaxSector + 1 - uSector; 85 if (cSectors > cBufSectors) 86 cSectors = cBufSectors; 87 if (cSectorsLeftToLoad < cSectors) 88 cSectors = (uint8_t)(cSectorsLeftToLoad); 89 90 //Bs3TestPrintf("Calling Bs3DiskRead(%#x,%#x,%#x,%#x,%#x,%p) [uCurFlatLoadAddr=%RX32]\n", 91 // bDrive, uCylinder, uHead, uSector, cSectors, pbBuf, uCurFlatLoadAddr); 92 rc = Bs3DiskRead_rm(bDrive, uCylinder, uHead, uSector, cSectors, pbBuf); 93 if (rc != 0) 94 { 95 Bs3TestPrintf("Bs3DiskRead(%#x,%#x,%#x,%#x,%#x,) failed: %#x\n", 96 bDrive, uCylinder, uHead, uSector, cBufSectors, rc); 97 Bs3Shutdown(); 98 } 99 100 #ifdef BS3_WITH_LOAD_CHECKSUMS 101 /* Checksum what we just loaded. */ 102 # if 0 /* For debugging. */ 103 { 104 uint16_t j; 105 uint32_t uChecksumTmp = uChecksum; 106 for (j = 0; j < cSectors; j++, iCurSector++) 107 Bs3TestPrintf("sector #%RU32: %#RX32 %#010RX32\n", iCurSector, 108 uChecksumTmp = Bs3CalcChecksum(uChecksumTmp, &pbBuf[j * 512U], 512U), 109 Bs3CalcChecksum(BS3_CALC_CHECKSUM_INITIAL_VALUE, &pbBuf[j * 512U], 512U)); 110 uChecksum = Bs3CalcChecksum(uChecksum, pbBuf, 512U * cSectors); 111 if (uChecksum != uChecksumTmp) 112 Bs3TestPrintf("Checksum error: %#RX32, expected %#RX32!\n", uChecksum, uChecksumTmp); 113 } 114 # else 115 uChecksum = Bs3CalcChecksum(uChecksum, pbBuf, 512U * cSectors); 116 # endif 117 #endif 118 119 /* Copy the page to where the DLL is being loaded. */ 120 Bs3MemCopyFlat_rm_far(uCurFlatLoadAddr, uFlatBuf, 512U * cSectors); 121 Bs3PrintChr('.'); 122 123 /* Advance */ 124 uCurFlatLoadAddr += cSectors * 512U; 125 cSectorsLeftToLoad -= cSectors; 126 uSector += cSectors; 127 if (!uSector || uSector > uMaxSector) 128 { 129 uSector = 1; 130 uHead++; 131 if (uHead > uMaxHead) 132 { 133 uHead = 0; 134 uCylinder++; 135 } 136 } 137 } 138 139 #ifdef BS3_WITH_LOAD_CHECKSUMS 140 /* Verify the checksum. */ 141 if (uChecksum != pHighDllEntry->uChecksum) 142 { 143 Bs3TestPrintf("Checksum mismatch for '%s': %#RX32 vs %#RX32\n", pszFilename, uChecksum, pHighDllEntry->uChecksum); 144 Bs3Shutdown(); 145 } 146 #endif 147 } 148 149 150 /** 151 * Initializes any special (16-bit) segments for the given high DLL. 152 */ 153 static void bs3InitHighDllSetUpSegments(BS3HIGHDLLENTRY RT_FAR *pHighDllEntry, const char RT_FAR *pszFilename) 154 { 155 PBS3HIGHDLLSEGMENT const paSegments = (PBS3HIGHDLLSEGMENT)((char RT_FAR *)pHighDllEntry + pHighDllEntry->offSegments); 156 unsigned const cSegments = pHighDllEntry->cSegments; 157 unsigned iSeg; 158 159 for (iSeg = 0; iSeg < cSegments; iSeg++) 160 { 161 Bs3TestPrintf("Segment #%u: %#RX32 LB %#RX32 idxSel=%#06x fFlags=%#x\n", 162 iSeg, paSegments[iSeg].uAddr, paSegments[iSeg].cb, paSegments[iSeg].idxSel, paSegments[iSeg].fFlags); 163 if (paSegments[iSeg].fFlags & BS3HIGHDLLSEGMENT_F_16BIT) 164 { 165 X86DESC BS3_FAR *pDesc = &Bs3Gdt[paSegments[iSeg].idxSel >> X86_SEL_SHIFT]; 166 167 if (paSegments[iSeg].fFlags & BS3HIGHDLLSEGMENT_F_EXEC) 168 { 169 BS3_ASSERT((unsigned)(paSegments[iSeg].idxSel - BS3_SEL_HIGH16_CS_FIRST) < (unsigned)BS3_SEL_HIGH16_CS_COUNT); 170 Bs3SelSetup16BitCode(pDesc, paSegments[iSeg].uAddr, 0); 171 if (paSegments[iSeg].fFlags & BS3HIGHDLLSEGMENT_F_CONFORMING) 172 pDesc->Gen.u4Type = X86_SEL_TYPE_ER_CONF_ACC; 173 //Bs3TestPrintf("Segment #%u: 16-bit code %p %#x\n", iSeg, pDesc, paSegments[iSeg].idxSel); 174 } 175 else 176 { 177 BS3_ASSERT((unsigned)(paSegments[iSeg].idxSel - BS3_SEL_HIGH16_DS_FIRST) < (unsigned)BS3_SEL_HIGH16_DS_COUNT); 178 Bs3SelSetup16BitData(pDesc, paSegments[iSeg].uAddr); 179 //Bs3TestPrintf("Segment #%u: 16-bit data %p %#x\n", iSeg, pDesc, paSegments[iSeg].idxSel); 180 } 181 if (paSegments[iSeg].cb < _64K) 182 pDesc->Gen.u16LimitLow = paSegments[iSeg].cb - 1; 183 } 184 //else 185 // Bs3TestPrintf("Segment #%u: Not 16-bit\n", iSeg); 186 } 187 188 } 189 190 191 /** 192 * Allocates/reserves the memory backing for the given DLL. 193 */ 194 static void bs3InitHighDllAllocateMemory(BS3HIGHDLLENTRY RT_FAR *pHighDllEntry, const char RT_FAR *pszFilename) 195 { 196 uint16_t const cPagesToLoad = (uint16_t)(pHighDllEntry->cbLoaded / _4K); 197 uint16_t iPage = Bs3SlabAllocFixed(&g_Bs3Mem4KUpperTiled.Core, pHighDllEntry->uLoadAddr, cPagesToLoad); 198 if (iPage == 0 || iPage == UINT16_MAX) 199 { 200 Bs3TestPrintf("Bs3SlabAllocFixed(,%#RX32, %#RX16) failed: %#RX16 (%s)\n", 201 pHighDllEntry->uLoadAddr, cPagesToLoad, iPage, pszFilename); 202 Bs3Shutdown(); 203 } 204 /** @todo We don't have any memory management above 16MB... at the moment. */ 205 } 49 206 50 207 … … 72 229 73 230 /* 74 * We need a buffer first of all. Using a 4K / PAGE_SIZE buffer let us75 * share calculations and variables with the allocation code.231 * We need a buffer first of all. Try for one able to contain a 232 * full track, as that'll give us the best reading speed. 76 233 */ 77 234 uint32_t uFlatBuf; … … 80 237 uint16_t cbBuf = uMaxSector >= 72U ? 72U * 512U : uMaxSector * 512U; 81 238 void BS3_FAR *pvBufAllocated = Bs3MemAlloc(BS3MEMKIND_REAL, cbBuf); 82 if (!pbBuf) 83 { 84 cbBuf = _4K; 85 pvBufAllocated = Bs3MemAlloc(BS3MEMKIND_REAL, cbBuf); 86 if (!pvBufAllocated) 239 if (!pvBufAllocated) 240 { 241 cbBuf = cbBuf >= _32K ? _32K : 1 << ASMBitLastSetU16(cbBuf) /* no - 1!*/; /* converts to a power of two. */ 242 for (;;) 87 243 { 88 Bs3TestPrintf("Failed to allocate 4 KiB memory buffer for loading high DLL(s)!\n"); 89 Bs3Shutdown(); 244 pvBufAllocated = Bs3MemAlloc(BS3MEMKIND_REAL, cbBuf); 245 if (pvBufAllocated) 246 break; 247 if (cbBuf <= _4K) 248 { 249 Bs3TestPrintf("Failed to allocate 4 KiB memory buffer for loading high DLL(s)!\n"); 250 Bs3Shutdown(); 251 } 252 cbBuf >>= 1; 90 253 } 91 254 } … … 101 264 for (i = 0; i < cHighDlls; i++) 102 265 { 103 const char RT_FAR * const pszzStrings = (char RT_FAR *)&g_aBs3HighDllTable[i] + g_aBs3HighDllTable[i].offStrings; 104 const char RT_FAR * const pszFilename = &pszzStrings[g_aBs3HighDllTable[i].offFilename]; 105 uint16_t const cPagesToLoad = (uint16_t)(g_aBs3HighDllTable[i].cbLoaded / _4K); 106 uint16_t iPage; 266 const char RT_FAR * const pszzStrings = (char RT_FAR *)&g_aBs3HighDllTable[i] + g_aBs3HighDllTable[i].offStrings; 267 const char RT_FAR * const pszFilename = &pszzStrings[g_aBs3HighDllTable[i].offFilename]; 107 268 Bs3Printf("Loading dll '%s' at %#RX32..%#RX32 ...", pszFilename, g_aBs3HighDllTable[i].uLoadAddr, 108 269 g_aBs3HighDllTable[i].uLoadAddr + g_aBs3HighDllTable[i].cbLoaded - 1); … … 111 272 * Allocate the memory taken by the DLL. 112 273 */ 113 iPage = Bs3SlabAllocFixed(&g_Bs3Mem4KUpperTiled.Core, g_aBs3HighDllTable[i].uLoadAddr, cPagesToLoad); 114 if (iPage == 0 || iPage == UINT16_MAX) 115 { 116 Bs3TestPrintf("Bs3SlabAllocFixed(,%#RX32, %#RX16) failed: %#RX16 (%s)\n", 117 g_aBs3HighDllTable[i].uLoadAddr, cPagesToLoad, iPage, pszFilename); 118 Bs3Shutdown(); 119 } 120 /** @todo We don't have any memory management above 16MB... */ 274 bs3InitHighDllAllocateMemory(&g_aBs3HighDllTable[i], pszFilename); 121 275 122 276 /* 123 * Load the DLL. This is where we ASSUME real-mode, pre-PIC setup, 124 * and interrupts enabled as we need to use int13 for the actual 125 * reading. We switch to 32-bit protected mode and copies the 126 * chunk from pbBuf and to the actual load address. 127 * 128 * Note! When reading we must make sure to not switch head as the 129 * BIOS code messes up the result if it does the wraparound. 277 * Process the segment table. 130 278 */ 131 { 132 133 /* Load the image. */ 134 { 135 #ifdef BS3_WITH_LOAD_CHECKSUMS 136 # if 0 /* for debugging */ 137 uint32_t iCurSector = 0; 138 # endif 139 uint32_t uChecksum = BS3_CALC_CHECKSUM_INITIAL_VALUE; 140 #endif 141 uint32_t cSectorsLeftToLoad = g_aBs3HighDllTable[i].cbInImage / 512U; 142 uint32_t uCurFlatLoadAddr = g_aBs3HighDllTable[i].uLoadAddr; 143 /* Calculate the current CHS position: */ 144 uint32_t const uCurSectorInImage = g_aBs3HighDllTable[i].offInImage / 512U; 145 uint16_t uCylinder = uCurSectorInImage / cSectorsPerCylinder; 146 uint16_t const uRemainder = uCurSectorInImage % cSectorsPerCylinder; 147 uint8_t uHead = uRemainder / uMaxSector; 148 uint8_t uSector = (uRemainder % uMaxSector) + 1; 149 while (cSectorsLeftToLoad > 0) 150 { 151 /* Figure out how much we dare read. Only up to the end of the track. */ 152 uint8_t cSectors = uMaxSector + 1 - uSector; 153 if (cSectors > cBufSectors) 154 cSectors = cBufSectors; 155 if (cSectorsLeftToLoad < cSectors) 156 cSectors = (uint8_t)(cSectorsLeftToLoad); 157 158 //Bs3TestPrintf("Calling Bs3DiskRead(%#x,%#x,%#x,%#x,%#x,%p) [uCurFlatLoadAddr=%RX32]\n", 159 // bDrive, uCylinder, uHead, uSector, cSectors, pbBuf, uCurFlatLoadAddr); 160 rc = Bs3DiskRead_rm(bDrive, uCylinder, uHead, uSector, cSectors, pbBuf); 161 if (rc != 0) 162 { 163 Bs3TestPrintf("Bs3DiskRead(%#x,%#x,%#x,%#x,%#x,) failed: %#x\n", 164 bDrive, uCylinder, uHead, uSector, cBufSectors, rc); 165 Bs3Shutdown(); 166 } 167 168 #ifdef BS3_WITH_LOAD_CHECKSUMS 169 /* Checksum what we just loaded. */ 170 # if 0 /* For debugging. */ 171 { 172 uint16_t j; 173 uint32_t uChecksumTmp = uChecksum; 174 for (j = 0; j < cSectors; j++, iCurSector++) 175 Bs3TestPrintf("sector #%RU32: %#RX32 %#010RX32\n", iCurSector, 176 uChecksumTmp = Bs3CalcChecksum(uChecksumTmp, &pbBuf[j * 512U], 512U), 177 Bs3CalcChecksum(BS3_CALC_CHECKSUM_INITIAL_VALUE, &pbBuf[j * 512U], 512U)); 178 uChecksum = Bs3CalcChecksum(uChecksum, pbBuf, 512U * cSectors); 179 if (uChecksum != uChecksumTmp) 180 Bs3TestPrintf("Checksum error: %#RX32, expected %#RX32!\n", uChecksum, uChecksumTmp); 181 } 182 # else 183 uChecksum = Bs3CalcChecksum(uChecksum, pbBuf, 512U * cSectors); 184 # endif 185 #endif 186 187 /* Copy the page to where the DLL is being loaded. */ 188 Bs3MemCopyFlat_rm_far(uCurFlatLoadAddr, uFlatBuf, 512U * cSectors); 189 Bs3PrintChr('.'); 190 191 /* Advance */ 192 uCurFlatLoadAddr += cSectors * 512U; 193 cSectorsLeftToLoad -= cSectors; 194 uSector += cSectors; 195 if (!uSector || uSector > uMaxSector) 196 { 197 uSector = 1; 198 uHead++; 199 if (uHead > uMaxHead) 200 { 201 uHead = 0; 202 uCylinder++; 203 } 204 } 205 } 206 207 #ifdef BS3_WITH_LOAD_CHECKSUMS 208 /* Verify the checksum. */ 209 if (uChecksum != g_aBs3HighDllTable[i].uChecksum) 210 { 211 Bs3TestPrintf("Checksum mismatch for '%s': %#RX32 vs %#RX32\n", 212 pszFilename, uChecksum, g_aBs3HighDllTable[i].uChecksum); 213 Bs3Shutdown(); 214 } 215 #endif 216 } 217 } 279 bs3InitHighDllSetUpSegments(&g_aBs3HighDllTable[i], pszFilename); 280 281 /* 282 * Load it. 283 */ 284 bs3InitHighDllLoadImage(&g_aBs3HighDllTable[i], pszFilename, pbBuf, cBufSectors, uFlatBuf, 285 bDrive, uMaxHead, uMaxSector, cSectorsPerCylinder); 218 286 } 219 287
Note:
See TracChangeset
for help on using the changeset viewer.