Boot Services là gì?
Boot Services là nhóm API của UEFI chỉ hợp lệ trong boot time. Bao gồm memory, protocol, event, image và controller services - tất cả truy cập qua gBS.
Boot Services là tập hợp các API của UEFI chỉ hợp lệ trong boot time - trước khi OS loader gọi ExitBootServices(). Toàn bộ Boot Services được truy cập qua con trỏ toàn cục gBS (EFI_BOOT_SERVICES *).
DXE driver, UEFI application, và BDS đều dùng Boot Services để làm mọi việc: allocate memory, install/locate protocol, tạo event, load image và connect controller.
Boot Services rất tiện, nhưng có hạn sử dụng. Sau
ExitBootServices(),gBSkhông còn hợp lệ - mọi code dùng Boot Services sau điểm này là undefined behavior.
Các nhóm API chính
| Mục | Giá trị | Ghi chú |
|---|---|---|
| Memory Services | AllocatePool, AllocatePages, FreePool, FreePages | Cấp phát và giải phóng memory trong boot time. Memory type ảnh hưởng đến lifetime. |
| Protocol Services | InstallProtocolInterface, LocateProtocol, OpenProtocol, CloseProtocol | Xương sống của DXE driver model. Tất cả driver binding đều đi qua đây. |
| Event & Timer | CreateEvent, SetTimer, SignalEvent, WaitForEvent, CloseEvent | Dùng cho callback, notify khi protocol xuất hiện, timer-based polling. |
| Image Services | LoadImage, StartImage, Exit, UnloadImage | BDS dùng LoadImage/StartImage để chạy OS loader và UEFI application. |
| Controller Services | ConnectController, DisconnectController | Trigger Driver Binding - bind/unbind driver với controller. |
| Misc Services | Stall, SetWatchdogTimer, GetMemoryMap, LocateHandleBuffer | Delay, watchdog, lấy memory map trước ExitBootServices, tìm handle theo protocol. |
Memory type và lifetime
Khi allocate memory bằng Boot Services, memory type quyết định lifetime của vùng đó:
VOID *Buffer;
// EfiBootServicesData - chỉ tồn tại đến ExitBootServices()
gBS->AllocatePool(EfiBootServicesData, Size, &Buffer);
// EfiRuntimeServicesData - cần tồn tại sau ExitBootServices()
// Runtime driver dùng type này để OS không reclaim
gBS->AllocatePool(EfiRuntimeServicesData, Size, &Buffer);
Lỗi phổ biến nhất là allocate với EfiBootServicesData rồi lưu pointer vào structure dùng ở runtime path. Sau ExitBootServices(), vùng memory boot services có thể bị OS reclaim.
EfiRuntimeServicesData chỉ nên dùng cho dữ liệu thật sự thuộc runtime service hoặc runtime driver. Không nên dùng runtime memory type chỉ vì muốn “giữ pointer lâu hơn” - vùng này sẽ xuất hiện trong memory map và ảnh hưởng đến OS. Memory này cũng có thể liên quan đến SetVirtualAddressMap() nếu runtime code giữ pointer sau khi OS chuyển sang virtual address mode.
Event và TPL
Boot Services có cơ chế Event để xử lý callback và async notification. Mọi event chạy ở một TPL (Task Priority Level) nhất định:
EFI_EVENT Event;
// Tạo event sẽ signal khi protocol mới xuất hiện
gBS->CreateEvent(
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK, // TPL của callback
MyNotifyFunction,
NULL,
&Event
);
// Đăng ký với một protocol GUID
VOID *Registration;
gBS->RegisterProtocolNotify(&gEfiBlockIoProtocolGuid, Event, &Registration);
// Cleanup khi không cần
gBS->CloseEvent(Event);
TPL quan trọng để hiểu thứ tự xử lý và reentrancy:
| Mục | Giá trị | Ghi chú |
|---|---|---|
| TPL_APPLICATION (4) | Mức thấp nhất | Code ứng dụng thông thường chạy ở đây. |
| TPL_CALLBACK (8) | Event notify/callback | Hầu hết event callback chạy ở TPL_CALLBACK. |
| TPL_NOTIFY (16) | Critical section nhẹ | Dùng khi cần block TPL_CALLBACK trong một đoạn code ngắn. |
| TPL_HIGH_LEVEL (31) | Mức cao nhất | Dùng nội bộ bởi firmware. Không dùng trong driver thông thường. |
Khi code đang chạy ở TPL cao hơn, event ở TPL thấp hơn sẽ bị defer đến khi TPL giảm xuống.
Ở TPL cao, callback nên chạy ngắn và tránh làm việc nặng. Không nên wait lâu, polling phức tạp, hoặc gọi các Boot Services không phù hợp với TPL hiện tại. Nếu cần xử lý nhiều, nên defer sang ngữ cảnh TPL thấp hơn.
Boot Services và các bài đã học
Boot Services là nền tảng kết nối tất cả những gì đã học:
Protocol Services → gBS->InstallProtocolInterface / LocateProtocol / OpenProtocol
Handle Database → gBS->LocateHandleBuffer / ProtocolsPerHandle / OpenProtocolInformation
Driver Binding → gBS->ConnectController / DisconnectController
DXE Dispatcher → load/dispatch driver trong môi trường DXE nơi Boot Services đã sẵn sàng
Mọi thao tác với handle database, protocol install/locate, driver binding đều đi qua gBS. Đây là lý do tại sao hiểu Boot Services là hiểu DXE.
Phân biệt Boot Services và Runtime Services
Boot Services (gBS) | Runtime Services (gRT) | |
|---|---|---|
| Hợp lệ khi | Trước ExitBootServices() | Trước và sau ExitBootServices() |
| Dùng cho | Driver, BDS, OS loader | Variable, time, reset, runtime firmware services |
| Memory type | EfiBootServicesData/Code | EfiRuntimeServicesData/Code |
| Ví dụ | AllocatePool, LocateProtocol | GetVariable, ResetSystem |
Khi nào cần quan tâm đến Boot Services?
Hầu như mọi DXE driver đều dùng Boot Services - không thể tránh. Nhưng có một số tình huống cụ thể cần chú ý đặc biệt:
- Runtime driver phải tránh
gBSsauExitBootServices() - OS loader phải lấy memory map rồi gọi
ExitBootServices()đúng cách - Driver leak event hay memory nếu không
CloseEventvàFreePoolkhi cleanup - Code dùng
EfiBootServicesDatanhưng pointer được giữ lâu hơn boot time
Checklist Boot Services
Câu hỏi tự kiểm tra
- Boot Services được truy cập qua pointer nào?
- Điểm nào đánh dấu kết thúc validity của Boot Services?
EfiBootServicesDatavàEfiRuntimeServicesDatakhác nhau ở lifetime thế nào?- TPL dùng để làm gì trong Event model?
- Tại sao runtime driver không được gọi
gBS->LocateProtocol()? - Driver có thể dùng Boot Services trong
Stop()không? - Nếu event notify bị leak, debug như thế nào?
Bài liên quan
Nguồn tham khảo public
- UEFI Specification 2.11 - Boot Services
- EDK II MdePkg - UefiBootServicesTableLib.h
- EDK II MdePkg - UefiSpec.h
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.
DXE là gì trong UEFI?
DXE là phase firmware sau PEI, nơi driver được dispatch, protocol được install và Boot Services trở nên đầy đủ. DXE xây dựng môi trường để BDS có thể chọn và khởi động OS.
TPL và Event trong UEFI là gì?
TPL kiểm soát mức ưu tiên callback trong UEFI. Event là cơ chế notify/signal/wait. Hiểu TPL giúp debug deadlock, callback sai thời điểm và timer không fire.
Protocol trong UEFI là gì?
Protocol là interface install lên handle trong DXE, cho phép driver giao tiếp không phụ thuộc implementation. Hiểu Protocol giúp debug driver binding và locate fail.
Biến note thành bài viết hoàn chỉnh
Notes là nơi ghi nhanh khái niệm.