HOB là gì trong UEFI?

HOB là dữ liệu PEI bàn giao cho DXE trong boot flow UEFI, giúp DXE biết memory, resource và firmware volume ban đầu.

Cập nhật 6 phút đọc
BIOS Terms cover

HOB (Hand-Off Block) là danh sách dữ liệu mà PEI xây dựng rồi bàn giao cho DXE. PEI không thể “nói miệng” với DXE - nó phải đóng gói toàn bộ thông tin về memory, firmware volume và resource vào HOB list trước khi nhảy sang DXE Core.

Nếu PEI là người chuẩn bị nền tảng, thì HOB là biên bản bàn giao để DXE biết hệ thống đang ở trạng thái nào.

01 PEI

Tạo HOB

Init memory, thu thập resource, đóng gói vào HOB list.

02 HOB list

Danh sách block

Mỗi block có EFI_HOB_GENERIC_HEADER: HobType, HobLength, Reserved.

03 DXE Core

Consume HOB

Đọc HOB list để biết memory map, FV, resource trước khi dispatch driver.

HOB chứa gì?

Mục Giá trị Ghi chú
EFI_HOB_TYPE_MEMORY_ALLOCATION Vùng memory đã được PEI cấp phát Các vùng đã được PEI dùng hoặc cấp phát - DXE không nên coi chúng là vùng trống thông thường.
EFI_HOB_TYPE_RESOURCE_DESCRIPTOR Tài nguyên hệ thống System memory, MMIO, I/O, reserved region. DXE dùng để xây memory map ban đầu.
EFI_HOB_TYPE_FV Firmware Volume Chỉ ra FV base + size. DXE Dispatcher tìm driver từ danh sách FV này.
EFI_HOB_TYPE_GUID_EXTENSION Dữ liệu custom theo GUID Platform module dùng để truyền BoardId, config, kết quả silicon init sang DXE.
EFI_HOB_TYPE_HANDOFF Thông tin handoff từ PEI Chứa boot mode, memory top, HOB list start/end. Block đầu tiên trong mọi HOB list.
EFI_HOB_TYPE_END_OF_HOB_LIST Marker kết thúc danh sách Luôn là block cuối. GetNextHob() dừng tại đây.

HOB được đọc ở đâu trong boot flow?

Phần lớn tài liệu chỉ nói DXE Core đọc HOB - đúng, nhưng chưa đủ. Trong EDK II, HOB list thường vẫn có thể được truy cập trong DXE và giai đoạn BDS trước ExitBootServices(), nên không chỉ DXE Core mới đọc HOB:

  • DXE Core đọc ngay đầu để lấy memory map, FV list, boot mode - đây là lần đọc quan trọng nhất.
  • DXE driver thông thường đọc GUID HOB trong EntryPoint để lấy dữ liệu platform PEI đã chuẩn bị, ví dụ BoardId, silicon config, kết quả memory training.
  • PlatformBootManagerLib - chạy ở đầu BDS - cũng có thể đọc HOB để lấy boot mode (BOOT_WITH_FULL_CONFIGURATION, BOOT_ON_S4_RESUME, v.v.) và quyết định hành vi boot theo từng tình huống.

EFI_HOB_TYPE_HANDOFF chứa BootMode chính là field được BDS-level code hay đọc lại. Nếu bạn thấy log BootMode = 0x01 ở đầu BDS, đó là dữ liệu từ HOB list PEI để lại, không phải từ variable.

Cách đọc HOB trong DXE

HobLib trong EDK II cung cấp bộ API chuẩn. Không cần tự parse header thủ công.

Đọc GUID HOB - dùng nhiều nhất trong driver thực tế:

#include <Library/HobLib.h>

EFI_HOB_GUID_TYPE *GuidHob = GetFirstGuidHob(&gMyPlatformInfoGuid);
if (GuidHob == NULL) {
  // PEI chưa tạo HOB này - lỗi nằm ở PEI, không phải DXE
  DEBUG((DEBUG_ERROR, "PlatformInfo HOB not found\n"));
  return EFI_NOT_FOUND;
}

MY_PLATFORM_INFO *Info = GET_GUID_HOB_DATA(GuidHob);
// Info trỏ thẳng vào payload - cast trực tiếp là đủ
DEBUG((DEBUG_INFO, "BoardId = %u\n", Info->BoardId));

GET_GUID_HOB_DATA là macro, không allocate memory - nó chỉ tính offset sizeof(EFI_HOB_GUID_TYPE) từ đầu block. Payload nằm ngay sau header.

Đọc boot mode từ Handoff HOB:

// GetBootModeHob() là wrapper đọc EFI_HOB_TYPE_HANDOFF
EFI_BOOT_MODE BootMode = GetBootModeHob();

if (BootMode == BOOT_ON_S4_RESUME) {
  // Xử lý S4 resume khác với normal boot
}

Platform code ở giai đoạn BDS có thể đọc boot mode để phân nhánh logic, ví dụ xử lý resume, recovery hoặc normal boot khác nhau.

Duyệt toàn bộ HOB list khi cần enumerate resource:

EFI_PEI_HOB_POINTERS Hob;
Hob.Raw = GetHobList(); // Con trỏ đầu HOB list

while (!END_OF_HOB_LIST(Hob)) {
  if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
    EFI_HOB_RESOURCE_DESCRIPTOR *Res = Hob.ResourceDescriptor;
    DEBUG((DEBUG_INFO, "Resource: Base=0x%lx Len=0x%lx Type=%d\n",
           Res->PhysicalStart,
           Res->ResourceLength,
           Res->ResourceType));
  }
  Hob.Raw = GET_NEXT_HOB(Hob); // Dùng HobLength để nhảy sang block tiếp
}

GET_NEXT_HOB dùng HobLength trong header để tính offset - đây là lý do mỗi HOB bắt buộc phải có header đúng chuẩn. HOB bị corrupt header sẽ khiến vòng lặp nhảy sai địa chỉ.

PEI tạo HOB như thế nào?

Hiểu cách PEI tạo HOB giúp bạn debug phía producer khi DXE không đọc được đúng dữ liệu.

// Thông báo vùng system memory sau khi DRAM init xong
BuildResourceDescriptorHob(
  EFI_RESOURCE_SYSTEM_MEMORY,
  EFI_RESOURCE_ATTRIBUTE_PRESENT   |
  EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
  EFI_RESOURCE_ATTRIBUTE_TESTED,
  PcdGet64(PcdDramBase),
  PcdGet64(PcdDramSize)
);

// Truyền dữ liệu platform-specific sang DXE qua GUID HOB
MY_PLATFORM_INFO *Info = BuildGuidHob(
                           &gMyPlatformInfoGuid,
                           sizeof(MY_PLATFORM_INFO)
                         );
if (Info != NULL) {
  Info->BoardId      = DetectedBoardId;
  Info->FeatureFlags = DetectedFeatures;
}

BuildGuidHob() allocate block trong HOB list và trả về pointer vào payload - bạn ghi dữ liệu trực tiếp vào đó. Không cần copy thêm bước nào.

Khi debug HOB

Checklist khi nghi DXE thiếu thông tin từ PEI

Khi nào không cần đụng tới HOB?

Nếu bạn chỉ viết DXE driver độc lập, consume protocol bình thường và không cần dữ liệu từ PEI, bạn có thể chưa cần đọc HOB ngay. Nhưng khi lỗi nằm ở ranh giới PEI → DXE - driver không chạy dù build pass, memory map sai, FV phụ không được scan - HOB là một trong những nơi đầu tiên nên kiểm tra.

Lỗi hiểu nhầm hay gặp

HOB không phải UEFI variable. Variable lưu được qua reboot nếu non-volatile. HOB chỉ có ý nghĩa trong lần boot hiện tại - sau ExitBootServices(), OS đã nhận quyền quản lý hệ thống và HOB không còn là cơ chế dữ liệu mà firmware hay OS nên dựa vào nữa.

HOB không phải Protocol. Protocol là interface publish lên handle database, có thể locate bất kỳ lúc nào trong DXE. HOB là dữ liệu tĩnh - PEI ghi một lần, DXE đọc lại, không có event hay callback.

DXE không phải nơi duy nhất đọc HOB. BDS platform code cũng đọc HOB, đặc biệt là boot mode. Nếu BDS có hành vi sai ở S3/S4/recovery, hãy kiểm tra HOB trước khi nghi variable hay policy.

Bài liên quan

Nguồn tham khảo public

Thấy nội dung này hữu ích?

Lưu lại hoặc chia sẻ cho người cũng đang học firmware, BIOS/UEFI và embedded systems.

Nội dung liên quan

Một số bài viết, ghi chú hoặc project có liên quan đến nội dung bạn vừa đọc.

Biến note thành bài viết hoàn chỉnh

Notes là nơi ghi nhanh khái niệm.