<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【UEFI】HOB 從概念到代碼

      總述

      使用 HOB 的原因是因為,在 UEFI 啟動過程中,PEI 階段向 DXE 階段安全、結構化地傳遞初始化信息(比如內存布局、平臺配置、資源分布等),因此發明了 HOB 機制。

      另外,在 PEI 階段內存已經完全初始化,到了 DXE 階段使用的是已完成初始化的內存,DXE 只是“使用”和“管理”內存。一旦內存初始化完成(PEI 中后期),完全可以通過地址傳遞。HOB 本質上就是存在于內存中的結構體鏈表。

      但是需要注意:

      HOBs may be relocated in system memory by the HOB consumer phase. HOBs must not contain pointers to other data in the HOB list, including that in other HOBs. The table must be able to be copied without requiring internal pointer adjustment.[1]

      也就是需要注意 PEI 的 HOB 內存空間在 DXE 階段會被DxeCore relocation,所以不要用 HOB 來存放內存地址。[2]

      UEFI 提供了 HOB(Hand-Off-Block)機制,即在 PEI 階段將數據打包成數據塊存放在一段連續的內存中,數據塊的標識為 GUID,DXE 階段可以通過該 GUID 在 HOB 中找到對應數據塊。內存中一系列的 HOB 組成了 HOB List

      如下圖所示:
      HOB的結構列表

      HOB的結構列表 HOB List

      HOB 是非常重要數據結構,在 CAR 時期將會初始化好,UEFI 的早期的堆棧都基于HOB,
      PEI 階段會創建大量的 HOB,包含板級數據(UBA), silicon Hob(Memmap, RC resource), Setup,當進入PEI PostMem phase后,CAR 里的 HOB 會 shadow 到 Mem, 當進入 DXE (也就是PeiMain 調用了TempPtr.DxeIpl->Entry) 后,這些 HOB 會被 DXE driver 大量采用, 用來創建 Protocol 或者其他初始化。

      image

      由 PEI 階段進入 DXE 階段,PeiCore 中傳遞 HOB 的代碼

      HOB 在 PEI 階段會被修改(寫),在 DXE 和 SMM 中會被使用,原則上不推薦SMM修改 HOB。創建的單個HOB Size最大為 64K

      ASSERT (DataLength <= (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE))); 
      // Make sure that data length is not too long.
      

      需要大數據量的HOB需要注意。

      HOB 在PEI到 DXE 傳送信息的過程遵循 one Producer to one Consumer 的模式,即在PEI階段,一個 PEIM 創建一個 HOB,在 DXE 階段,一個 DXE Driver 使用那個 HOB 并且把 HOB 相關的信息傳送給其他的需要這些信息的 DXE 組件。

      因此,只有 PEI Phase 才允許增加或改動這些 HOBs,當 HOB List 被傳送給 DXE Phase 之后,他們就是只讀的(Read Only)。

      一個只讀的 HOB List 的延伸就是 Handoff 信息,比如 Boot Mode,必須以別的方式來處理。比如,DXE Phase 想要產生一個 Recovery 條件,它不能 update Boot Mode,而是通過使用特殊方式的 reset call 來實現。

      HOB list 是在 PEI Phase 被建立的,它存在于已經 present,initialized,tested 的Memory 中。一旦最初的 HOB List 被創建,物理內存就不能被 remapped, interleaved, 或者被后來的程序 moved。

      第一次進入 PeiCore 的時候,還是 CAR 階段,內存沒有初始化,InitializeMemoryServices 中調用 PeiCoreBuildHobHandoffInfoTable 開啟 HOB 創建;位置在Car中;
      image

      PeiCore() 進入 InitializeMemoryServices()

      image

      InitializeMemoryServices() 進入 PeiCoreBuildHobHandoffInfoTable()

      網上會找到很多資料說:
      如何增加一個新的HOB到HOB List中?

      PEI Phase(HOB Producer Phase)肯定包含一個指向PHIT HOB(這是HOB List的開始)的指針,然后遵循以下的步驟:

      1. 確定NewHobSize,即確定要創建的HOB的大?。ㄒ訠yte為單位)

      2. 確定是否有足夠的空閑內存分配給新的HOB(NewHobSize <= (PHIT->EfiFreeMemoryTop - PHIT->EfiFreeMemoryBottom))

      3. 在(PHIT->EfiFreeMemoryBottom)處構建HOB

      4. 設置PHIT->EfiFreeMemoryBottom = PHIT->EfiFreeMemoryBottom + NewHobSize~~

      但是在開發中,其實我們不必操作 PHIT 中的各個堆棧指針,已經做好的有很多輪子。

      代碼

      說了那么多,我們肯定是面向 API 編程,不用費勁心思去自己對HOB List中 PHIT的各種操作。

      1. 在PEI階段中,需要寫一個PEIM,來創建一個HOB。HOB不建議放內存地址,所以這里沒用字符數組。

      image

      #include <uefi.h>
      #include <Library/UefiLib.h>
      #include <Library/BaseLib.h>
      #include <Library/DebugLib.h>
      #include <Library/BaseMemoryLib.h>
      #include <Library/UefiDriverEntryPoint.h>
      #include <Library/PeimEntryPoint.h>
      #include <Library/PeiServicesLib.h>
      #include <Library/PeiServicesTablePointerLib.h>
      #include <Pi/PiHob.h>
      #include <Pi/PiPeiCis.h>
      
      EFI_GUID gEfiMyPeimHobGuid = {0x34ad055e, 0x1c21, 0x4b06, {0x80, 0x2f, 0xcd, 0x8a, 0x34, 0x2b, 0xa8, 0xc9}};
      
      // define a data struct for HOB Create
      typedef struct _MY_PEIM_HOB
      {
        EFI_HOB_GUID_TYPE     EfiHobGuidType;
        CHAR8 c0;
        CHAR8 c1;
        CHAR8 c2;
        CHAR8 c3;
        CHAR8 c4;
        CHAR8 c5;
        CHAR8 c6;
        CHAR8 c7;
        CHAR8 c8;
        CHAR8 c9;
      } MY_PEIM_HOB;
      
      // PEI Module Entry Function
      EFI_STATUS
      EFIAPI
      MyPeimHobEntry(
        IN       EFI_PEI_FILE_HANDLE  FileHandle,
        IN CONST EFI_PEI_SERVICES     **PeiServices
      )
      {
        EFI_STATUS Status;
        DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] MyPeimHobEntry Start..\n"));
      
        MY_PEIM_HOB *Hob = NULL;
      
        // create HOB by PeiServices
        Status = PeiServicesCreateHob (
                                 EFI_HOB_TYPE_GUID_EXTENSION,
                                 sizeof(MY_PEIM_HOB),
                                 &Hob);
      
        // fill the HOB data [Guid + 'Hello HOB!']
        if (!EFI_ERROR(Status))
        {
          Hob->EfiHobGuidType.Name = gEfiMyPeimHobGuid;
          Hob->c0 = 'H';
          Hob->c1 = 'e';
          Hob->c2 = 'l';
          Hob->c3 = 'l';
          Hob->c4 = 'o';
          Hob->c5 = ' ';
          Hob->c6 = 'H';
          Hob->c7 = 'O';
          Hob->c8 = 'B';
          Hob->c9 = '!';
      
        }
      
        DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] MyPeimHobEntry End..\n"));
        return EFI_SUCCESS;
      }
      
      [Defines]
        INF_VERSION = 0x00010006
        BASE_NAME = MyPeimHob
        FILE_GUID = e1223900-9e9a-4a7d-8835-ff4f54f5cff9
        MODULE_TYPE = PEIM
        VERSION_STRING = 1.0
        ENTRY_POINT = MyPeimHobEntry
      
      [Sources]
        MyPeimHob.c
      
      [Packages]
        MdePkg/MdePkg.dec
        ShellPkg/ShellPkg.dec
        MdeModulePkg/MdeModulePkg.dec
      
      [LibraryClasses]
        BaseLib
        PeimEntryPoint
        BaseMemoryLib
        DebugLib
        PeiServicesLib
      
      [depex]
        TRUE
      
      1. 在DXE階段中,需要寫一個DXE Driver,來獲得之前創建好的HOB,并打印出來。
        image
      #include <uefi.h>
      #include <Library/UefiLib.h>
      #include <Library/BaseLib.h>
      #include <Library/DebugLib.h>
      #include <Library/BaseMemoryLib.h>
      #include <Library/UefiDriverEntryPoint.h>
      #include <Pi/PiBootMode.h>
      #include <Pi/PiHob.h>
      #include <Library/HobLib.h>
      #include <Library/UefiBootServicesTableLib.h>
      
      EFI_GUID gEfiMyPeimHobGuid = {0x34ad055e, 0x1c21, 0x4b06, {0x80, 0x2f, 0xcd, 0x8a, 0x34, 0x2b, 0xa8, 0xc9}};
      
      typedef struct _MY_PEIM_HOB
      {
        EFI_HOB_GUID_TYPE     EfiHobGuidType;
        CHAR8 c0;
        CHAR8 c1;
        CHAR8 c2;
        CHAR8 c3;
        CHAR8 c4;
        CHAR8 c5;
        CHAR8 c6;
        CHAR8 c7;
        CHAR8 c8;
        CHAR8 c9;
      } MY_PEIM_HOB;
      
      
      EFI_STATUS
      EFIAPI
      MyDxeHobEntry(
        IN EFI_HANDLE        ImageHandle,
        IN EFI_SYSTEM_TABLE  *SystemTable
      )
      {
        EFI_STATUS Status = EFI_SUCCESS;
        DEBUG ((EFI_D_ERROR , "[MyHelloWorldHob] MyDxeHobEntry Start..\n"));
        MY_PEIM_HOB *Hob;
      
        // get the first Hob connected with [gEfiMyPeimHobGuid] by Guid.
        Hob = GetFirstGuidHob (&gEfiMyPeimHobGuid);
      
        // parse the hob and print debug info
        if ( Hob != NULL)
        {
          DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] MyDxeHob Guid:%g\n", Hob->EfiHobGuidType.Name));
          DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] %c \n", Hob->c0));
          DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] %c \n", Hob->c1));
          DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] %c \n", Hob->c2));
          DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] %c \n", Hob->c3));
          DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] %c \n", Hob->c4));
          DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] %c \n", Hob->c5));
          DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] %c \n", Hob->c6));
          DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] %c \n", Hob->c7));
          DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] %c \n", Hob->c8));
          DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] %c \n", Hob->c9));
        }
      
      
        DEBUG ((EFI_D_ERROR , "[MyHelloWorldHob] MyDxeHobEntry End..\n"));
        return Status;
      }
      
      
      [Defines]
        INF_VERSION = 0x00010006
        BASE_NAME = MyDxeHob
        FILE_GUID = 0760c3a1-a98e-4d86-8102-160d49e29e51
        MODULE_TYPE = UEFI_DRIVER
        VERSION_STRING = 1.0
        ENTRY_POINT = MyDxeHobEntry
      
      [Sources]
        MyDxeHob.c
      
      [Packages]
        MdePkg/MdePkg.dec
        ShellPkg/ShellPkg.dec
        MdeModulePkg/MdeModulePkg.dec
      
      [LibraryClasses]
        UefiDriverEntryPoint
        BaseLib
        BaseMemoryLib
        DebugLib
        PrintLib
        DevicePathLib
        UefiBootServicesTableLib
        MemoryAllocationLib
        UefiLib
        HobLib
      
      [depex]
        TRUE
      
      1. 根據PEIM和DXE Driver的類型,填寫OvmfPkgX64.fdf和OvmfPkgX64.dsc,來編譯寫好的兩個模塊,具體
        OvmfPkgX64.fdf

      image

      image

      OvmfPkgX64.dsc
      image

      image

      最后build一下,然后再在qemu目錄下創建setup-qemu-x64.bat文件,里面內容

      "D:\Program Files\qemu\qemu-system-x86_64.exe" -bios "D:\edk2\edk2\Build\OvmfX64\DEBUG_VS2019\FV\OVMF.fd" -M "pc" -m 256 -cpu "qemu64" -boot order=dc -serial stdio -hda fat:rw:D:\edk2\ovmf\esp -net none
      

      其中...\ovmf\esp文件夾需要自己創建,或者改成自己想掛載的路徑下。

      在qemu目錄下執行qemu>setup-qemu-x64.bat | findstr MyHelloWorldHob 查看結果

      image

      在這個例子里用GUID直接找HOB,實際開發中,會使用GetHobList()找到HOB頭,然后循環調用GetNextHob()來找對應類型的HOB,可以參考EDK2中的原生代碼,全局搜索GetNextHob()這個函數就能找到。篇幅原因,這里先Todo.......

      后記:HOB 是如何跨階段傳遞的?

      1. 在 Cache-As-RAM 中創建

      PEI 階段在 DRAM 初始化之前運行,因此它使用 Cache-As-RAM(CAR) 作為臨時內存。

      HOB 就是在這個 CAR 中被創建的。

      在早期 PEI 階段,HOB 是保存在這個臨時的??臻g里的。

      2. 內存初始化之后,遷移 HOB

      當 DRAM 初始化完成之后,PEI Core 會分配一塊真實的內存區域作為 永久內存池(Permanent Memory)。

      此時,PEI Core 會把已經存在于 CAR 中的 HOB 數據復制到新分配的 DRAM 區域。

      在 PeiMain 中,PeiDispatcher() 會調用一個專門用于初始化永久內存的PEIM,這個PEIM根據你所編譯的Pkg不同而不同。這個PEIM會進行內存初始化。

      這一步叫做 HOB 的重定位(HOB Relocation)。

      內核會更新 HOB list 的起始地址指針。

      3. DXE 階段讀取 HOB

      當轉交控制權給 DXE Loader 時,PEI 會通過 EFI_PEI_HOB_POINTER 將 HOB list 的新地址傳遞過去。

      DXE Core 通過這個地址獲取 HOB 列表,從而繼續處理。


      1. UEFI Platform Initialization Specification ??

      2. UEFI 基礎教程 (七) - HOB 簡單使用 ??

      posted @ 2025-05-30 16:47  Tyler77  閱讀(435)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 国产第一页浮力影院入口| 国产精品亚洲中文字幕| 国产网友愉拍精品视频手机| 精品一区二区三区自拍图片区| 天天澡日日澡狠狠欧美老妇| 国产视频最新| 伊人久久大香线蕉综合影院| 亚洲人成网网址在线看| 1区2区3区4区产品不卡码网站 | 亚洲夂夂婷婷色拍ww47| 国产一级二级三级毛片| 国产午夜视频在线观看| 中文字幕少妇人妻精品| 欧美日韩一线| 国产精品成人av电影不卡| 蜜桃无码一区二区三区| jizzjizz少妇亚洲水多| 亚洲免费观看在线视频| 国产成人一区二区不卡| 波多野结衣的av一区二区三区| 超碰成人精品一区二区三| 国产永久免费高清在线观看| 国产av中文字幕精品| 国产播放91色在线观看| 亚洲男女羞羞无遮挡久久丫 | 日韩高清免费一码二码三码| 人人爽人人爽人人片av东京热| 男女一级国产片免费视频| 九九热在线这里只有精品| 国产精品乱子乱xxxx| 一级女性全黄久久片免费| 国产精成人品日日拍夜夜| 97超级碰碰碰碰久久久久| 国产成人午夜在线视频极速观看| 永久无码天堂网小说区| 国产高颜值极品嫩模视频| 综合色一色综合久久网| 亚洲色av天天天天天天| 亚洲人妻精品中文字幕| 荥经县| 亚洲三级香港三级久久|