VirtualBox

Ignore:
Timestamp:
Nov 20, 2023 4:16:55 PM (15 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
160282
Message:

ValKit/bs3kit,bs3-cpu-basic-3: Experimental support for loading a 2nd test image above 1MB (at 8MB by default). This should allow for larger testcases, esp. for 32-bit and 64-bit code. bugref:10371

Location:
trunk/src/VBox/ValidationKit/bootsectors/bs3kit
Files:
4 added
11 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk

    r102127 r102157  
    4242# Boot Sector post-link tool (used via the parent Config.kmk).
    4343BLDPROGS += VBoxBs3Linker
    44 VBoxBs3Linker_TEMPLATE = VBoxBldProg
     44VBoxBs3Linker_TEMPLATE = VBoxAdvBldProg
    4545VBoxBs3Linker_SOURCES  = $(VBOX_PATH_BS3KIT_SRC)/VBoxBs3Linker.cpp
    4646
     
    204204        bs3-cmn-SlabAlloc.c \
    205205        bs3-cmn-SlabAllocEx.c \
     206        bs3-cmn-SlabAllocFixed.c \
    206207        bs3-cmn-SlabFree.c \
    207208        bs3-cmn-SlabListInit.c \
     
    299300        bs3-system-data.asm \
    300301        bs3-rm-InitAll.c \
     302        bs3-rm-InitAllWithHighDlls.c \
    301303        bs3-rm-InitMemory.c \
    302304        bs3-rm-InitGdt.c \
     305        bs3-rm-InitHighDlls.c \
    303306        bs3-cmn-hexdigits.c \
    304307        bs3-cmn-CpuDetectData.c \
     
    370373#
    371374VBOX_BS3KIT_MODE_SOURCES = \
     375        bs3-mode-MemCopyFlat.asm \
    372376        bs3-mode-Name.asm \
    373377        bs3-mode-NameShortLower.asm \
     
    408412        bs3-mode-TestDoModesByMax.c \
    409413        bs3-mode-TestDoModesHlp.asm \
    410         bs3-mode-BiosInt15hE820.asm
     414        bs3-mode-BiosInt15hE820.asm \
     415        bs3-mode-DiskQueryGeometry.asm \
     416        bs3-mode-DiskRead.asm
    411417
    412418# The 16-bit real mode BS3Kit library.
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/VBoxBs3Linker.cpp

    r99632 r102157  
    4040*********************************************************************************************************************************/
    4141#include <stdio.h>
    42 #include <string.h>
    4342#include <stdlib.h>
    44 #include <iprt/types.h>
     43
    4544#include <iprt/assert.h>
     45#include <iprt/err.h>
     46#include <iprt/file.h>
     47#include <iprt/getopt.h>
     48#include <iprt/initterm.h>
     49#include <iprt/ldr.h>
     50#include <iprt/mem.h>
     51#include <iprt/message.h>
     52#include <iprt/path.h>
     53#include <iprt/string.h>
     54
     55#include "bs3kit-linker.h"
    4656
    4757
     
    4959*   Structures and Typedefs                                                                                                      *
    5060*********************************************************************************************************************************/
    51 #pragma pack(1)
    52 typedef struct BS3BOOTSECTOR
    53 {
    54     uint8_t     abJmp[3];
    55     char        abOemId[8];
    56     /** @name EBPB, DOS 4.0 style.
    57      * @{  */
    58     uint16_t    cBytesPerSector;        /**< 00bh */
    59     uint8_t     cSectorsPerCluster;     /**< 00dh */
    60     uint16_t    cReservedSectors;       /**< 00eh */
    61     uint8_t     cFATs;                  /**< 010h */
    62     uint16_t    cRootDirEntries;        /**< 011h */
    63     uint16_t    cTotalSectors;          /**< 013h */
    64     uint8_t     bMediaDescriptor;       /**< 015h */
    65     uint16_t    cSectorsPerFAT;         /**< 016h */
    66     uint16_t    cPhysSectorsPerTrack;   /**< 018h */
    67     uint16_t    cHeads;                 /**< 01ah */
    68     uint32_t    cHiddentSectors;        /**< 01ch */
    69     uint32_t    cLargeTotalSectors;     /**< 020h - We (ab)use this to indicate the number of sectors to load. */
    70     uint8_t     bBootDrv;               /**< 024h */
    71     uint8_t     bFlagsEtc;              /**< 025h */
    72     uint8_t     bExtendedSignature;     /**< 026h */
    73     uint32_t    dwSerialNumber;         /**< 027h */
    74     char        abLabel[11];            /**< 02bh */
    75     char        abFSType[8];            /**< 036h */
    76     /** @} */
    77 } BS3BOOTSECTOR;
    78 #pragma pack()
    79 typedef BS3BOOTSECTOR *PBS3BOOTSECTOR;
    80 
    81 AssertCompileMemberOffset(BS3BOOTSECTOR, cLargeTotalSectors, 0x20);
    82 AssertCompileMemberOffset(BS3BOOTSECTOR, abLabel, 0x2b);
    83 AssertCompileMemberOffset(BS3BOOTSECTOR, abFSType, 0x36);
    84 
    85 #define BS3_OEMID       "BS3Kit\n\n"
    86 #define BS3_FSTYPE      "RawCode\n"
    87 #define BS3_LABEL       "VirtualBox\n"
    88 #define BS3_MAX_SIZE    UINT32_C(491520) /* 480KB */
    89 
    90 
    91 int main(int argc, char **argv)
    92 {
    93     const char  *pszOutput  = NULL;
    94     struct BS3LNKINPUT
    95     {
    96         const char *pszFile;
    97         FILE       *pFile;
    98         uint32_t    cbFile;
    99     }           *paInputs   = (struct BS3LNKINPUT *)calloc(sizeof(paInputs[0]), argc);
    100     unsigned     cInputs    = 0;
    101     uint32_t     cSectors   = 0;
    102 
     61typedef struct BS3LNKINPUT
     62{
     63    const char     *pszFile;
     64    FILE           *pFile;
     65    uint32_t        cbFile;
     66    uint32_t        cbBits;
     67    uint32_t        uLoadAddr;
     68    uint32_t        offInImage;
     69    void           *pvBits;
     70    RTLDRMOD        hLdrMod;
     71} BS3LNKINPUT;
     72
     73
     74typedef struct BS3LNKIMPORTSTATE
     75{
     76    FILE           *pOutput;
     77    RTSTRSPACE      hImportNames;
     78    unsigned        cImports;
     79    unsigned        cExports;
     80    size_t          cbStrings;
     81} BS3LNKIMPORTSTATE;
     82
     83typedef struct BS3LNKIMPORTNAME
     84{
     85    RTSTRSPACECORE  Core;
     86    size_t          offString;
     87    RT_FLEXIBLE_ARRAY_EXTENSION
     88    char            szName[RT_FLEXIBLE_ARRAY];
     89} BS3LNKIMPORTNAME;
     90
     91
     92
     93/**
     94 * @callback_method_impl{FNRTLDRENUMSYMS}
     95 */
     96static DECLCALLBACK(int) GenerateHighDllAsmOutputExportTable(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol,
     97                                                             RTLDRADDR Value, void *pvUser)
     98{
     99    BS3LNKIMPORTSTATE * const pState = (BS3LNKIMPORTSTATE *)pvUser;
     100    if (!pszSymbol || !*pszSymbol)
     101        return RTMsgErrorRc(VERR_LDR_BAD_FIXUP, "All exports must be by name. uSymbol=%#x Value=%RX64", uSymbol, (uint64_t)Value);
     102
     103    // BS3HIGHDLLEXPORTENTRY
     104    fprintf(pState->pOutput,
     105            "g_pfn%s:\n"
     106            "        dd      0\n"
     107            "        dd      %#08x\n",
     108            pszSymbol, (unsigned)pState->cbStrings);
     109    pState->cbStrings += strlen(pszSymbol) + 1;
     110    pState->cExports  += 1;
     111
     112    RT_NOREF(hLdrMod);
     113    return VINF_SUCCESS;
     114}
     115
     116/**
     117 * @callback_method_impl{FNRTSTRSPACECALLBACK}
     118 */
     119static DECLCALLBACK(int) GenerateHighDllAsmOutputImportTable(PRTSTRSPACECORE pStr, void *pvUser)
     120{
     121    FILE             *pOutput = (FILE *)pvUser;
     122    BS3LNKIMPORTNAME *pName   = (BS3LNKIMPORTNAME *)pStr;
     123
     124    // BS3HIGHDLLIMPORTENTRY
     125    fprintf(pOutput,
     126            "        dw      %#06x\n"
     127            "        dw      seg %s\n"
     128            "        dd      %s wrt BS3FLAT\n"
     129            , (unsigned)pName->offString, pName->szName, pName->szName);
     130
     131    return VINF_SUCCESS;
     132}
     133
     134
     135/**
     136 * @callback_method_impl{FNRTLDRENUMSYMS}
     137 */
     138static DECLCALLBACK(int) GenerateHighDllAsmOutputExportStrings(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol,
     139                                                               RTLDRADDR Value, void *pvUser)
     140{
     141    BS3LNKIMPORTSTATE * const pState = (BS3LNKIMPORTSTATE *)pvUser;
     142    if (!pszSymbol || !*pszSymbol)
     143        return RTMsgErrorRc(VERR_LDR_BAD_FIXUP, "All exports must be by name. uSymbol=%#x Value=%RX64", uSymbol, (uint64_t)Value);
     144
     145    fprintf(pState->pOutput, "        db      '%s', 0\n", pszSymbol);
     146    pState->cbStrings += strlen(pszSymbol) + 1;
     147
     148    RT_NOREF(hLdrMod);
     149    return VINF_SUCCESS;
     150}
     151
     152
     153/**
     154 * @callback_method_impl{FNRTSTRSPACECALLBACK}
     155 */
     156static DECLCALLBACK(int) GenerateHighDllAsmOutputImportStrings(PRTSTRSPACECORE pStr, void *pvUser)
     157{
     158    BS3LNKIMPORTSTATE * const pState = (BS3LNKIMPORTSTATE *)pvUser;
     159    BS3LNKIMPORTNAME  * const pName   = (BS3LNKIMPORTNAME *)pStr;
     160
     161    pName->offString = pState->cbStrings;
     162    fprintf(pState->pOutput, "        db      '%s', 0\n", pName->szName);
     163    pState->cbStrings += pName->Core.cchString + 1;
     164
     165    return VINF_SUCCESS;
     166}
     167
     168
     169/**
     170 * @callback_method_impl{FNRTLDRIMPORT}
     171 */
     172static DECLCALLBACK(int) GenerateHighDllAsmImportCallback(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol,
     173                                                          unsigned uSymbol, PRTLDRADDR pValue, void *pvUser)
     174{
     175    BS3LNKIMPORTSTATE *pState = (BS3LNKIMPORTSTATE *)pvUser;
     176    if (!pszSymbol)
     177        return RTMsgErrorRc(VERR_LDR_BAD_FIXUP, "All imports must be by name. pszModule=%s uSymbol=%#x", pszModule, uSymbol);
     178    if (!RTStrSpaceGet(&pState->hImportNames, pszSymbol))
     179    {
     180        size_t const           cchSymbol = strlen(pszSymbol);
     181        BS3LNKIMPORTNAME * const pName   = (BS3LNKIMPORTNAME *)RTMemAlloc(RT_UOFFSETOF_DYN(BS3LNKIMPORTNAME,
     182                                                                                           szName[cchSymbol + 1]));
     183        AssertReturn(pName, VERR_NO_MEMORY);
     184
     185        pName->Core.cchString = cchSymbol;
     186        pName->Core.pszString = (char *)memcpy(pName->szName, pszSymbol, cchSymbol + 1);
     187        pName->offString      = UINT16_MAX;
     188
     189        AssertReturnStmt(RTStrSpaceInsert(&pState->hImportNames, &pName->Core), RTMemFree(pName),
     190                         RTMsgErrorRc(VERR_INTERNAL_ERROR, "IPE #1"));
     191        pState->cImports++;
     192    }
     193    *pValue = 0x10042;
     194    RT_NOREF(hLdrMod);
     195    return VINF_SUCCESS;
     196}
     197
     198
     199static RTEXITCODE GenerateHighDllImportTableAssembly(FILE *pOutput, const char *pszGenAsmFor)
     200{
     201    RTERRINFOSTATIC ErrInfo;
     202    RTLDRMOD        hLdrMod;
     203    int rc = RTLdrOpenEx(pszGenAsmFor, 0, RTLDRARCH_X86_32, &hLdrMod, RTErrInfoInitStatic(&ErrInfo));
     204    if (RT_FAILURE(rc))
     205        return RTMsgErrorExitFailure("RTLdrOpenEx failed to open '%s': %Rrc%#RTeim", pszGenAsmFor, rc, &ErrInfo.Core);
     206
     207    RTEXITCODE rcExit;
     208    size_t cbImage = RTLdrSize(hLdrMod);
     209    if (cbImage != ~(size_t)0)
     210    {
     211        void *pvBits = RTMemAlloc(cbImage);
     212        if (pvBits)
     213        {
     214            BS3LNKIMPORTSTATE State = { pOutput, NULL, 0, 0, 0 };
     215            rc = RTLdrGetBits(hLdrMod, pvBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmImportCallback, pOutput);
     216            if (RT_SUCCESS(rc))
     217            {
     218                /** @todo move more of this to bs3kit*.h?    */
     219                fprintf(pOutput,
     220                        ";\n"
     221                        "; Automatically generated - DO NOT MODIFY!\n"
     222                        ";\n"
     223                        "%%include \"bs3kit.mac\"\n"
     224                        "\n"
     225                        "section BS3HIGHDLLEXPORTS   align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT\n"
     226                        "section BS3HIGHDLLIMPORTS   align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT\n"
     227                        "section BS3HIGHDLLSTRINGS   align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT\n"
     228                        "section BS3HIGHDLLTABLE     align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT\n"
     229                        "section BS3HIGHDLLTABLE_END align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT\n"
     230                        "GROUP BS3HIGHDLLGROUP  BS3HIGHDLLIMPORTS BS3HIGHDLLEXPORTS BS3HIGHDLLSTRINGS BS3HIGHDLLTABLE BS3HIGHDLLTABLE_END\n"
     231                        "\n");
     232
     233                /* Populate the string table with imports. */
     234                const char *pszFilename = RTPathFilename(pszGenAsmFor);
     235                fprintf(pOutput,
     236                        "section BS3HIGHDLLSTRINGS\n"
     237                        "start_strings:\n"
     238                        "        db      0\n"
     239                        "        db      '%s', 0    ; module name\n"
     240                        "        ; imports\n",
     241                        pszFilename);
     242                State.cbStrings = 1 + strlen(pszFilename) + 1;
     243                rc = RTStrSpaceEnumerate(&State.hImportNames, GenerateHighDllAsmOutputImportStrings, &State);
     244                AssertRC(rc);
     245                fprintf(pOutput, "        ; exports\n");
     246
     247                /* Populate the string table with exports. */
     248                size_t const offExportStrings = State.cbStrings;
     249                rc = RTLdrEnumSymbols(hLdrMod, 0, pvBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmOutputExportStrings, &State);
     250                size_t const cbStrings        = State.cbStrings;
     251                if (RT_SUCCESS(rc) && cbStrings < _64K)
     252                {
     253                    /* Output the import table. */
     254                    fprintf(pOutput,
     255                            "section BS3HIGHDLLIMPORTS\n"
     256                            "start_imports:\n");
     257                    rc = RTStrSpaceEnumerate(&State.hImportNames, GenerateHighDllAsmOutputImportTable, &State);
     258                    AssertRC(rc);
     259                    fprintf(pOutput, "\n");
     260
     261                    /* Output the export table (ASSUMES stable enumeration order). */
     262                    fprintf(pOutput,
     263                            "section BS3HIGHDLLEXPORTS\n"
     264                            "start_exports:\n");
     265                    State.cbStrings = offExportStrings;
     266                    rc = RTLdrEnumSymbols(hLdrMod, 0, pvBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmOutputExportTable, &State);
     267                    AssertRC(rc);
     268                    fprintf(pOutput, "\n");
     269
     270                    /* Generate the table entry. */
     271                    fprintf(pOutput,
     272                            "section BS3HIGHDLLTABLE\n"
     273                            "start_entry: ; struct BS3HIGHDLLENTRY \n"
     274                            "        db      '%s', 0    ; achMagic[8]\n"
     275                            "        dd      0               ; uLoadAddress\n"
     276                            "        dd      %#08zx        ; cbLoaded\n"
     277                            "        dd      0               ; offInImage\n"
     278                            "        dd      %#08zx        ; cbInImage\n"
     279                            "        dd      %#04x            ; cImports\n"
     280                            "        dd      start_imports - start_entry\n"
     281                            "        dd      %#04x            ; cExports\n"
     282                            "        dd      start_exports - start_entry\n"
     283                            "        dd      %#05x           ; cbStrings\n"
     284                            "        dd      start_strings - start_entry\n"
     285                            "        dd      1               ; offDllName\n"
     286                            , BS3HIGHDLLENTRY_MAGIC, cbImage, cbImage, State.cImports, State.cExports, (unsigned)cbStrings);
     287                    rcExit = RTEXITCODE_SUCCESS;
     288                }
     289                else if (RT_FAILURE(rc))
     290                    rcExit = RTMsgErrorExitFailure("RTLdrEnumSymbols failed: %Rrc", rc);
     291                else
     292                    rcExit = RTMsgErrorExitFailure("Too many import/export strings: %#x bytes, max 64KiB", cbStrings);
     293            }
     294            else
     295                rcExit = RTMsgErrorExitFailure("RTLdrGetBits failed: %Rrc", rc);
     296            RTMemFree(pvBits);
     297        }
     298        else
     299            rcExit = RTMsgErrorExitFailure("Out of memory!");
     300    }
     301    else
     302        rcExit = RTMsgErrorExitFailure("RTLdrSize failed on '%s'", pszGenAsmFor);
     303
     304    RTLdrClose(hLdrMod);
     305    return rcExit;
     306}
     307
     308
     309static BS3HIGHDLLENTRY *LocateHighDllEntry(uint8_t const *pbBits, uint32_t cbBits, const char *pszFilename)
     310{
    103311    /*
    104      * Scan the arguments.
     312     * We search backwards for up to 4 KB.
    105313     */
    106     for (int i = 1; i < argc; i++)
    107     {
    108         if (argv[i][0] == '-')
     314    size_t const offStop = cbBits > _4K ? cbBits - _4K : 0;
     315    size_t       off     = cbBits >= sizeof(BS3HIGHDLLENTRY) ? cbBits - sizeof(BS3HIGHDLLENTRY) : 0;
     316    while (off > offStop)
     317    {
     318        BS3HIGHDLLENTRY const *pEntry = (BS3HIGHDLLENTRY const *)&pbBits[off];
     319        if (   pEntry->achMagic[0] == BS3HIGHDLLENTRY_MAGIC[0]
     320            && memcmp(pEntry->achMagic, BS3HIGHDLLENTRY_MAGIC, sizeof(pEntry->achMagic)) == 0)
    109321        {
    110             const char *pszOpt = &argv[i][1];
    111             if (*pszOpt == '-')
     322            if (pEntry->cbStrings < _64K && pEntry->cbStrings >= 8)
    112323            {
    113                 /* Convert long options to short ones. */
    114                 pszOpt--;
    115                 if (!strcmp(pszOpt, "--output"))
    116                     pszOpt = "o";
    117                 else if (!strcmp(pszOpt, "--version"))
    118                     pszOpt = "V";
    119                 else if (!strcmp(pszOpt, "--help"))
    120                     pszOpt = "h";
    121                 else
     324                if (off + pEntry->offStrings > 0 && off + pEntry->offStrings + pEntry->cbStrings <= off)
    122325                {
    123                     fprintf(stderr, "syntax errro: Unknown options '%s'\n", pszOpt);
    124                     free(paInputs);
    125                     return 2;
    126                 }
    127             }
    128 
    129             /* Process the list of short options. */
    130             while (*pszOpt)
    131             {
    132                 switch (*pszOpt++)
    133                 {
    134                     case 'o':
     326                    if (off + pEntry->offExports > 0 && off + pEntry->offExports + pEntry->cExports * 8 <= off)
    135327                    {
    136                         const char *pszValue = pszOpt;
    137                         pszOpt = strchr(pszOpt, '\0');
    138                         if (*pszValue == '=')
    139                             pszValue++;
    140                         else if (!*pszValue)
     328                        if (off + pEntry->offImports > 0 && off + pEntry->offImports + pEntry->cImports * 8 <= off)
    141329                        {
    142                             if (i + 1 >= argc)
     330                            if (pEntry->offFilename > 0 && pEntry->offFilename < pEntry->cbStrings)
    143331                            {
    144                                 fprintf(stderr, "syntax error: The --output option expects a filename.\n");
    145                                 free(paInputs);
    146                                 return 12;
     332                                const char *psz = (const char *)&pbBits[off + pEntry->offStrings + pEntry->offFilename];
     333                                if (strcmp(pszFilename, psz) == 0)
     334                                    return (BS3HIGHDLLENTRY *)pEntry;
    147335                            }
    148                             pszValue = argv[++i];
    149336                        }
    150                         if (pszOutput)
    151                         {
    152                             fprintf(stderr, "Only one output file is allowed. You've specified '%s' and '%s'\n",
    153                                     pszOutput, pszValue);
    154                             free(paInputs);
    155                             return 2;
    156                         }
    157                         pszOutput = pszValue;
    158                         pszOpt = "";
    159                         break;
    160337                    }
    161 
    162                     case 'V':
    163                         printf("%s\n", "$Revision$");
    164                         free(paInputs);
    165                         return 0;
    166 
    167                     case '?':
    168                     case 'h':
    169                         printf("usage: %s [options] -o <output> <input1> [input2 ... [inputN]]\n",
    170                                argv[0]);
    171                         free(paInputs);
    172                         return 0;
    173338                }
    174339            }
    175340        }
     341        off--;
     342    }
     343    RTMsgError("Failed to find the BS3HIGHDLLENTRY structure for '%s'!", pszFilename);
     344    return NULL;
     345}
     346
     347
     348/**
     349 * @callback_method_impl{FNRTLDRIMPORT}
     350 */
     351static DECLCALLBACK(int) ResolveHighDllImportCallback(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol,
     352                                                      unsigned uSymbol, PRTLDRADDR pValue, void *pvUser)
     353{
     354    BS3HIGHDLLENTRY * const pEntry = (BS3HIGHDLLENTRY *)pvUser;
     355    if (!pszSymbol)
     356        return RTMsgErrorRc(VERR_LDR_BAD_FIXUP, "All imports must be by name. pszModule=%s uSymbol=%#x", pszModule, uSymbol);
     357
     358    /* Search the import table: */
     359    BS3HIGHDLLIMPORTENTRY const *paImports   = (BS3HIGHDLLIMPORTENTRY const *)((uintptr_t)pEntry + pEntry->offImports);
     360    const char * const           pszzStrings = (const char *)((uintptr_t)pEntry + pEntry->offStrings);
     361    size_t i = pEntry->cImports;
     362    while (i-- > 0)
     363    {
     364        if (strcmp(pszSymbol, &pszzStrings[paImports[i].offName]) == 0)
     365        {
     366            *pValue = paImports[i].offFlat;
     367            return VINF_SUCCESS;
     368        }
     369    }
     370    RT_NOREF(hLdrMod);
     371    return RTMsgErrorRc(VERR_SYMBOL_NOT_FOUND, "Unable to locate import %s (in %s)!", pszSymbol, pszModule);
     372}
     373
     374
     375static RTEXITCODE DoTheLinking(FILE *pOutput, BS3LNKINPUT *paInputs, unsigned cInputs)
     376{
     377    if (cInputs < 2)
     378        return RTMsgErrorExitFailure("Require at least two input files when linking!");
     379
     380    /*
     381     * Read all the files into memory.
     382     *
     383     * The first two are binary blobs, i.e. the boot sector and the base image.
     384     * Any additional files are DLLs and we need to do linking.
     385     */
     386    uint32_t uHiLoadAddr = BS3HIGHDLL_LOAD_ADDRESS;
     387    uint32_t off         = 0;
     388    for (unsigned i = 0; i < cInputs; i++)
     389    {
     390        paInputs[i].offInImage = off;
     391        if (i < 2)
     392        {
     393            paInputs[i].cbBits = RT_ALIGN_32(paInputs[i].cbFile, 512);
     394            paInputs[i].pvBits = RTMemAllocZ(paInputs[i].cbBits);
     395            if (!paInputs[i].pvBits)
     396                return RTMsgErrorExitFailure("Out of memory (%#x)\n", paInputs[i].cbBits);
     397            size_t cbRead = fread(paInputs[i].pvBits, sizeof(uint8_t), paInputs[i].cbFile, paInputs[i].pFile);
     398            if (cbRead != paInputs[i].cbFile)
     399                return RTMsgErrorExitFailure("Error reading '%s' (got %d bytes, wanted %u).",
     400                                             paInputs[i].pszFile, (int)cbRead, (unsigned)paInputs[i].cbFile);
     401            paInputs[i].uLoadAddr = i == 90 ? 0x7c00 : 0x10000;
     402        }
    176403        else
    177404        {
    178             /*
    179              * Add to input file collection.
    180              */
    181             paInputs[cInputs].pszFile = argv[i];
    182 #if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
    183             FILE *pFile = fopen(paInputs[cInputs].pszFile, "rb");
    184 #else
    185             FILE *pFile = fopen(paInputs[cInputs].pszFile, "r");
    186 #endif
    187             if (pFile)
     405            RTERRINFOSTATIC ErrInfo;
     406            int rc = RTLdrOpenEx(paInputs[i].pszFile, 0, RTLDRARCH_X86_32, &paInputs[i].hLdrMod, RTErrInfoInitStatic(&ErrInfo));
     407            if (RT_FAILURE(rc))
     408                return RTMsgErrorExitFailure("RTLdrOpenEx failed to open '%s': %Rrc%#RTeim",
     409                                             paInputs[i].pszFile, rc, &ErrInfo.Core);
     410
     411            size_t const cbImage = RTLdrSize(paInputs[i].hLdrMod);
     412            if (cbImage == ~(size_t)0)
     413                return RTMsgErrorExitFailure("RTLdrSize failed on '%s'!", paInputs[i].pszFile);
     414            if (cbImage > _64M)
     415                return RTMsgErrorExitFailure("Image '%s' is definitely too large: %#zx", paInputs[i].pszFile, cbImage);
     416
     417            paInputs[i].cbBits = RT_ALIGN_32((uint32_t)cbImage, 4096); /* Bs3InitHighDlls_rm depend on the 4KiB alignment.  */
     418            paInputs[i].pvBits = RTMemAllocZ(paInputs[i].cbBits);
     419            if (!paInputs[i].pvBits)
     420                return RTMsgErrorExitFailure("Out of memory (%#x)\n", paInputs[i].cbBits);
     421
     422            /* Locate the entry for this high dll in the base image. */
     423            BS3HIGHDLLENTRY *pHighDllEntry = LocateHighDllEntry((uint8_t *)paInputs[1].pvBits, paInputs[1].cbFile,
     424                                                                RTPathFilename(paInputs[i].pszFile));
     425            AssertReturn(pHighDllEntry, RTEXITCODE_FAILURE);
     426
     427            /* Get the fixed up image bits. */
     428            rc = RTLdrGetBits(paInputs[i].hLdrMod, paInputs[i].pvBits, uHiLoadAddr, ResolveHighDllImportCallback, pHighDllEntry);
     429            if (RT_FAILURE(rc))
     430                return RTMsgErrorExitFailure("RTLdrGetBits failed on '%s': %Rrc", paInputs[i].pszFile, rc);
     431
     432            /* Update the export addresses. */
     433            BS3HIGHDLLEXPORTENTRY *paExports   = (BS3HIGHDLLEXPORTENTRY *)((uintptr_t)pHighDllEntry + pHighDllEntry->offExports);
     434            const char * const     pszzStrings = (const char *)((uintptr_t)pHighDllEntry + pHighDllEntry->offStrings);
     435            size_t iExport = pHighDllEntry->cExports;
     436            while (iExport-- > 0)
    188437            {
    189                 if (fseek(pFile, 0, SEEK_END) == 0)
    190                 {
    191                     paInputs[cInputs].cbFile = (uint32_t)ftell(pFile);
    192                     if (fseek(pFile, 0, SEEK_SET) == 0)
    193                     {
    194                         if (cInputs != 0 || paInputs[cInputs].cbFile == 512)
    195                         {
    196                             cSectors += RT_ALIGN_32(paInputs[cInputs].cbFile, 512) / 512;
    197                             if (cSectors <= BS3_MAX_SIZE / 512)
    198                             {
    199                                 if (cSectors > 0)
    200                                 {
    201                                     paInputs[cInputs].pFile = pFile;
    202                                     pFile = NULL;
    203                                 }
    204                                 else
    205                                     fprintf(stderr, "error: empty input file: '%s'\n", paInputs[cInputs].pszFile);
    206                             }
    207                             else
    208                                 fprintf(stderr, "error: input is too big: %u bytes, %u sectors (max %u bytes, %u sectors)\n"
    209                                         "info: detected loading '%s'\n",
    210                                         cSectors * 512, cSectors, BS3_MAX_SIZE, BS3_MAX_SIZE / 512,
    211                                         paInputs[cInputs].pszFile);
    212                         }
    213                         else
    214                             fprintf(stderr, "error: first input file (%s) must be exactly 512 bytes\n", paInputs[cInputs].pszFile);
    215                     }
    216                     else
    217                         fprintf(stderr, "error: seeking to start of '%s' failed\n", paInputs[cInputs].pszFile);
    218                 }
     438                const char * const pszSymbol = (const char *)&pszzStrings[paExports[iExport].offName];
     439                RTLDRADDR          Value     = 0;
     440                rc = RTLdrGetSymbolEx(paInputs[i].hLdrMod, paInputs[i].pvBits, uHiLoadAddr, UINT32_MAX, pszSymbol, &Value);
     441                if (RT_SUCCESS(rc))
     442                    paExports[iExport].offFlat = (uint32_t)Value;
    219443                else
    220                     fprintf(stderr, "error: seeking to end of '%s' failed\n", paInputs[cInputs].pszFile);
     444                    return RTMsgErrorExitFailure("Failed to resolve '%s' in '%s': %Rrc", pszSymbol, paInputs[i].pszFile, rc);
    221445            }
    222             else
    223                 fprintf(stderr, "error: Failed to open input file '%s' for reading\n", paInputs[cInputs].pszFile);
    224             if (pFile)
    225             {
    226                 free(paInputs);
    227                 fclose(pFile);
    228                 return 1;
    229             }
    230             cInputs++;
     446
     447            /* Update the DLL entry with the load address and file address: */
     448            pHighDllEntry->offInImage = off;
     449            pHighDllEntry->uLoadAddr  = uHiLoadAddr;
     450            paInputs[i].uLoadAddr     = uHiLoadAddr;
     451            uHiLoadAddr += paInputs[i].cbBits;
    231452        }
    232     }
    233 
    234     if (!pszOutput)
    235     {
    236         fprintf(stderr, "syntax error: No output file was specified (-o or --output).\n");
    237         free(paInputs);
    238         return 2;
    239     }
    240     if (cInputs == 0)
    241     {
    242         fprintf(stderr, "syntax error: No input files was specified.\n");
    243         free(paInputs);
    244         return 2;
    245     }
     453        Assert(!(off & 0x1ff));
     454        off += paInputs[i].cbBits;
     455        Assert(!(off & 0x1ff));
     456    }
     457
     458    /** @todo image size check.   */
    246459
    247460    /*
    248      * Do the job.
     461     * Patch the BPB with base image sector count.
    249462     */
    250     /* Open the output file. */
    251 #if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
    252     FILE *pOutput = fopen(pszOutput, "wb");
    253 #else
    254     FILE *pOutput = fopen(pszOutput, "w");
    255 #endif
    256     if (!pOutput)
    257     {
    258         fprintf(stderr, "error: Failed to open output file '%s' for writing\n", pszOutput);
    259         free(paInputs);
    260         return 1;
    261     }
    262 
    263     /* Copy the input files to the output file, with sector padding applied. */
    264     int rcExit = 0;
    265     size_t off = 0;
    266     for (unsigned i = 0; i < cInputs && rcExit == 0; i++)
    267     {
    268         uint8_t  abBuf[4096]; /* Must be multiple of 512! */
    269         uint32_t cbToRead = paInputs[i].cbFile;
    270         while (cbToRead > 0)
    271         {
    272             /* Read a block from the input file. */
    273             uint32_t const cbThisRead = RT_MIN(cbToRead, sizeof(abBuf));
    274             size_t cbRead = fread(abBuf, sizeof(uint8_t), cbThisRead, paInputs[i].pFile);
    275             if (cbRead != cbThisRead)
    276             {
    277                 fprintf(stderr, "error: Error reading '%s' (got %d bytes, wanted %u).\n",
    278                         paInputs[i].pszFile, (int)cbRead, (unsigned)cbThisRead);
    279                 rcExit = 1;
    280                 break;
    281             }
    282             cbToRead -= cbThisRead;
    283 
    284             /* Padd the end of the file if necessary. */
    285             if ((cbRead & 0x1ff) != 0)
    286             {
    287                 memset(&abBuf[cbRead], 0, 4096 - cbRead);
    288                 cbRead = (cbRead + 0x1ff) & ~0x1ffU;
    289             }
    290 
    291             /* Patch the BPB of the first file. */
    292             if (off == 0)
    293             {
    294                 PBS3BOOTSECTOR pBs = (PBS3BOOTSECTOR)&abBuf[0];
    295                 if (   memcmp(pBs->abLabel,  RT_STR_TUPLE(BS3_LABEL))  == 0
    296                     && memcmp(pBs->abFSType, RT_STR_TUPLE(BS3_FSTYPE)) == 0
    297                     && memcmp(pBs->abOemId,  RT_STR_TUPLE(BS3_OEMID))  == 0)
    298                     pBs->cLargeTotalSectors = cSectors;
    299                 else
    300                 {
    301                     fprintf(stderr, "error: Didn't find magic strings in the first file (%s).\n", paInputs[i].pszFile);
    302                     rcExit = 1;
    303                 }
    304             }
    305 
    306             /* Write the block to the output file. */
    307             if (fwrite(abBuf, sizeof(uint8_t), cbRead, pOutput) == cbRead)
    308                 off += cbRead;
    309             else
    310             {
    311                 fprintf(stderr, "error: fwrite failed\n");
    312                 rcExit = 1;
    313                 break;
    314             }
    315         }
    316 
    317         if (ferror(paInputs[i].pFile))
    318         {
    319             fprintf(stderr, "error: Error reading '%s'.\n", paInputs[i].pszFile);
    320             rcExit = 1;
    321         }
    322     }
    323 
    324     /* Close the input files. */
    325     for (unsigned i = 0; i < cInputs && rcExit == 0; i++)
    326         fclose(paInputs[i].pFile);
    327     free(paInputs);
    328 
    329     /* Avoid output sizes that makes the FDC code think it's a single sided
    330        floppy.  The BIOS always report double sided floppies, and even if we
    331        the bootsector adjust it's bMaxHeads value when getting a 20h error
    332        we end up with a garbaged image (seems somewhere in the BIOS/FDC it is
    333        still treated as a double sided floppy and we get half the data we want
    334        and with gaps).
    335 
    336        Similarly, if the size is 320KB or 360KB the FDC detects it as a double
    337        sided 5.25" floppy with 40 tracks, while the BIOS keeps reporting a
    338        1.44MB 3.5" floppy. So, just avoid those sizes too. */
     463    PBS3BOOTSECTOR pBs = (PBS3BOOTSECTOR)paInputs[0].pvBits;
     464    if (   memcmp(pBs->abLabel,  RT_STR_TUPLE(BS3_LABEL))  == 0
     465        && memcmp(pBs->abFSType, RT_STR_TUPLE(BS3_FSTYPE)) == 0
     466        && memcmp(pBs->abOemId,  RT_STR_TUPLE(BS3_OEMID))  == 0)
     467        pBs->cLargeTotalSectors = (paInputs[0].cbBits + paInputs[1].cbBits) / 512;
     468    else
     469        return RTMsgErrorExitFailure("Didn't find magic strings in the first file (%s).", paInputs[0].pszFile);
     470
     471    /*
     472     * Write out the image.
     473     */
     474    for (unsigned i = 0; i < cInputs; i++)
     475    {
     476        Assert(ftell(pOutput) == (int32_t)paInputs[i].offInImage);
     477        ssize_t cbWritten = fwrite(paInputs[i].pvBits, sizeof(uint8_t), paInputs[i].cbBits, pOutput);
     478        if (cbWritten != (ssize_t)paInputs[i].cbBits)
     479            return RTMsgErrorExitFailure("fwrite failed (%zd vs %zu)", cbWritten, paInputs[i].cbBits);
     480    }
     481
     482    /*
     483     * Avoid output sizes that makes the FDC code think it's a single sided
     484     * floppy.  The BIOS always report double sided floppies, and even if we
     485     * the bootsector adjust it's bMaxHeads value when getting a 20h error
     486     * we end up with a garbaged image (seems somewhere in the BIOS/FDC it is
     487     * still treated as a double sided floppy and we get half the data we want
     488     * and with gaps).
     489     *
     490     * Similarly, if the size is 320KB or 360KB the FDC detects it as a double
     491     * sided 5.25" floppy with 40 tracks, while the BIOS keeps reporting a
     492     * 1.44MB 3.5" floppy. So, just avoid those sizes too.
     493     */
    339494    uint32_t cbOutput = ftell(pOutput);
    340495    if (   cbOutput == 512 * 8 * 40 * 1 /* 160kB 5"1/4 SS */
     
    345500        static uint8_t const s_abZeroSector[512] = { 0 };
    346501        if (fwrite(s_abZeroSector, sizeof(uint8_t), sizeof(s_abZeroSector), pOutput) != sizeof(s_abZeroSector))
     502            return RTMsgErrorExitFailure("fwrite failed (padding)");
     503    }
     504
     505    return RTEXITCODE_SUCCESS;
     506}
     507
     508int main(int argc, char **argv)
     509{
     510    int rc = RTR3InitExe(argc, &argv, 0);
     511    if (RT_FAILURE(rc))
     512        return RTMsgInitFailure(rc);
     513
     514    /*
     515     * Scan the arguments.
     516     */
     517    static const RTGETOPTDEF s_aOptions[] =
     518    {
     519        { "--output",                           'o', RTGETOPT_REQ_STRING },
     520        { "--generate-high-dll-import-table",   'g', RTGETOPT_REQ_STRING },
     521    };
     522
     523    const char  *pszOutput      = NULL;
     524    const char  *pszGenAsmFor   = NULL;
     525    BS3LNKINPUT  aInputs[3];                /* 3 = bootsector, low image, high image */
     526    unsigned     cInputs        = 0;
     527    uint32_t     cSectors       = 0;
     528
     529    RTGETOPTSTATE   GetState;
     530    rc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
     531    AssertRCReturn(rc, RTEXITCODE_SYNTAX);
     532    RTGETOPTUNION   ValueUnion;
     533    int             ch;
     534    while ((ch = RTGetOpt(&GetState, &ValueUnion)))
     535    {
     536        switch (ch)
    347537        {
    348             fprintf(stderr, "error: fwrite failed (padding)\n");
    349             rcExit = 1;
     538            case 'o':
     539                if (pszOutput)
     540                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Only one output file is allowed. You've specified '%s' and '%s'",
     541                                          pszOutput, ValueUnion.psz);
     542                pszOutput = ValueUnion.psz;
     543                break;
     544
     545            case 'g':
     546                if (pszGenAsmFor)
     547                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "--generate-high-dll-import-table can only be used once (first for %s, now for %s)",
     548                                          pszGenAsmFor, ValueUnion.psz);
     549                pszGenAsmFor = ValueUnion.psz;
     550                break;
     551
     552            case VINF_GETOPT_NOT_OPTION:
     553            {
     554                if (pszGenAsmFor)
     555                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "--generate-high-dll-import-table don't take any non-option arguments!");
     556
     557                /*
     558                 * Add to input file collection.
     559                 */
     560                if (cInputs >= RT_ELEMENTS(aInputs))
     561                    return RTMsgErrorExitFailure("Too many input files!");
     562                aInputs[cInputs].pszFile = ValueUnion.psz;
     563#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
     564                FILE *pFile = fopen(aInputs[cInputs].pszFile, "rb");
     565#else
     566                FILE *pFile = fopen(aInputs[cInputs].pszFile, "r");
     567#endif
     568                if (pFile)
     569                {
     570                    if (fseek(pFile, 0, SEEK_END) == 0)
     571                    {
     572                        aInputs[cInputs].cbFile = (uint32_t)ftell(pFile);
     573                        if (fseek(pFile, 0, SEEK_SET) == 0)
     574                        {
     575                            if (cInputs != 0 || aInputs[cInputs].cbFile == 512)
     576                            {
     577                                cSectors += RT_ALIGN_32(aInputs[cInputs].cbFile, 512) / 512;
     578                                if (cSectors <= BS3_MAX_SIZE / 512 || cInputs > 0)
     579                                {
     580                                    if (cSectors > 0)
     581                                    {
     582                                        aInputs[cInputs].pvBits  = NULL;
     583                                        aInputs[cInputs].cbBits  = 0;
     584                                        aInputs[cInputs].hLdrMod = NIL_RTLDRMOD;
     585                                        aInputs[cInputs++].pFile = pFile;
     586                                        pFile = NULL;
     587                                        break;
     588                                    }
     589                                    RTMsgError("empty input file: '%s'", aInputs[cInputs].pszFile);
     590                                }
     591                                else
     592                                    RTMsgError("input is too big: %u bytes, %u sectors (max %u bytes, %u sectors)\n"
     593                                               "detected loading '%s'",
     594                                               cSectors * 512, cSectors, BS3_MAX_SIZE, BS3_MAX_SIZE / 512,
     595                                               aInputs[cInputs].pszFile);
     596                            }
     597                            else
     598                                RTMsgError("first input file (%s) must be exactly 512 bytes", aInputs[cInputs].pszFile);
     599                        }
     600                        else
     601                            RTMsgError("seeking to start of '%s' failed", aInputs[cInputs].pszFile);
     602                    }
     603                    else
     604                        RTMsgError("seeking to end of '%s' failed", aInputs[cInputs].pszFile);
     605                }
     606                else
     607                    RTMsgError("Failed to open input file '%s' for reading", aInputs[cInputs].pszFile);
     608                if (pFile)
     609                    fclose(pFile);
     610                return RTEXITCODE_FAILURE;
     611            }
     612
     613            case 'V':
     614                printf("%s\n", "$Revision$");
     615                return RTEXITCODE_SUCCESS;
     616
     617            case 'h':
     618                printf("usage: %s --output <output> <basemod> [high-dll1... [high-dllN]]\n"
     619                       "   or: %s --output <high-dll.asm> --generate-high-dll-import-table <some.high-dll>\n"
     620                       "   or: %s --help\n"
     621                       "   or: %s --version\n"
     622                       , argv[0], argv[0], argv[0], argv[0]);
     623                return RTEXITCODE_SUCCESS;
     624
     625            default:
     626                return RTGetOptPrintError(ch, &ValueUnion);
    350627        }
    351628    }
     629
     630    if (!pszOutput)
     631        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No output file was specified (-o or --output).");
     632
     633    if (cInputs == 0 && !pszGenAsmFor)
     634        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No input files was specified.");
     635
     636    /*
     637     * Do the job.
     638     */
     639    /* Open the output file */
     640#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
     641    FILE *pOutput = fopen(pszOutput, !pszGenAsmFor ? "wb" : "w");
     642#else
     643    FILE *pOutput = fopen(pszOutput, "w");
     644#endif
     645    if (!pOutput)
     646        RTMsgErrorExitFailure("Failed to open output file '%s' for writing!", pszOutput);
     647
     648    RTEXITCODE rcExit;
     649    if (pszGenAsmFor)
     650        rcExit = GenerateHighDllImportTableAssembly(pOutput, pszGenAsmFor);
     651    else
     652        rcExit = DoTheLinking(pOutput, aInputs, cInputs);
    352653
    353654    /* Finally, close the output file (can fail because of buffered data). */
    354655    if (fclose(pOutput) != 0)
    355     {
    356         fprintf(stderr, "error: Error closing '%s'.\n", pszOutput);
    357         rcExit = 1;
    358     }
    359 
     656        rcExit = RTMsgErrorExitFailure("Error closing '%s'!", pszOutput);
     657
     658    /* Delete the output file on failure. */
     659    if (rcExit != RTEXITCODE_SUCCESS)
     660        RTFileDelete(pszOutput);
     661
     662    /* Close the input files and free memory associated with them. */
     663    for (unsigned i = 0; i < cInputs && rcExit == 0; i++)
     664    {
     665        if (aInputs[i].pFile)
     666            fclose(aInputs[i].pFile);
     667        if (aInputs[i].hLdrMod != NIL_RTLDRMOD)
     668            RTLdrClose(aInputs[i].hLdrMod);
     669        if (aInputs[i].pvBits)
     670            RTMemFree(aInputs[i].pvBits);
     671    }
     672
     673    /* Close stderr to make sure it's flushed properly. */
    360674    fclose(stderr);
    361675    return rcExit;
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabAllocFixed.c

    r102144 r102157  
    4343
    4444
    45 #undef Bs3SlabAllocEx
    46 BS3_CMN_DEF(void BS3_FAR *, Bs3SlabAllocEx,(PBS3SLABCTL pSlabCtl, uint16_t cChunks, uint16_t fFlags))
     45#undef Bs3SlabAllocFixed
     46BS3_CMN_DEF(uint16_t, Bs3SlabAllocFixed,(PBS3SLABCTL pSlabCtl, uint32_t uFlatAddr, uint16_t cChunks))
    4747{
    48     BS3_ASSERT(cChunks > 0);
    49     if (pSlabCtl->cFreeChunks >= cChunks)
     48    uint32_t iBit32 = (uFlatAddr - BS3_XPTR_GET_FLAT(void, pSlabCtl->pbStart)) >> pSlabCtl->cChunkShift;
     49    if (iBit32 < pSlabCtl->cChunks)
    5050    {
    51         int32_t iBit = ASMBitFirstClear(&pSlabCtl->bmAllocated, pSlabCtl->cChunks);
    52         if (iBit >= 0)
    53         {
    54             BS3_ASSERT(!ASMBitTest(&pSlabCtl->bmAllocated, iBit));
     51        uint16_t iBit = (uint16_t)iBit32;
     52        uint16_t i;
    5553
    56             while ((uint32_t)iBit + cChunks <= pSlabCtl->cChunks)
    57             {
    58                 /* Check that we've got the requested number of free chunks here. */
    59                 uint16_t i;
    60                 for (i = 1; i < cChunks; i++)
    61                     if (ASMBitTest(&pSlabCtl->bmAllocated, iBit + i))
    62                         break;
    63                 if (i == cChunks)
    64                 {
    65                     /* Check if the chunks are all in the same tiled segment. */
    66                     BS3_XPTR_AUTO(void, pvRet);
    67                     BS3_XPTR_SET_FLAT(void, pvRet,
    68                                       BS3_XPTR_GET_FLAT(uint8_t, pSlabCtl->pbStart) + ((uint32_t)iBit << pSlabCtl->cChunkShift));
    69                     if (   !(fFlags & BS3_SLAB_ALLOC_F_SAME_TILE)
    70                         ||    (BS3_XPTR_GET_FLAT(void, pvRet) >> 16)
    71                            == ((BS3_XPTR_GET_FLAT(void, pvRet) + ((uint32_t)cChunks << pSlabCtl->cChunkShift) - 1) >> 16) )
    72                     {
    73                         /* Complete the allocation. */
    74                         void *fpRet;
    75                         for (i = 0; i < cChunks; i++)
    76                             ASMBitSet(&pSlabCtl->bmAllocated, iBit + i);
    77                         pSlabCtl->cFreeChunks  -= cChunks;
    78                         fpRet = BS3_XPTR_GET(void, pvRet);
    79 #if ARCH_BITS == 16
    80                         BS3_ASSERT(fpRet != NULL);
    81 #endif
    82                         return fpRet;
    83                     }
     54        /* If the slab doesn't cover the entire area requested, reduce it.
     55           Caller can then move on to the next slab in the list to get the rest. */
     56        if (pSlabCtl->cChunks - iBit < cChunks)
     57            cChunks = pSlabCtl->cChunks - iBit;
    8458
    85                     /*
    86                      * We're crossing a tiled segment boundrary.
    87                      * Skip to the start of the next segment and retry there.
    88                      * (We already know that the first chunk in the next tiled
    89                      * segment is free, otherwise we wouldn't have a crossing.)
    90                      */
    91                     BS3_ASSERT(((uint32_t)cChunks << pSlabCtl->cChunkShift) <= _64K);
    92                     i = BS3_XPTR_GET_FLAT_LOW(void, pvRet);
    93                     i = UINT16_C(0) - i;
    94                     i >>= pSlabCtl->cChunkShift;
    95                     iBit += i;
    96                 }
    97                 else
    98                 {
    99                     /*
    100                      * Continue searching.
    101                      */
    102                     iBit = ASMBitNextClear(&pSlabCtl->bmAllocated, pSlabCtl->cChunks, iBit + i);
    103                     if (iBit < 0)
    104                         break;
    105                 }
    106             }
    107         }
     59        /* Check that all the chunks are free. */
     60        for (i = 0; i < cChunks; i++)
     61            if (ASMBitTest(&pSlabCtl->bmAllocated, iBit + i))
     62                return UINT16_MAX;
     63
     64        /* Complete the allocation. */
     65        for (i = 0; i < cChunks; i++)
     66            ASMBitSet(&pSlabCtl->bmAllocated, iBit + i);
     67        pSlabCtl->cFreeChunks  -= cChunks;
     68        return cChunks;
    10869    }
    109     return NULL;
     70    return 0;
    11071}
    11172
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-common.mac

    r102131 r102157  
    5252;
    5353
    54 ;
    55 ; 16-bit text
     54
     55;                                                                      0x86a00
     56; 16-bit text                                                 442368 = 0x6C000 (442368)
    5657;
    5758%ifndef BS3_IS_DOS_EXE
     
    111112BS3_GLOBAL_DATA Bs3Text16_Size, 2
    112113    dw  BS3_DATA_NM(Bs3Text16_EndOfSegment) wrt CGROUP16
     114%ifndef BS3_IS_HIGH_IMAGE
    113115BS3_GLOBAL_DATA Bs3RmText16_Size, 2
    114116    dw  BS3_DATA_NM(Bs3RmText16_EndOfSegment) wrt BS3GROUPRMTEXT16
     117%endif ; !BS3_IS_HIGH_IMAGE
    115118BS3_GLOBAL_DATA Bs3X0Text16_Size, 2
    116119    dw  BS3_DATA_NM(Bs3X0Text16_EndOfSegment) wrt BS3GROUPX0TEXT16
     
    118121    dw  BS3_DATA_NM(Bs3X1Text16_EndOfSegment) wrt BS3GROUPX1TEXT16
    119122
     123%ifndef BS3_IS_HIGH_IMAGE
    120124BS3_GLOBAL_DATA Bs3RmText16_FlatAddr, 4
    121125    dd  BS3_DATA_NM(Bs3RmText16_StartOfSegment) wrt BS3FLAT
     126%endif ; !BS3_IS_HIGH_IMAGE
    122127BS3_GLOBAL_DATA Bs3X0Text16_FlatAddr, 4
    123128    dd  BS3_DATA_NM(Bs3X0Text16_StartOfSegment) wrt BS3FLAT
     
    164169%endif
    165170
     171%ifndef BS3_IS_HIGH_IMAGE
    166172;
    167173; 16-bit real-mode text
     
    174180BS3_GLOBAL_DATA Bs3RmText16_EndOfSegment, 0
    175181GROUP BS3GROUPRMTEXT16 BS3RMTEXT16_START BS3RMTEXT16 BS3RMTEXT16_END
    176 
     182%endif ; !BS3_IS_HIGH_IMAGE
    177183
    178184;
     
    199205GROUP BS3GROUPX1TEXT16 BS3X1TEXT16_START BS3X1TEXT16 BS3X1TEXT16_END
    200206
     207%ifndef BS3_IS_HIGH_IMAGE
    201208;
    202209; Separate the BS3X1TEXT16_END from BS3_BEGIN_TEXT32 to better help pinpoint
     
    208215BS3_GLOBAL_DATA BS3SEPARATE16AND32BITCODE_EndOfSegment, 0
    209216GROUP BS3SEPARATE16AND32BITCODEGROUP BS3SEPARATE16AND32BITCODE
     217%endif ; !BS3_IS_HIGH_IMAGE
    210218
    211219
     
    220228
    221229
     230%ifndef BS3_IS_HIGH_IMAGE
    222231;
    223232; This is a hack to separate the 32-bit and 64-bit text segments when linking,
     
    230239BS3_GLOBAL_DATA Bs3Separate32And64BitCode_EndOfSegment, 0
    231240GROUP BS3SEPARATE32AND64BITCODEGROUP BS3SEPARATE32AND64BITCODE
     241%endif ; !BS3_IS_HIGH_IMAGE
    232242
    233243
     
    276286
    277287
     288%ifndef BS3_IS_HIGH_IMAGE
     289;
     290; The high dll table segment.
     291;
     292section BS3HIGHDLLEXPORTS   align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT ;; @todo Consider moving this to DATA16...
     293section BS3HIGHDLLIMPORTS   align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT
     294section BS3HIGHDLLSTRINGS   align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT
     295section BS3HIGHDLLTABLE     align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT
     296BS3_GLOBAL_DATA g_aBs3HighDllTable, 0
     297section BS3HIGHDLLTABLE_END align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT
     298BS3_GLOBAL_DATA g_Bs3HighDllTable_End, 0
     299GROUP BS3HIGHDLLGROUP  BS3HIGHDLLIMPORTS BS3HIGHDLLEXPORTS BS3HIGHDLLSTRINGS BS3HIGHDLLTABLE BS3HIGHDLLTABLE_END
     300
    278301;
    279302; 16-bit accessible system data.
     
    288311BS3_BEGIN_TEXT16
    289312BS3_GLOBAL_NAME_EX Bs3KitEntryPoint, function, 0
    290 
     313%endif ; !BS3_IS_HIGH_IMAGE
     314
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-BiosInt15hE820.asm

    r98103 r102157  
    172172        jc      .failed
    173173        cmp     eax, INT15_E820_SIGNATURE
    174         jc      .failed
     174        jne     .failed
    175175        cmp     ecx, 20
    176176        jb      .failed
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-DiskQueryGeometry.asm

    r102150 r102157  
    11; $Id$
    22;; @file
    3 ; BS3Kit - Bs3BiosInt15hE820
     3; BS3Kit - Bs3DiskQueryGeometry
    44;
    55
     
    3939;*********************************************************************************************************************************
    4040%include "bs3kit-template-header.mac"
    41 
    42 
    43 ;*********************************************************************************************************************************
    44 ;*  Defined Constants And Macros                                                                                                 *
    45 ;*********************************************************************************************************************************
    46 ;; Signature: 'SMAP'
    47 %define INT15_E820_SIGNATURE    0534d4150h
    4841
    4942
     
    118111        BS3_SET_BITS 16
    119112%endif
    120         ; Ralf Brown suggest setting es:di to NULL before the call. This is also helpful
    121         ; wrt to IVT manipulation (next step).
     113
     114        ;
     115        ; Ralf Brown suggest setting es:di to NULL before the call.
     116        ; Doubt this is really needed in our case, but whatever.
     117        ;
    122118        xor     di, di
    123119        mov     es, di
    124 
    125         ;
    126         ; Save current and restore the original IVT[13h] entry.
    127         ;
    128         mov     si, seg g_aBs3RmIvtOriginal
    129         mov     ds, si
    130         mov     si, g_aBs3RmIvtOriginal
    131 
    132         push    word [es:13h * 4]
    133         mov     ax, [si + 13h * 4]
    134         mov     [es:13h * 4], ax
    135 
    136         push    word [es:13h * 4 + 2]
    137         mov     ax, [si + 13h * 4 + 2]
    138         mov     [es:13h * 4 + 2], ax
    139120
    140121        ;
     
    145126        mov     es, di
    146127        int     13h
    147 
    148         ;
    149         ; Restore the modified IVT[13h] entry.
    150         ; Must not touch EFLAGS.CF!
    151         ;
    152         push    word 0
    153         pop     ds
    154         pop     word [ds:13h * 4 + 2]
    155         pop     word [ds:13h * 4]
    156128
    157129        ;
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-DiskRead.asm

    r102150 r102157  
    11; $Id$
    22;; @file
    3 ; BS3Kit - Bs3BiosInt15hE820
     3; BS3Kit - Bs3DiskRead
    44;
    55
     
    4242
    4343;*********************************************************************************************************************************
    44 ;*  Defined Constants And Macros                                                                                                 *
    45 ;*********************************************************************************************************************************
    46 ;; Signature: 'SMAP'
    47 %define INT15_E820_SIGNATURE    0534d4150h
    48 
    49 
    50 ;*********************************************************************************************************************************
    5144;*  External symbols                                                                                                             *
    5245;*********************************************************************************************************************************
     
    5548BS3_BEGIN_TEXT16
    5649extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_rm)
    57 BS3_EXTERN_DATA16 g_aBs3RmIvtOriginal
     50
     51BS3_EXTERN_DATA16   g_aBs3RmIvtOriginal
     52%ifdef TMPL_16BIT
     53BS3_EXTERN_CMN      Bs3SelProtFar16DataToRealMode
     54%else
     55BS3_EXTERN_CMN      Bs3SelFlatDataToRealMode
     56%endif
     57
    5858
    5959
    6060;;
    61 ; Performs a int 13h function 8 call.
    62 ;
    63 ; @cproto   BS3_MODE_PROTO_STUB(uint8_t, Bs3DiskQueryGeometry,(uint8_t bDrive, uint16_t *puMaxCylinder,
    64 ;                                                              uint8_t *puMaxHead, uint8_t *puMaxSector));
     61; Performs a int 13h function 2 call.
     62;
     63; @cproto   BS3_MODE_PROTO_STUB(uint8_t, Bs3DiskRead,(uint8_t bDrive, uint16_t uCylinder, uint8_t uHead, uint8_t uSector,
     64;                                                     uint8_t cSectors, void RT_FAR *pvBuf));
    6565;
    6666; @returns  Register value (ax/eax). Zero on success, non-zero on failure.
     
    7272;
    7373TMPL_BEGIN_TEXT
    74 BS3_PROC_BEGIN_MODE Bs3DiskQueryGeometry, BS3_PBC_HYBRID
     74BS3_PROC_BEGIN_MODE Bs3DiskRead, BS3_PBC_HYBRID
    7575        push    xBP
    7676        mov     xBP, xSP
     
    9090        ; Load/Save parameters.
    9191%define a_bDrive                [xBP + xCB + cbCurRetAddr + xCB*0]
    92 %define a_puMaxCylinder         [xBP + xCB + cbCurRetAddr + xCB + sCB*0]
    93 %define a_pMaxHead              [xBP + xCB + cbCurRetAddr + xCB + sCB*1]
    94 %define a_puMaxSector           [xBP + xCB + cbCurRetAddr + xCB + sCB*2]
     92%define a_uCylinder             [xBP + xCB + cbCurRetAddr + xCB*1]
     93%define a_uCylinderHi           [xBP + xCB + cbCurRetAddr + xCB*1 + 1]
     94%define a_uHead                 [xBP + xCB + cbCurRetAddr + xCB*2]
     95%define a_uSector               [xBP + xCB + cbCurRetAddr + xCB*3]
     96%define a_cSectors              [xBP + xCB + cbCurRetAddr + xCB*4]
     97%define a_pvBuf                 [xBP + xCB + cbCurRetAddr + xCB*5]
     98%define a_pvBufSel              [xBP + xCB + cbCurRetAddr + xCB*5 + 2]
    9599
    96100%ifdef TMPL_64BIT
    97101        mov     a_bDrive, rcx           ; save bDrive
    98         mov     a_puMaxCylinder, rdx    ; save pcCylinders
    99         mov     a_pMaxHead, r8          ; save pcHeads
    100         mov     a_puMaxSector, r9       ; save pcSectors
     102        mov     a_uCylinder, rdx        ; save uCylinder
     103        mov     a_uHead, r8             ; save uHead
     104        mov     a_uSector, r9           ; save uSector
    101105        movzx   edx, cl                 ; dl = drive
    102106%else
    103107        mov     dl, a_bDrive            ; dl = drive
    104108%endif
     109
     110        ;
     111        ; Convert buffer pointer if not in real mode.
     112        ; Note! We clean the stack up in the epilogue.
     113        ;
     114%ifdef TMPL_64BIT
     115        sub     rsp, 20h
     116        mov     rcx, a_pvBuf
     117        call    Bs3SelFlatDataToRealMode
     118        mov     a_pvBuf, rax
     119%elifdef TMPL_32BIT
     120        mov     ecx, a_pvBuf
     121        push    ecx
     122        call    Bs3SelFlatDataToRealMode
     123        mov     a_pvBuf, eax
     124%elif !BS3_MODE_IS_RM_OR_V86(TMPL_MODE)
     125        push    word a_pvBufSel
     126        push    word a_pvBuf
     127        call    Bs3SelProtFar16DataToRealMode
     128        mov     a_pvBuf, ax
     129        mov     a_pvBufSel, dx
     130%endif
     131
     132        ;
     133        ; Set up the BIOS call parameters.
     134        ;
     135        mov     ah, 02h                     ; read
     136        mov     al, a_cSectors
     137        mov     cx, a_uCylinder
     138        xchg    ch, cl
     139        shl     cl, 6
     140        or      cl, a_uSector
     141        mov     dl, a_bDrive
     142        mov     dh, a_uHead
     143        mov     bx, a_pvBuf
     144        mov     di, a_pvBufSel
    105145
    106146        ;
     
    118158        BS3_SET_BITS 16
    119159%endif
    120         ; Ralf Brown suggest setting es:di to NULL before the call. This is also helpful
    121         ; wrt to IVT manipulation (next step).
    122         xor     di, di
     160
     161        ;
     162        ; Make the call.
     163        ;
    123164        mov     es, di
    124 
    125         ;
    126         ; Save current and restore the original IVT[13h] entry.
    127         ;
    128         mov     si, seg g_aBs3RmIvtOriginal
    129         mov     ds, si
    130         mov     si, g_aBs3RmIvtOriginal
    131 
    132         push    word [es:13h * 4]
    133         mov     ax, [si + 13h * 4]
    134         mov     [es:13h * 4], ax
    135 
    136         push    word [es:13h * 4 + 2]
    137         mov     ax, [si + 13h * 4 + 2]
    138         mov     [es:13h * 4 + 2], ax
    139 
    140         ;
    141         ; Make the call.
    142         ;
    143         mov     ax, 0800h                   ; ah=08h
    144         xor     di, di                      ; ralf brown suggestion to guard against bios bugs.
    145         mov     es, di
     165;        pushf
     166;        sti
    146167        int     13h
    147 
    148         ;
    149         ; Restore the modified IVT[13h] entry.
    150         ; Must not touch EFLAGS.CF!
    151         ;
    152         push    word 0
    153         pop     ds
    154         pop     word [ds:13h * 4 + 2]
    155         pop     word [ds:13h * 4]
     168;        popf
    156169
    157170        ;
     
    167180 %endif
    168181%endif
     182hlt
     183
    169184        ;
    170185        ; Check that we didn't failed.
    171186        ;
    172187        jc      .failed_return_ah
    173 
    174         ;
    175         ; Save the return values.
    176         ;   CL[7:6]:CH = max cylinders.
    177         ;   DH         = max heads
    178         ;   CL[5:0]    = max sectors
    179         ; Other stuff we don't care about:
    180         ;   AH         = 0
    181         ;   AL         = undefined/zero
    182         ;   BL         = drive type
    183         ;   DL         = max drives.
    184         ;   ES:DI      = driver parameter table for floppies.
    185         ;
    186 %ifdef TMPL_16BIT
    187         les     di, a_pMaxHead
    188         mov     [es:di], dh
    189 
    190         les     di, a_puMaxSector
    191         mov     al, 3fh
    192         and     al, cl
    193         mov     [es:di], al
    194 
    195         les     di, a_puMaxCylinder
    196         shr     cl, 6
    197         xchg    cl, ch
    198         mov     [es:di], cx
    199 %else
    200         mov     xDI, a_pMaxHead
    201         mov     [xDI], dh
    202 
    203         mov     xDI, a_puMaxSector
    204         mov     al, 3fh
    205         and     al, cl
    206         mov     [xDI], al
    207 
    208         mov     xDI, a_puMaxCylinder
    209         shr     cl, 6
    210         xchg    cl, ch
    211         mov     [xDI], cx
    212 %endif
     188        test    ah, ah
     189        jnz     .failed_return_ah
    213190
    214191        ;
     
    243220        dec     al
    244221        jmp     .return
    245 BS3_PROC_END_MODE   Bs3DiskQueryGeometry
    246 
     222BS3_PROC_END_MODE   Bs3DiskRead
     223
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitAll.c

    r98103 r102157  
    5959    Bs3InitGdt_rm_far();
    6060
     61#ifdef BS3_INIT_ALL_WITH_HIGH_DLLS
     62    /*
     63     * Load the high DLLs (if any) now, before we bugger up the PIC and
     64     * replace the IVT.
     65     */
     66    Bs3InitHighDlls_rm_far();
     67#endif
     68
    6169    /*
    6270     * Before we disable all interrupts, try convince the BIOS to stop the
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-autostubs.kmk

    r102127 r102157  
    9797$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3ExtCtxGetFsw)
    9898$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PicUpdateMask)
     99$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SlabAllocFixed)
    99100$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SlabFree)
    100101$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TestSubErrorCount)
     
    194195$(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3SwitchTo32BitAndCallC)
    195196$(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3BiosInt15h88)
     197$(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3DiskQueryGeometry)
     198$(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3DiskRead)
     199$(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3MemCopyFlat)
    196200$(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3TrapInit)
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-define.h

    r102127 r102157  
    181181#define Bs3SlabAlloc BS3_CMN_MANGLER(Bs3SlabAlloc)
    182182#define Bs3SlabAllocEx BS3_CMN_MANGLER(Bs3SlabAllocEx)
     183#define Bs3SlabAllocFixed BS3_CMN_MANGLER(Bs3SlabAllocFixed)
    183184#define Bs3SlabFree BS3_CMN_MANGLER(Bs3SlabFree)
    184185#define Bs3SlabInit BS3_CMN_MANGLER(Bs3SlabInit)
     
    251252# define Bs3BiosInt15hE820 BS3_MODE_MANGLER(Bs3BiosInt15hE820)
    252253# define Bs3CpuDetect BS3_MODE_MANGLER(Bs3CpuDetect)
     254# define Bs3DiskQueryGeometry BS3_MODE_MANGLER(Bs3DiskQueryGeometry)
     255# define Bs3DiskRead BS3_MODE_MANGLER(Bs3DiskRead)
     256# define Bs3MemCopyFlat BS3_MODE_MANGLER(Bs3MemCopyFlat)
    253257# define Bs3SwitchTo32BitAndCallC BS3_MODE_MANGLER(Bs3SwitchTo32BitAndCallC)
    254258# define Bs3TestDoModes BS3_MODE_MANGLER(Bs3TestDoModes)
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-undef.h

    r102127 r102157  
    181181#undef Bs3SlabAlloc
    182182#undef Bs3SlabAllocEx
     183#undef Bs3SlabAllocFixed
    183184#undef Bs3SlabFree
    184185#undef Bs3SlabInit
     
    251252# undef Bs3BiosInt15hE820
    252253# undef Bs3CpuDetect
     254# undef Bs3DiskQueryGeometry
     255# undef Bs3DiskRead
     256# undef Bs3MemCopyFlat
    253257# undef Bs3SwitchTo32BitAndCallC
    254258# undef Bs3TestDoModes
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h

    r102127 r102157  
    615615# define BS3_FP_OFF(a_pv)            ((uintptr_t)(a_pv))
    616616#endif
     617
     618/**
     619 * Converts a far real mode address to a 32-bit flat address.
     620 *
     621 * @returns Flat address.
     622 * @param   a_pv        The _real_ _mode_ far pointer to convert.
     623 */
     624#define BS3_FP_REAL_TO_FLAT(a_pv)   (((uint32_t)BS3_FP_SEG(a_pv) << 4) + BS3_FP_OFF(a_pv))
    617625
    618626/** @def BS3_MAKE_PROT_R0PTR_FROM_FLAT
     
    17571765 * @param   pvSrc           The source buffer.
    17581766 * @param   cbToCopy        The number of bytes to copy.
     1767 * @sa      Bs3MemCopyFlat
    17591768 */
    17601769BS3_CMN_PROTO_STUB(void BS3_FAR *, Bs3MemCpy,(void BS3_FAR *pvDst, const void BS3_FAR *pvSrc, size_t cbToCopy));
     
    21522161
    21532162/**
    2154  * Allocates one or more chunks rom a slab.
     2163 * Allocates one or more chunks from a slab.
    21552164 *
    21562165 * @returns Pointer to the request number of chunks on success, NULL if we're
     
    21612170 */
    21622171BS3_CMN_PROTO_STUB(void BS3_FAR *, Bs3SlabAllocEx,(PBS3SLABCTL pSlabCtl, uint16_t cChunks, uint16_t fFlags));
     2172
     2173/**
     2174 * Allocates a specific range of chunks from a slab.
     2175 *
     2176 * @returns Number of chunks it was possible to allocate in the slab.
     2177 * @retval  0 if the given address isn't in the slab.
     2178 * @retval  UINT16_MAX if one or more of the requested chunks are already in
     2179 *          use, so the request cannot be fulfilled.
     2180 * @param   pSlabCtl        The slab control structure to allocate from.
     2181 * @param   uFlatAddr       The flat address of the range to allocate.
     2182 * @param   cChunks         The number of contiguous chunks we want.
     2183 */
     2184BS3_CMN_PROTO_STUB(uint16_t, Bs3SlabAllocFixed,(PBS3SLABCTL pSlabCtl, uint32_t uFlatAddr, uint16_t cChunks));
    21632185
    21642186/**
     
    25422564 * Call 16-bit prot mode function from v8086 mode.
    25432565 *
    2544  * This switches from v8086 mode to 16-bit protected mode (code) and executed
     2566 * This switches from v8086 mode to 16-bit protected mode (code) and executes
    25452567 * @a fpfnCall with @a cbParams bytes of parameters pushed on the stack.
    25462568 * Afterwards it switches back to v8086 mode and returns a 16-bit status code.
     
    41314153
    41324154/**
     4155 * Initializes all of boot sector kit \#3 as well as the high DLLs.
     4156 */
     4157BS3_DECL(void) Bs3InitAllWithHighDlls_rm(void);
     4158
     4159/**
    41334160 * Initializes the REAL and TILED memory pools.
    41344161 *
     
    41414168 */
    41424169BS3_DECL_FAR(void) Bs3InitGdt_rm_far(void);
     4170
     4171/**
     4172 * Initializes (loads) any high DLLs.
     4173 *
     4174 * @note This cannot be called after the PIC or traps have been initialized!
     4175 */
     4176BS3_DECL_FAR(void) Bs3InitHighDlls_rm_far(void);
    41434177
    41444178
     
    43374371
    43384372/**
     4373 * Special version of memcpy for copying from/to real mode.
     4374 *
     4375 * @returns pvDst
     4376 * @param   uFlatDst        The flat address of the destination buffer.
     4377 * @param   uFlatSrc        The flat address of the source buffer.
     4378 * @param   cbToCopy        The number of bytes to copy.  Max 64KB.
     4379 *
     4380 * @todo    Only work on 386+ at present.   Could be made to work for 286 and
     4381 *          addresses < 16MB if we care...
     4382 */
     4383BS3_MODE_PROTO_STUB(void BS3_FAR *, Bs3MemCopyFlat,(uint32_t uFlatDst, uint32_t uFlatSrc, uint32_t cbToCopy));
     4384
     4385/**
    43394386 * Executes the array of tests in every possibly mode.
    43404387 *
     
    45464593/** @} */
    45474594
     4595/** @defgroup grp_bs3kit_disk   Disk via INT 13h
     4596 * @{
     4597 */
     4598
     4599/**
     4600 * Performs a int 13h function AL=08h call to get the driver parameters.
     4601 *
     4602 * @returns 0 on success, non-zero error BIOS code on failure.
     4603 * @param   bDrive          The drive to get parameters for.
     4604 * @param   puMaxCylinder   Where to store the max cylinder value.
     4605 *                          Range: 0 thru *pcMaxCylinder.
     4606 * @param   puMaxHead       Where to store the max head value.
     4607 *                          Range: 0 thru *pcMaxHead.
     4608 * @param   puMaxSector     Where to store the max sector value.
     4609 *                          Range: 1 thru *pcMaxSector.
     4610 */
     4611BS3_MODE_PROTO_STUB(uint8_t, Bs3DiskQueryGeometry,(uint8_t bDrive, uint16_t *puMaxCylinder,
     4612                                                   uint8_t *puMaxHead, uint8_t *puMaxSector));
     4613
     4614/**
     4615 * Performs a int 13h function AL=08h call to get the driver parameters.
     4616 *
     4617 * @returns 0 on success, non-zero error BIOS code on failure.
     4618 * @param   bDrive          The drive to read from.
     4619 * @param   uCylinder       The cylinder to start read at (0-max).
     4620 * @param   uHead           The head to start reading at (0-max).
     4621 * @param   uSector         The sector to start reading at (1-max).
     4622 * @param   cSectors        The number of sectors to read (1+).
     4623 * @param   pvBuf           The buffer to read into.  This MUST be addressable
     4624 *                          from real mode!
     4625 */
     4626BS3_MODE_PROTO_STUB(uint8_t, Bs3DiskRead,(uint8_t bDrive, uint16_t uCylinder, uint8_t uHead, uint8_t uSector,
     4627                                          uint8_t cSectors, void RT_FAR *pvBuf));
     4628
     4629/** @} */
     4630
    45484631
    45494632/** @} */
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac

    r99443 r102157  
    333333;
    334334; !!HACK ALERT!!
     335 %ifndef BS3_IS_HIGH_IMAGE
    335336segment BS3FLAT use32 class=BS3FLAT
    336337GROUP FLAT BS3FLAT
     338 %else
     339; For HIGH DLLs the hack is WRONG, so we just declare both BS3FLAT and FLAT the way
     340; wlink wants flat groups to be defined. (See FIX_FRAME_FLAT use in omfreloc.c.)
     341GROUP BS3FLAT
     342GROUP FLAT
     343 %endif
    337344%endif
    338345
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