UEFI Driver Model là gì?
UEFI Driver Model là mô hình tách biệt driver khỏi controller cụ thể. Thành phần trung tâm là Driver Binding Protocol với Supported/Start/Stop.
UEFI Driver Model là mô hình để driver nhận diện controller, start thiết bị và stop/cleanup khi cần. Thành phần trung tâm là Driver Binding Protocol với ba hàm: Supported(), Start() và Stop().
Đừng học ba hàm này như ba dòng lý thuyết. Trong debug thực tế, chúng là ba điểm breakpoint quan trọng nhất khi một driver “không ăn” vào device.
Tại sao UEFI cần Driver Model?
Nếu không có một driver model chung, driver và controller rất dễ bị gắn chặt với nhau: driver phải biết trước mình quản lý thiết bị nào. UEFI Driver Model tách hai thứ này ra:
- Driver biết mình có thể quản lý loại thiết bị nào
- Controller là thiết bị cụ thể xuất hiện trên bus
Khi firmware cần enumerate thiết bị, nó hỏi từng driver: “Mày có hỗ trợ controller này không?” (Supported()). Nếu có, firmware nói “thì start đi” (Start()). Cơ chế này cho phép cùng một driver xử lý nhiều instance của cùng loại hardware, và firmware có thể load/unload driver mà không cần biết trước hardware layout.
Ba hàm cốt lõi
Supported()
Probe nhẹ: driver có hỗ trợ controller này không? Không được giữ resource sau khi return.
Start()
Bind thật sự: open protocol, allocate resource, install protocol; bus driver có thể tạo child handle.
Stop()
Cleanup đối xứng với Start: close protocol, uninstall protocol, free resource.
| Mục | Giá trị | Ghi chú |
|---|---|---|
| Supported() | Probe - không init | Nên nhanh và nhẹ. Nếu open protocol để kiểm tra, phải close ngay trước khi return. |
| Start() | Bind thật sự | Tạo context, mở protocol BY_DRIVER, install protocol cần thiết. Bus driver có thể tạo child handle; device driver thường install protocol lên controller handle. |
| Stop() | Cleanup đối xứng | Mỗi OpenProtocol trong Start cần CloseProtocol tương ứng trong Stop. Thiếu một cái thì DisconnectController có thể fail. |
Bus driver và Device driver
Hai pattern phổ biến trong Driver Model:
Bus driver - quản lý bus, enumerate child:
- Bind vào bus controller handle
- Tạo child handle cho mỗi device trên bus
- Install Device Path và bus-specific protocol lên child handle
- Ví dụ: PCI bus driver tạo handle cho mỗi PCI function
Device driver - quản lý một device/controller cụ thể:
- Bind vào controller handle hoặc child handle do bus driver tạo ra
- Install abstraction protocol lên handle phù hợp
- Có thể không tạo child handle; một số driver vẫn tạo child handle nếu thiết bị có nhiều logical unit
- Ví dụ: NVMe driver có thể bind vào PCI controller và tạo namespace child handle, rồi install Block I/O lên namespace handle
Phân biệt hai loại này quan trọng khi debug: nếu device không xuất hiện trong Boot Manager, có thể bus driver chưa tạo child handle, hoặc device driver chưa install đúng protocol.
Ví dụ debug thực tế
Một PCI device có mặt nhưng driver không hoạt động:
Supported()fail → kiểm tra Vendor ID/Device ID, protocol dependencySupported()pass nhưngStart()fail → xem driver open protocol nào, allocate gì, fail ở bước nào- Driver chạy nhưng device không lên boot menu → kiểm tra child handle có được tạo không, protocol chain có đủ đến Simple File System không
- Unplug/reconnect lỗi → soi
Stop()cleanup, CloseProtocol có đủ không
ConnectController - ai trigger bind?
Driver không tự gọi Supported() và Start() - firmware làm điều đó qua ConnectController(). BDS/platform boot manager thường gọi ConnectAll() hoặc connect theo Device Path trước khi load OS, tùy platform policy. Nếu driver đã dispatch nhưng device vẫn chưa bind, kiểm tra ConnectController có được gọi chưa.
Component Name Protocol
Ngoài Driver Binding, driver thường implement thêm Component Name2 Protocol (EFI_COMPONENT_NAME2_PROTOCOL) để cung cấp tên hiển thị:
// Driver name hiển thị trong UEFI Shell và Boot Manager UI
CHAR16 *DriverName = L"My NVMe Driver v1.0";
// Controller name theo ngôn ngữ
CHAR16 *ControllerName = L"Intel NVMe Controller";
Không phải mọi driver đều bắt buộc phải có, nhưng Component Name2 (EFI_COMPONENT_NAME2_PROTOCOL) rất hữu ích cho UEFI Shell, debug và UI. Trong EDK II, driver thường install Driver Binding cùng ComponentName/ComponentName2 qua helper EfiLibInstallDriverBindingComponentName2().
Checklist driver model
Câu hỏi tự kiểm tra
- Tại sao UEFI cần Driver Model thay vì driver gắn cứng với controller?
Supported()khácStart()ở điểm quan trọng nào?- Bus driver và device driver khác nhau thế nào về child handle?
- Nếu
Stop()khôngCloseProtocol, điều gì xảy ra khiDisconnectController? - Ai trigger
Supported()vàStart()- driver tự gọi hay firmware gọi?
Bài liên quan
Nguồn tham khảo public
- UEFI Specification 2.11 - Driver Model
- EDK II UEFI Driver Writer’s Guide
- EDK II MdePkg - Protocol/DriverBinding.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.
Driver Binding Flow là gì?
Giải thích Supported, Start, Stop trong UEFI Driver Model và cách nó ảnh hưởng quá trình enumerate thiết bị.
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.
Biến note thành bài viết hoàn chỉnh
Notes là nơi ghi nhanh khái niệm.