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.
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()và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.
PlatformBootManagerBeforeConsole()
Connect device tối thiểu, setup console, đọc HOB để lấy boot mode.
Connect console & refresh
Connect ConIn/ConOut, refresh danh sách boot option từ device hiện có.
PlatformBootManagerAfterConsole()
Xử lý BootNext, BootOrder, hotkey, timeout. Platform policy quyết định ở đây.
Load và Start image
Gọi LoadImage() và StartImage() cho option được chọn. Nếu fail, thử option tiếp theo.
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
- DXE Core trigger BDS bằng cơ chế nào?
- BDS đọc HOB boot mode để làm gì?
ConnectAll()hoặc connect theo Device Path giúp gì trước khi BDS load image?BootNextkhácBootOrderở điểm nào?LoadImage()trảEFI_NOT_FOUND- nguyên nhân có thể là gì?PlatformBootManagerAfterConsole()thường xử lý những gì?- Nếu tất cả boot option fail, BDS thường làm gì?
Bài liên quan
- DXE là gì?
- Boot####, BootOrder và BootNext là gì?
- Device Path là gì?
- BDS → TSL Handoff là gì?
- HOB là gì?
- ExitBootServices là gì?
Nguồn tham khảo public
- UEFI Specification 2.11 - Boot Manager
- EDK II MdeModulePkg - BdsDxe
- EDK II MdeModulePkg - PlatformBootManagerLib
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.
Boot####, BootOrder và BootNext là gì?
Boot#### là EFI_LOAD_OPTION trong NVRAM chứa attributes, Device Path và optional data. BootOrder và BootNext điều khiển thứ tự BDS thử boot.
BDS → TSL Handoff là gì?
Giải thích cách BDS chọn boot option, load EFI image và bàn giao cho OS loader trước ExitBootServices.
Device Path trong UEFI là gì?
Device Path mô tả đường đi từ bus phần cứng đến file EFI qua chuỗi node nhị phân. Hiểu cấu trúc này giúp debug boot fail và Boot#### stale sau thay disk.
Biến note thành bài viết hoàn chỉnh
Notes là nơi ghi nhanh khái niệm.