UEFI Service Driver là gì?
UEFI Service Driver install protocol lên service handle, không cần Driver Binding. Hiểu service handle pattern, khi nào dùng thay vì driver binding, và cách trace service protocol.
UEFI Service Driver là driver install protocol cung cấp dịch vụ cho các driver hoặc module khác - mà không cần EFI_DRIVER_BINDING_PROTOCOL. Nó không bind vào controller, không có Supported()/Start()/Stop(). Nó chỉ làm một việc: install protocol lên một handle để consumer locate và dùng.
Đây là loại driver đơn giản nhất về cấu trúc, nhưng dễ bị viết sai về ownership, lifetime, và khi nào nên dùng service handle mới thay vì install lên handle có sẵn.
Service driver vs Driver Binding driver
| Mục | Giá trị | Ghi chú |
|---|---|---|
| Driver Binding driver | Bind vào controller | Cần Supported()/Start()/Stop(). Bind vào hardware handle. Protocol phụ thuộc vào hardware present. |
| Service driver | Install service protocol | Không Supported()/Start()/Stop(). Install lên service handle mới hoặc handle có sẵn. Protocol available sau khi driver dispatch và InstallProtocolInterface() thành công. |
| Khi nào dùng service driver | Service không cần bind controller cụ thể | HII database, variable policy, crypto service, platform info, custom platform service - không cần bind trực tiếp vào một controller cụ thể. |
Entry point - install và xong
Service driver entry point đơn giản nhất trong UEFI:
EFI_STATUS EFIAPI
MyServiceDriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
MY_SERVICE_DATA *ServiceData;
// Allocate service context
Status = gBS->AllocatePool(
EfiBootServicesData,
sizeof(MY_SERVICE_DATA),
(VOID **)&ServiceData
);
if (EFI_ERROR(Status)) return Status;
// Init service context
InitMyService(ServiceData);
// Install protocol lên handle mới (NULL → firmware tạo handle)
EFI_HANDLE ServiceHandle = NULL;
Status = gBS->InstallProtocolInterface(
&ServiceHandle,
&gMyServiceProtocolGuid,
EFI_NATIVE_INTERFACE,
&ServiceData->Protocol
);
if (EFI_ERROR(Status)) {
gBS->FreePool(ServiceData);
return Status;
}
// Lưu handle để có thể uninstall sau nếu cần
ServiceData->ServiceHandle = ServiceHandle;
// Service handle tồn tại - consumer có thể LocateProtocol ngay bây giờ
return EFI_SUCCESS;
}
Không có ConnectController(). Không có DisconnectController(). Không có Stop(). Driver init xong là service available.
Service driver là boot-time DXE driver. Protocol của nó tồn tại trong handle database và được dùng trước
ExitBootServices(). Nếu service phải được OS gọi sau EBS, đó là runtime driver/runtime service design khác - xem UEFI Runtime Driver là gì?.
Service handle - tạo mới hay install lên handle có sẵn
Có hai cách install service protocol:
// Cách 1: Install lên handle MỚI
// Dùng khi service là độc lập, không liên quan handle nào khác
EFI_HANDLE ServiceHandle = NULL; // NULL → firmware tạo handle mới
gBS->InstallProtocolInterface(
&ServiceHandle,
&gMyServiceProtocolGuid,
EFI_NATIVE_INTERFACE,
&ServiceData->Protocol
);
// ServiceHandle bây giờ có giá trị - lưu lại nếu cần uninstall sau
// Cách 2: Install lên handle CÓ SẴN (ví dụ: ImageHandle)
// Dùng khi muốn associate service với module cụ thể
gBS->InstallProtocolInterface(
&ImageHandle, // handle đã tồn tại
&gMyServiceProtocolGuid,
EFI_NATIVE_INTERFACE,
&ServiceData->Protocol
);
| Mục | Giá trị | Ghi chú |
|---|---|---|
| Handle mới (NULL) | Service handle độc lập | Consumer dùng LocateProtocol để tìm. Phù hợp với global service không gắn với module cụ thể. |
| ImageHandle | Gắn với driver image | Phù hợp khi service lifetime gắn với driver image. Nếu driver hỗ trợ unload, unload handler phải uninstall protocol và free context đúng cách. |
| Handle khác | Gắn với entity khác | Ví dụ: install thêm protocol lên controller handle để augment capability. Cần cẩn thận ownership. |
Consumer locate service - LocateProtocol
Consumer locate service protocol qua LocateProtocol() - không cần biết handle cụ thể:
MY_SERVICE_PROTOCOL *MyService;
Status = gBS->LocateProtocol(
&gMyServiceProtocolGuid,
NULL,
(VOID **)&MyService
);
if (EFI_ERROR(Status)) {
// Service chưa available - có thể driver publish service chưa dispatch
// Hoặc có thể register notify khi protocol được install
return Status;
}
// Dùng service
MyService->DoSomething(MyService, ...);
Nếu consumer cần biết khi service available, có thể dùng RegisterProtocolNotify():
// Phải tạo event trước khi register notify
EFI_EVENT NotifyEvent;
VOID *Registration;
Status = gBS->CreateEvent(
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
MyServiceNotifyHandler,
NULL,
&NotifyEvent
);
if (EFI_ERROR(Status)) return Status;
// Register để được notify khi service protocol được install
Status = gBS->RegisterProtocolNotify(
&gMyServiceProtocolGuid,
NotifyEvent,
&Registration
);
Ví dụ service driver trong EDK II
| Mục | Giá trị | Ghi chú |
|---|---|---|
| HII Database Driver | edk2/MdeModulePkg/Universal/HiiDatabaseDxe/ | Install EFI_HII_DATABASE_PROTOCOL, EFI_HII_FONT_PROTOCOL, v.v. lên service handle. BIOS Setup UI, string package, form package đều dùng đây. |
| Variable Policy Driver | edk2/MdeModulePkg/Universal/Variable/ | Publish policy protocol để DXE/platform code đăng ký variable policy trong boot phase; thường bị lock ở EndOfDxe/SmmReadyToLock tùy platform. Không phải runtime variable service. |
| Security Manager | edk2/MdeModulePkg/Universal/SecurityStubDxe/ | Install EFI_SECURITY_ARCH_PROTOCOL lên service handle. Được hook trong LoadImage path. |
| Platform Info Driver | Platform package | Publish board ID, hardware config, silicon policy. Consumer DXE driver LocateProtocol để đọc. |
Failure pattern - service không available khi consumer cần
LocateProtocol fail - service chưa dispatch:
- Consumer DXE driver dispatch trước service driver
- DEPEX của consumer phải khai báo GUID của service protocol:
[Depex]
gMyServiceProtocolGuid # ← GUID này, không phải Driver Binding GUID
Nếu thiếu DEPEX, consumer có thể dispatch trước khi service available.
Service install nhưng GUID sai:
# UEFI Shell: kiểm tra service protocol có trên handle nào không
Shell> dh -p <protocol_GUID>
# Không thấy → service driver chưa dispatch, hoặc GUID mismatch
Shell> dh -v # tìm handle có gMyServiceProtocolGuid
Service context bị free sớm:
- Protocol vẫn còn trong handle database nhưng interface trỏ tới memory đã free
- Consumer
LocateProtocol()thành công nhưng gọi function pointer thì crash - Xảy ra khi error path FreePool context trước khi UninstallProtocolInterface
Trace khi service protocol không available
# UEFI Shell: kiểm tra protocol có trong handle database không
Shell> dh -p EFI_HII_DATABASE_PROTOCOL # hoặc GUID của service cần tìm
# Nếu không thấy: service driver chưa dispatch
# Nguyên nhân thường gặp:
# 1. FDF thiếu service driver
# 2. DEPEX của service driver chưa thỏa (protocol required chưa install)
# 3. Service driver dispatch thành công nhưng install fail im lặng
# Tìm trong build map (path tùy platform/toolchain)
grep "MyServiceDriver" Build/*/*/FV/*.map
# EDK II - service driver pattern
grep -r "InstallProtocolInterface\|LocateProtocol" \
edk2/MdeModulePkg/Universal/HiiDatabaseDxe/ --include="*.c" | head -10
Checklist Service Driver
Câu hỏi tự kiểm tra
- Service driver khác Driver Binding driver ở điểm cốt lõi nào?
- Tại sao consumer cần khai báo service protocol GUID trong DEPEX?
- Service handle mới (NULL) và ImageHandle khác nhau về lifetime thế nào?
- Nếu
LocateProtocol()fail, nguyên nhân phổ biến nhất là gì? - Khi nào service driver cần chủ động
UninstallProtocolInterface()?
Bài liên quan
Nguồn tham khảo public
- UEFI Specification 2.11 - InstallProtocolInterface
- EDK II - HiiDatabaseDxe
- EDK II UEFI Driver Writer’s Guide - Service Driver
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.
Start() trong UEFI Driver Model là gì?
Start() là nơi driver bind vào controller: open BY_DRIVER, install protocol, tạo child handle nếu là bus driver. Hiểu cleanup fail path và anti-pattern làm handle database bẩn.
Stop() trong UEFI Driver Model là gì?
Stop() là cleanup đối xứng của Start(). Hiểu CloseProtocol, uninstall protocol, NumberOfChildren, destroy child handle và anti-pattern làm DisconnectController fail.
Supported() trong UEFI Driver Model là gì?
Supported() là hàm probe của Driver Binding. Hiểu return status, OpenProtocol attribute đúng, anti-pattern làm driver không bao giờ bind và cách trace khi Supported fail.
Biến note thành bài viết hoàn chỉnh
Notes là nơi ghi nhanh khái niệm.