VirtualBox

Changeset 102285 in vbox for trunk


Ignore:
Timestamp:
Nov 24, 2023 2:37:50 AM (15 months ago)
Author:
vboxsync
Message:

bs3kit: Implemented 16-bit prot segment setup for high-dlls, defaulting to ring-0 code with conforming as an option. bugref:10371

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

Legend:

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

    r102277 r102285  
    129129    if (pSeg->fProt & RTMEM_PROT_EXEC)
    130130        pState->aSegments[iSegment].fFlags |= BS3HIGHDLLSEGMENT_F_EXEC;
     131    if (pSeg->fFlags & RTLDRSEG_FLAG_OS2_CONFORM)
     132        pState->aSegments[iSegment].fFlags |= BS3HIGHDLLSEGMENT_F_CONFORMING;
    131133    if (pSeg->fFlags & RTLDRSEG_FLAG_16BIT)
    132134        pState->aSegments[iSegment].fFlags |= BS3HIGHDLLSEGMENT_F_16BIT;
    133     else if (pSeg->RVA == NIL_RTLDRADDR)
     135    else if (pSeg->RVA != NIL_RTLDRADDR)
    134136    {
    135137        /* Have to check the eyecatcher string to see if it's a 32-bit or 64-bit segment. */
     
    144146        pchSeg[32] = chSaved32;
    145147    }
     148    //if (pSeg->fFlags & RTLDRSEG_FLAG_OS2_ALIAS16) /* 32-bit or 64-bit segment, but allocate a 16-bit alias to it. no wlink sup.  */
     149    //    pState->aSegments[iSegment].fFlags |= BS3HIGHDLLSEGMENT_F_16BIT;
     150
    146151
    147152    // BS3HIGHDLLSEGMENT
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitHighDlls.c

    r102277 r102285  
    4747extern BS3HIGHDLLENTRY BS3_FAR_DATA BS3_DATA_NM(g_aBs3HighDllTable)[];
    4848extern 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 */
     61static 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 */
     153static 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 */
     194static 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}
    49206
    50207
     
    72229
    73230            /*
    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.
     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.
    76233             */
    77234            uint32_t         uFlatBuf;
     
    80237            uint16_t         cbBuf          = uMaxSector >= 72U ? 72U * 512U : uMaxSector * 512U;
    81238            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 (;;)
    87243                {
    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;
    90253                }
    91254            }
     
    101264            for (i = 0; i < cHighDlls; i++)
    102265            {
    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];
    107268                Bs3Printf("Loading dll '%s' at %#RX32..%#RX32 ...", pszFilename, g_aBs3HighDllTable[i].uLoadAddr,
    108269                          g_aBs3HighDllTable[i].uLoadAddr + g_aBs3HighDllTable[i].cbLoaded - 1);
     
    111272                 * Allocate the memory taken by the DLL.
    112273                 */
    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);
    121275
    122276                /*
    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.
    130278                 */
    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);
    218286            }
    219287
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-linker.h

    r102277 r102285  
    135135    uint16_t    fFlags;
    136136} BS3HIGHDLLSEGMENT;
    137 #define BS3HIGHDLLSEGMENT_F_EXEC    1
    138 #define BS3HIGHDLLSEGMENT_F_16BIT   2
    139 #define BS3HIGHDLLSEGMENT_F_32BIT   4
    140 #define BS3HIGHDLLSEGMENT_F_64BIT   8
     137typedef BS3HIGHDLLSEGMENT RT_FAR *PBS3HIGHDLLSEGMENT;
     138/** @name BS3HIGHDLLSEGMENT_F_XXX - segment flags.
     139 * @{ */
     140#define BS3HIGHDLLSEGMENT_F_EXEC         0x0001
     141#define BS3HIGHDLLSEGMENT_F_16BIT        0x0002
     142#define BS3HIGHDLLSEGMENT_F_32BIT        0x0004
     143#define BS3HIGHDLLSEGMENT_F_64BIT        0x0008
     144#define BS3HIGHDLLSEGMENT_F_CONFORMING   0x0010
     145/** @} */
    141146
    142147
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