BDS là gì trong UEFI?

BDS là phase chọn boot option sau DXE. Firmware đọc BootOrder, connect device, load và start EFI image. Hiểu BDS giúp debug khi máy không boot đúng option.

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

BDS (Boot Device Selection) là phase sau DXE, nơi firmware chuyển từ “dựng môi trường driver” sang “chọn và khởi động OS”. Đây là nơi firmware đọc boot option từ NVRAM, connect các thiết bị cần thiết, load file .efi và trao quyền cho OS loader.

BDS không chỉ “chọn ổ cứng”. Nó phải resolve Device Path qua nhiều tầng phần cứng, kiểm tra file tồn tại, rồi mới gọi LoadImage()StartImage().

BDS được trigger như thế nào?

Trong UEFI PI/EDK II model, BDS thường được vào thông qua EFI_BDS_ARCH_PROTOCOL. Một BDS DXE module install protocol này, và DXE Core gọi entry của nó sau khi DXE dispatch hoàn tất.

// BDS module install protocol này trong entry point
EFI_BDS_ARCH_PROTOCOL  mBds = {
  BdsEntry    // hàm firmware gọi khi DXE xong
};

gBS->InstallProtocolInterface(
       &gBdsHandle,
       &gEfiBdsArchProtocolGuid,
       EFI_NATIVE_INTERFACE,
       &mBds
     );

Sau khi DXE dispatch hoàn tất và architectural protocols cần thiết đã sẵn sàng, DXE Core chuyển sang BDS thông qua BDS architectural protocol. Từ đây, boot policy chủ yếu do BDS/platform policy quyết định.

Flow BDS

Flow dưới đây lấy góc nhìn EDK II, nơi BDS policy thường được chia qua PlatformBootManagerLib.

01

PlatformBootManagerBeforeConsole()

Connect device tối thiểu, setup console, đọc HOB để lấy boot mode.

02

Connect console & refresh

Connect ConIn/ConOut, refresh danh sách boot option từ device hiện có.

03

PlatformBootManagerAfterConsole()

Xử lý BootNext, BootOrder, hotkey, timeout. Platform policy quyết định ở đây.

04

Load và Start image

Gọi LoadImage() và StartImage() cho option được chọn. Nếu fail, thử option tiếp theo.

05

Fallback

Nếu tất cả option fail, thường vào Boot Manager UI hoặc loop lại.

HOB boot mode ảnh hưởng BDS thế nào?

BDS hoặc platform boot manager có thể đọc boot mode từ HOB list - giá trị PEI đã set - để quyết định hành vi:

EFI_BOOT_MODE BootMode = GetBootModeHob();

switch (BootMode) {
  case BOOT_WITH_FULL_CONFIGURATION:
    // Normal boot - enumerate thiết bị đầy đủ
    break;
  case BOOT_ON_S4_RESUME:
    // Resume từ hibernate - skip một số init
    break;
  case BOOT_IN_RECOVERY_MODE:
    // Recovery - load recovery image thay vì OS loader thông thường
    break;
}

Đây là lý do BDS đôi khi đọc lại HOB dù đã ở giai đoạn muộn - boot mode là thông tin từ PEI, không phải từ variable.

ConnectAll và tại sao quan trọng

Trước khi BDS có thể load file .efi, các controller trên đường đi tới boot device phải được connect. Tùy platform policy, BDS có thể connect toàn bộ controller bằng helper như EfiBootManagerConnectAll(), hoặc chỉ connect các controller nằm trên Device Path của boot option:

// EfiBootManagerConnectAll() là helper thường dùng trong EDK II BDS
EfiBootManagerConnectAll();

// Hoặc connect theo Device Path cụ thể
EfiBootManagerConnectDevicePath(DevicePath, NULL);

Nếu BDS không connect đủ controller trước khi thử load, LoadImage() có thể trả EFI_NOT_FOUND dù file thực sự tồn tại - vì Simple File System Protocol chưa được publish.

PlatformBootManager - nơi platform policy sống

Trong EDK II, BDS core logic nằm ở MdeModulePkg/Universal/BdsDxe. Nhưng platform-specific policy sống ở PlatformBootManagerLib - library mà OEM/platform vendor implement:

Mục Giá trị Ghi chú
PlatformBootManagerBeforeConsole() Chạy trước khi console sẵn sàng Connect minimal device, đọc HOB boot mode, setup boot option lần đầu.
PlatformBootManagerAfterConsole() Chạy sau khi console sẵn sàng Xử lý timeout, hotkey, BootNext override, custom boot order policy.
PlatformBootManagerUnableToBoot() Gọi khi không có option nào boot được Platform quyết định fallback: hiện Boot Manager UI, loop, hay halt.

Đây là nơi tùy chỉnh boot behavior theo platform - ví dụ hiển thị logo, handle recovery hotkey, hay inject boot option cho PXE.

BootNext, BootOrder và Timeout

UINT32 Attributes =
  EFI_VARIABLE_NON_VOLATILE |
  EFI_VARIABLE_BOOTSERVICE_ACCESS |
  EFI_VARIABLE_RUNTIME_ACCESS;

// BootNext - ưu tiên option này cho lần boot hiện tại
// BDS thường delete BootNext sau khi dùng để chỉ có hiệu lực một lần
UINT16 BootNext = 0x0001;
gRT->SetVariable(L"BootNext", &gEfiGlobalVariableGuid,
                  Attributes, sizeof(UINT16), &BootNext);

// BootOrder - thứ tự ưu tiên
UINT16 BootOrder[] = { 0x0000, 0x0001, 0x0002 };
gRT->SetVariable(L"BootOrder", &gEfiGlobalVariableGuid,
                  Attributes, sizeof(BootOrder), BootOrder);

// Timeout - số giây BDS chờ trước khi auto-boot
// Timeout = 0: boot ngay, không chờ user input
// Ý nghĩa các giá trị đặc biệt phụ thuộc platform/implementation
UINT16 Timeout = 5;
gRT->SetVariable(L"Timeout", &gEfiGlobalVariableGuid,
                  Attributes, sizeof(UINT16), &Timeout);

BDS đọc BootNext trước BootOrder. Nếu BootNext tồn tại, BDS sẽ ưu tiên option đó cho lần boot hiện tại và thường delete BootNext để chỉ có hiệu lực một lần. Sau đó mới theo BootOrder từ đầu.

Khi debug BDS

Checklist khi máy không boot đúng option

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

BDS không tự connect tất cả device. Một số implementation chỉ connect device trên boot path, không connect tất cả. Nếu device cần debug không có driver bind, check xem BDS có gọi ConnectAll hay chỉ connect theo Device Path cụ thể.

BootOrder không phải list tên thiết bị. Nó là list số #### tương ứng với Boot#### variable. Thiếu Boot#### trong NVRAM mà BootOrder vẫn tham chiếu thì option đó bị skip.

BDS timeout = 0 không phải không có timeout. Timeout = 0 thường có nghĩa là boot ngay, không chờ user input. Ý nghĩa các giá trị đặc biệt khác phụ thuộc implementation/platform policy - không nên giả định nếu chưa kiểm tra firmware cụ thể.

Câu hỏi tự kiểm tra

  1. DXE Core trigger BDS bằng cơ chế nào?
  2. BDS đọc HOB boot mode để làm gì?
  3. ConnectAll() hoặc connect theo Device Path giúp gì trước khi BDS load image?
  4. BootNext khác BootOrder ở điểm nào?
  5. LoadImage() trả EFI_NOT_FOUND - nguyên nhân có thể là gì?
  6. PlatformBootManagerAfterConsole() thường xử lý những gì?
  7. Nếu tất cả boot option fail, BDS thường làm gì?

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.