VirtualBox

Changeset 91497 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Sep 30, 2021 11:34:59 AM (3 years ago)
Author:
vboxsync
Message:

Main/NvramStore,Runtime/efivarstorevfs: Some fixes to the nvram initialization, bugref:9580

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/efi/efivarstorevfs.cpp

    r90343 r91497  
    3434#include <iprt/asm.h>
    3535#include <iprt/assert.h>
     36#include <iprt/crc.h>
    3637#include <iprt/file.h>
    3738#include <iprt/err.h>
     
    23362337
    23372338
     2339/**
     2340 * Fills the given range with 0xff to match what a real NAND flash device would return for
     2341 * unwritten storage.
     2342 *
     2343 * @returns IPRT status code.
     2344 * @param   hVfsFile            The VFS file handle to write to.
     2345 * @param   offStart            The start offset to fill.
     2346 * @param   offEnd              Offset to fill up to (exclusive).
     2347 */
     2348static int rtEfiVarStoreFillWithFF(RTVFSFILE hVfsFile, uint64_t offStart, uint64_t offEnd)
     2349{
     2350    int rc = VINF_SUCCESS;
     2351    uint8_t abFF[512];
     2352    memset(&abFF[0], 0xff, sizeof(abFF));
     2353
     2354    while (   offStart < offEnd
     2355           && RT_SUCCESS(rc))
     2356    {
     2357        size_t cbThisWrite = RT_MIN(sizeof(abFF), offEnd - offStart);
     2358        rc = RTVfsFileWriteAt(hVfsFile, offStart, &abFF[0], cbThisWrite, NULL);
     2359        offStart += cbThisWrite;
     2360    }
     2361
     2362    return rc;
     2363}
     2364
     2365
    23382366RTDECL(int) RTEfiVarStoreOpenAsVfs(RTVFSFILE hVfsFileIn, uint32_t fMntFlags, uint32_t fVarStoreFlags, PRTVFS phVfs, PRTERRINFO pErrInfo)
    23392367{
     
    24022430        cbStore = cbFile - offStore;
    24032431    }
     2432
     2433    uint32_t cbFtw = 0;
     2434    uint32_t offFtw = 0;
     2435    uint32_t cbVarStore = cbStore;
     2436    uint32_t cbNvEventLog = 0;
     2437    uint32_t offNvEventLog = 0;
     2438    if (!(fFlags & RTEFIVARSTORE_CREATE_F_NO_FTW_WORKING_SPACE))
     2439    {
     2440        /* Split the available space in half for the fault tolerant working area. */
     2441        /** @todo Don't fully understand how these values come together right now but
     2442         * we want to create NVRAM files matching the default OVMF_VARS.fd for now, see
     2443         * https://github.com/tianocore/edk2/commit/b24fca05751f8222acf264853709012e0ab7bf49
     2444         * for the layout.
     2445         * Probably have toadd more arguments to control the different parameters.
     2446         */
     2447        cbNvEventLog  = _4K;
     2448        cbVarStore    = cbStore / 2 - cbNvEventLog - _4K;
     2449        cbFtw         = cbVarStore + _4K;
     2450        offNvEventLog = cbVarStore;
     2451        offFtw        = offNvEventLog + cbNvEventLog;
     2452    }
     2453
    24042454    uint32_t const cBlocks = (uint32_t)(cbStore / cbBlock);
    24052455
     
    24072457    EFI_GUID                   GuidVarAuth  = EFI_VARSTORE_HEADER_GUID_AUTHENTICATED_VARIABLE;
    24082458    EFI_FIRMWARE_VOLUME_HEADER FvHdr;       RT_ZERO(FvHdr);
    2409     EFI_FW_BLOCK_MAP           BlockMap;    RT_ZERO(BlockMap);
     2459    EFI_FW_BLOCK_MAP           aBlockMap[2]; RT_ZERO(aBlockMap);
    24102460    EFI_VARSTORE_HEADER        VarStoreHdr; RT_ZERO(VarStoreHdr);
    24112461
     
    24152465    FvHdr.u32Signature   = RT_H2LE_U32(EFI_FIRMWARE_VOLUME_HEADER_SIGNATURE);
    24162466    FvHdr.fAttr          = RT_H2LE_U32(0x4feff); /** @todo */
    2417     FvHdr.cbFvHdr        = RT_H2LE_U16(sizeof(FvHdr) + sizeof(BlockMap));
     2467    FvHdr.cbFvHdr        = RT_H2LE_U16(sizeof(FvHdr) + sizeof(aBlockMap));
    24182468    FvHdr.bRevision      = EFI_FIRMWARE_VOLUME_HEADER_REVISION;
    24192469
     
    24242474        u16Chksum += RT_LE2H_U16(*pu16++);
    24252475
    2426     /* Block map. */
    2427     BlockMap.cbBlock     = RT_H2LE_U32(cbBlock);
    2428     BlockMap.cBlocks     = RT_H2LE_U32(cBlocks);
    2429 
    2430     pu16 = (const uint16_t *)&BlockMap;
    2431     while (pu16 < (const uint16_t *)&BlockMap + (sizeof(BlockMap) / sizeof(uint16_t)))
     2476    /* Block map, the second entry remains 0 as it serves the delimiter. */
     2477    aBlockMap[0].cbBlock     = RT_H2LE_U32(cbBlock);
     2478    aBlockMap[0].cBlocks     = RT_H2LE_U32(cBlocks);
     2479
     2480    pu16 = (const uint16_t *)&aBlockMap[0];
     2481    while (pu16 < (const uint16_t *)&aBlockMap[0] + (sizeof(aBlockMap) / sizeof(uint16_t)))
    24322482        u16Chksum += RT_LE2H_U16(*pu16++);
    24332483
    2434     FvHdr.u16Chksum      = RT_H2LE_U16(u16Chksum);
     2484    FvHdr.u16Chksum          = RT_H2LE_U16(UINT16_MAX - u16Chksum + 1);
    24352485
    24362486    /* Variable store header. */
    24372487    memcpy(&VarStoreHdr.GuidVarStore, &GuidVarAuth, sizeof(GuidVarAuth));
    2438     VarStoreHdr.cbVarStore   = cbStore - sizeof(FvHdr) - sizeof(BlockMap);
     2488    VarStoreHdr.cbVarStore   = RT_H2LE_U32(cbVarStore - sizeof(FvHdr) - sizeof(aBlockMap));
    24392489    VarStoreHdr.bFmt         = EFI_VARSTORE_HEADER_FMT_FORMATTED;
    24402490    VarStoreHdr.bState       = EFI_VARSTORE_HEADER_STATE_HEALTHY;
     
    24432493    int rc = RTVfsFileWriteAt(hVfsFile, offStore, &FvHdr, sizeof(FvHdr), NULL);
    24442494    if (RT_SUCCESS(rc))
    2445         rc = RTVfsFileWriteAt(hVfsFile, offStore + sizeof(FvHdr), &BlockMap, sizeof(BlockMap), NULL);
     2495        rc = RTVfsFileWriteAt(hVfsFile, offStore + sizeof(FvHdr), &aBlockMap[0], sizeof(aBlockMap), NULL);
    24462496    if (RT_SUCCESS(rc))
    2447         rc = RTVfsFileWriteAt(hVfsFile, offStore + sizeof(FvHdr) + sizeof(BlockMap), &VarStoreHdr, sizeof(VarStoreHdr), NULL);
     2497        rc = RTVfsFileWriteAt(hVfsFile, offStore + sizeof(FvHdr) + sizeof(aBlockMap), &VarStoreHdr, sizeof(VarStoreHdr), NULL);
    24482498    if (RT_SUCCESS(rc))
    24492499    {
    24502500        /* Fill the remainder with 0xff as it would be the case for a real NAND flash device. */
    2451         uint8_t abFF[512];
    2452         memset(&abFF[0], 0xff, sizeof(abFF));
    2453 
    2454         uint64_t offStart = offStore + sizeof(FvHdr) + sizeof(BlockMap) + sizeof(VarStoreHdr);
    2455         uint64_t offEnd   = offStore + cbStore;
    2456         while (   offStart < offEnd
    2457                && RT_SUCCESS(rc))
    2458         {
    2459             size_t cbThisWrite = RT_MIN(sizeof(abFF), offEnd - offStart);
    2460             rc = RTVfsFileWriteAt(hVfsFile, offStart, &abFF[0], cbThisWrite, NULL);
    2461             offStart += cbThisWrite;
    2462         }
    2463     }
    2464 
    2465     /** @todo FTW region. */
     2501        uint64_t offStart = offStore + sizeof(FvHdr) + sizeof(aBlockMap) + sizeof(VarStoreHdr);
     2502        uint64_t offEnd   = offStore + cbVarStore;
     2503
     2504        rc = rtEfiVarStoreFillWithFF(hVfsFile, offStart, offEnd);
     2505    }
     2506
     2507    if (   RT_SUCCESS(rc)
     2508        && !(fFlags & RTEFIVARSTORE_CREATE_F_NO_FTW_WORKING_SPACE))
     2509    {
     2510        EFI_GUID             GuidFtwArea = EFI_WORKING_BLOCK_SIGNATURE_GUID;
     2511        EFI_FTW_BLOCK_HEADER FtwHdr; RT_ZERO(FtwHdr);
     2512
     2513        memcpy(&FtwHdr.GuidSignature, &GuidFtwArea, sizeof(GuidFtwArea));
     2514        FtwHdr.fWorkingBlockValid = RT_H2LE_U32(0xfffffffe); /** @todo */
     2515        FtwHdr.cbWriteQueue       = RT_H2LE_U64(0xfe0); /* This comes from the default OVMF variable volume. */
     2516        FtwHdr.u32Chksum          = RTCrc32(&FtwHdr, sizeof(FtwHdr));
     2517
     2518        /* The area starts with the event log which defaults to 0xff. */
     2519        rc = rtEfiVarStoreFillWithFF(hVfsFile, offNvEventLog, offNvEventLog + cbNvEventLog);
     2520        if (RT_SUCCESS(rc))
     2521        {
     2522            /* Write the FTW header. */
     2523            rc = RTVfsFileWriteAt(hVfsFile, offFtw, &FtwHdr, sizeof(FtwHdr), NULL);
     2524            if (RT_SUCCESS(rc))
     2525                rc = rtEfiVarStoreFillWithFF(hVfsFile, offFtw + sizeof(FtwHdr), offFtw + cbFtw);
     2526        }
     2527    }
    24662528
    24672529    return rc;
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