BDF trong PCIe là gì?
Giải thích BDF trong PCIe: Bus Device Function, địa chỉ thiết bị, enumeration, bridge bus number, multi-function device và debug device mất.
Bạn đọc log PCI và thấy dòng kiểu 00:1C.0, 02:00.0, 03:00.1. Driver thì báo không tìm thấy controller. OS thì thấy device ở 04:00.0, còn UEFI Shell hôm qua lại thấy ở 02:00.0. Nếu bạn không hiểu BDF, rất dễ debug nhầm device, đọc nhầm config space, hoặc hardcode sai địa chỉ.
BDF là tọa độ cơ bản nhất để nói chuyện với một PCI/PCIe function.
Nói ngắn gọn: BDF là Bus/Device/Function, địa chỉ logic của một PCI function trong PCI hierarchy. Firmware dùng BDF để đọc configuration space, enumerate thiết bị, gán resource, tạo EFI_PCI_IO_PROTOCOL và giúp driver bind đúng controller.
BDF trông như thế nào?
02:00.0
│ │ └─ Function = 0
│ └──── Device = 00
└─────── Bus = 02
BDF trong PCIe topology
Bus 00
├─ 00:00.0 Host bridge / root complex related function
├─ 00:1C.0 PCIe Root Port
│ └─ Bus 02
│ └─ 02:00.0 NVMe controller
├─ 00:1D.0 PCIe Root Port
│ └─ Bus 03
│ └─ 03:00.0 Ethernet controller
└─ 00:1F.3 Audio / chipset function 02:00.0 không có nghĩa là slot vật lý số 2. Nó nghĩa là function số 0, device số 0, trên bus số 2.
BDF trong enumeration flow
Start from root bridge
Firmware biết segment và bus range của root bridge.
Scan bus/device/function
Firmware thử đọc Vendor ID ở từng BDF.
If Vendor ID valid
Device/function tồn tại và configuration space đọc được.
If bridge found
Firmware gán secondary/subordinate bus và scan bus phía sau.
Assign BAR resources
BDF được gán MMIO/I/O resources phù hợp.
Create UEFI handle
Firmware install EFI_PCI_IO_PROTOCOL cho function đó.
Driver binds
DriverBinding Supported/Start dùng PciIo để match device.
Bus, Device, Function là gì?
| Phần | Ý nghĩa | Ghi chú debug |
|---|---|---|
| Bus | Số bus PCI | Bus 0 thường là root bus, bus sau bridge được firmware gán |
| Device | Số device trên bus | Thường 0 đến 31 trong PCI conventional addressing |
| Function | Function trong một device | 0 đến 7, dùng cho multi-function device |
| BDF đầy đủ | Bus:Device.Function | Ví dụ 02:00.0 |
| Segment/Domain | Miền PCI riêng trên hệ thống lớn | Có thể ghi 0000:02:00.0 trong OS |
| Root Bridge | Nguồn bus range | Mỗi root bridge có segment/bus range |
| Bridge | Tạo bus phía dưới | Secondary/subordinate bus quyết định BDF downstream |
| Endpoint | Thiết bị cuối | Thường là target driver bind |
Segment/Domain là gì?
Trên nhiều hệ thống, BDF đầy đủ có thêm segment hoặc domain phía trước.
0000:02:00.0
│ │ │ └─ Function
│ │ └──── Device
│ └─────── Bus
└──────────── Segment / Domain
| Khái niệm | Ý nghĩa | Debug |
|---|---|---|
| Segment | PCI segment group/domain | Hệ thống nhiều root complex có thể có nhiều segment |
| Domain trong Linux | Thường hiển thị dạng 0000:02:00.0 | Đừng bỏ qua nếu nhiều domain |
| UEFI root bridge | Có thể expose SegmentNumber | PciRootBridgeIo/PciHostBridge resource |
| Bus range | Mỗi segment có bus range riêng | Bus 02 ở segment 0 khác segment 1 |
| ACPI MCFG | Mô tả ECAM base theo segment/bus range | OS không thấy device nếu MCFG sai |
| Driver debug | Log segment nếu platform nhiều domain | Tránh đọc nhầm device |
| Server/SoC | Multi-root complex phổ biến hơn | BDF cần domain để đầy đủ |
| Hardcode | Hardcode 02:00.0 thiếu segment | Sai trên multi-segment system |
BDF và Configuration Space
BDF là địa chỉ để firmware truy cập configuration space của một PCI function.
| Config field | Offset thường gặp | Vì sao cần BDF |
|---|---|---|
| Vendor ID | 0x00 | Xác định function có tồn tại không |
| Device ID | 0x02 | Nhận diện thiết bị cụ thể |
| Command Register | 0x04 | Bật Memory/I/O/Bus Master |
| Status Register | 0x06 | Trạng thái và capability support |
| Class Code | 0x0B:0x09 | Nhận diện loại device |
| Header Type | 0x0E | Endpoint hay bridge, multi-function hay không |
| BAR0-BAR5 | 0x10 trở đi | Resource MMIO/I/O của function |
| Capability Pointer | 0x34 | MSI/MSI-X/PCIe capabilities |
Nếu bạn đọc sai BDF, mọi config field đều là của thiết bị khác hoặc trả 0xFFFF.
Vendor ID 0xFFFF tại một BDF
Khi đọc Vendor ID tại BDF và thấy 0xFFFF, thường là không có function response ở địa chỉ đó.
| Nguyên nhân | Ví dụ | Cách kiểm tra |
|---|---|---|
| BDF không tồn tại | Scan 02:00.0 nhưng bus 02 không có device | Scan toàn bus |
| Bus number sai | Bridge secondary bus chưa set đúng | Dump bridge bus registers |
| Link down | Root port chưa link up | Check PCIe link status |
| Device reset/power | Endpoint chưa ready | Check reset/power timing |
| Function không tồn tại | Đọc 02:00.3 nhưng device chỉ có function 0 | Check multi-function bit |
| Config access sai | ECAM/MMCONFIG base sai | Dùng PciRootBridgeIo để đọc |
| Policy hide/disable | BIOS setup disable slot | Check setup/policy/strap |
| Hotplug empty | Slot không có presence | Check hotplug state |
Function và multi-function device
Một PCI device có thể có nhiều function. Function 0 luôn quan trọng vì header type ở function 0 cho biết device có multi-function hay không.
| Khía cạnh | Ý nghĩa | Debug |
|---|---|---|
| Function 0 | Function đầu tiên | Luôn check trước |
| Header Type bit 7 | Multi-function bit | Nếu set, scan function 1 đến 7 |
| Function 1-7 | Các function phụ | Có thể là audio, management, sub-device |
| Same device number | Bus/device giống nhau, function khác | 02:00.0 và 02:00.1 |
| Different class | Mỗi function có class code riêng | Driver match theo function |
| Driver binding | Mỗi function có PciIo handle riêng | Driver bind từng function |
| Common bug | Chỉ scan function 0 | Mất function phụ |
| False scan | Scan function 1-7 khi không multi-function | Có thể đọc 0xFFFF, thường OK nhưng tốn thời gian |
BDF và bridge bus number
Bus number của endpoint phía sau bridge không cố định. Firmware gán bus number khi enumerate bridge.
BDF phía sau bridge phụ thuộc bus assignment
Before enumeration
└─ Root Port at 00:1C.0
└─ Endpoint phía sau chưa có bus number cuối
After enumeration
└─ Root Port at 00:1C.0
├─ Primary Bus = 00
├─ Secondary Bus = 02
├─ Subordinate Bus = 02
└─ Endpoint = 02:00.0 | Register | Ý nghĩa | Nếu sai |
|---|---|---|
| Primary Bus | Bus phía trên bridge | Hierarchy sai |
| Secondary Bus | Bus đầu tiên phía dưới bridge | Endpoint phía dưới không có BDF đúng |
| Subordinate Bus | Bus cuối phía dưới bridge | Switch/endpoint sâu hơn bị mất |
| Temporary assignment | Firmware set tạm trong lúc scan | Log giữa chừng có thể khác final |
| Final assignment | BDF cuối OS/driver thấy | Driver hardcode cũ có thể sai |
| Bus reserve | Dự trữ cho hotplug/switch | Không đủ bus làm hotplug fail |
| Root bridge bus range | Giới hạn toàn hierarchy | Không đủ bus để assign |
| ACPI handoff | OS cần biết bus range đúng | OS rescan thấy khác hoặc mất device |
BDF có thể thay đổi khi nào?
| Tình huống | Vì sao | Cách debug |
|---|---|---|
| Thêm/bớt PCIe switch | Bus topology thay đổi | So bridge bus assignment |
| Hotplug device | Firmware/OS reserve/assign bus khác | Check hotplug bus reserve |
| BIOS setting đổi | Disable/enable root port hoặc Above 4G | Compare setup variables |
| Firmware version đổi | Enumeration policy khác | Good/bad PCI log diff |
| OS reassign bus | OS policy khác firmware | Compare UEFI vs OS BDF |
| Multi-root segment | Domain khác | Log segment/domain đầy đủ |
| SR-IOV/ARI | Nhiều function/virtual function | Check capability and function numbering |
| Resource conflict | Allocator thay đổi hierarchy | Dump resource allocation log |
BDF trong UEFI Device Path
UEFI thường mô tả PCI device bằng device path node, ví dụ Pci(Device,Function) theo từng tầng, không chỉ một BDF phẳng.
| Khía cạnh | BDF | UEFI Device Path |
|---|---|---|
| Dạng | Bus:Device.Function | Chuỗi node theo đường đi |
| Mục tiêu | Địa chỉ config space hiện tại | Mô tả path đến device |
| Qua bridge | Bus number đã được assign | Có thể có nhiều Pci() node |
| Ổn định | Có thể đổi khi bus allocation đổi | Có thể ổn định hơn nếu topology cố định |
| Driver debug | Dễ đọc config space | Dễ trace path/controller |
| Boot option | Thường lưu device path | Không chỉ BDF |
| UEFI Shell | dh/devtree/map có thể hiện path | Hữu ích khi BDF đổi |
| Common bug | Hardcode BDF | Nên dùng device path/policy khi cần boot path |
BDF và EFI_PCI_IO_PROTOCOL
Sau PCI enumeration, mỗi PCI function thường có controller handle với EFI_PCI_IO_PROTOCOL. Protocol này gắn với một BDF cụ thể.
| Việc | Ý nghĩa | Debug |
|---|---|---|
| GetLocation | Lấy Segment/Bus/Device/Function | Log controller BDF |
| Config.Read | Đọc config space function đó | Vendor/class/BAR debug |
| GetBarAttributes | Xem BAR resource | BAR mapping debug |
| Attributes | Enable Memory/IO/BusMaster | Device hoạt động chưa |
| DriverBinding Supported | Match device theo BDF/config | Return EFI_UNSUPPORTED sai |
| DriverBinding Start | Map BAR và init device | Start fail theo BDF |
| Controller handle | Handle đại diện function | dh/devtree debug |
| Child handle | Bus driver có thể tạo child | Device hierarchy |
Debug Diary: đọc nhầm BDF
Triệu chứng:
Driver log đọc Vendor ID đúng
Nhưng không phải device mình muốn
Checklist đọc nhầm BDF
Debug Diary: device hôm qua là 02:00.0, hôm nay là 04:00.0
Triệu chứng:
Cùng một card
BDF thay đổi sau khi đổi BIOS setting hoặc cắm thêm card
Checklist BDF thay đổi
Debug Diary: function phụ không xuất hiện
Triệu chứng:
02:00.0 thấy
02:00.1 không thấy
Checklist function phụ mất
Debug Diary: device sau bridge không có BDF
Triệu chứng:
Root port có ở 00:1C.0
Endpoint phía sau không có BDF
Checklist endpoint sau bridge không có BDF
Debug Diary: OS BDF khác UEFI BDF
Triệu chứng:
UEFI Shell thấy device 02:00.0
Linux/Windows thấy device 03:00.0
Checklist OS BDF khác UEFI
Anti-pattern khi dùng BDF
| Anti-pattern | Vì sao sai | Cách sửa |
|---|---|---|
| Hardcode 02:00.0 | Bus number có thể đổi | Match bằng device path/vendor/subsystem/policy |
| Bỏ qua segment | Multi-domain system đọc nhầm device | Log domain đầy đủ |
| Chỉ scan function 0 | Mất multi-function device | Check multi-function bit |
| Không check Vendor ID | Đọc BDF không tồn tại | Vendor ID != 0xFFFF |
| Nhầm bridge BDF với endpoint BDF | Debug sai config | Check Header Type/Class Code |
| So OS và UEFI BDF tuyệt đối | OS có thể renumber | So topology và device path |
| Không log BDF trong driver | Debug controller khó | Log Segment:Bus:Device.Function |
| Dùng BDF làm định danh license/security | Không ổn định | Dùng hardware identity phù hợp hơn |
Instrumentation nên có
| Vị trí | Nên log | Mục tiêu |
|---|---|---|
| PCI scan | Segment:Bus:Device.Function | Biết scan ở đâu |
| Config read | Vendor ID, Device ID | Biết device tồn tại |
| Header | Header Type, Class Code | Biết endpoint/bridge/multifunction |
| Bridge | Primary/Secondary/Subordinate | Debug downstream bus |
| BAR | BAR type/size/base | Debug resource |
| PciIo | GetLocation result | Driver bind đúng controller |
| Driver Supported | BDF + match reason | Debug EFI_UNSUPPORTED |
| Driver Start | BDF + init status | Debug start fail |
| OS compare | UEFI BDF vs OS BDF | Debug handoff/renumber |
| Good/bad diff | BDF topology diff | Regression |
BDF debug playbook
BDF debug playbook
Security checklist
Security checklist khi dùng BDF
Khi đọc log BDF nên tìm gì?
| Cần hiểu | Tìm trong log | Câu hỏi |
|---|---|---|
| Segment | 0000 hoặc segment khác | Có nhiều domain không? |
| Bus | 02 trong 02:00.0 | Bus này đến từ bridge nào? |
| Device | 00 trong 02:00.0 | Có đúng slot/device không? |
| Function | 0 trong 02:00.0 | Có function phụ không? |
| Vendor ID | Không phải 0xFFFF | Function có tồn tại không? |
| Class Code | Bridge/endpoint/class | Debug đúng loại device không? |
| Header Type | Multi-function bit | Có cần scan function 1-7 không? |
| Bridge bus registers | Primary/Secondary/Subordinate | Downstream bus hợp lệ không? |
| Device Path | Pci() nodes | Topology có khớp không? |
| OS compare | OS BDF | OS có renumber không? |
Câu hỏi tự kiểm tra
Tự kiểm tra sau khi đọc note này
Blog seeds
- BDF trong PCIe là gì?
- Bus Device Function giải thích cho firmware engineer
- Vì sao PCIe device đổi từ 02:00.0 sang 04:00.0?
- Vendor ID 0xFFFF khi đọc BDF nghĩa là gì?
- Multi-function PCI device và lỗi chỉ scan function 0
Bài liên quan
- PCI/PCIe Architecture Overview
- Vendor ID và Device ID là gì?
- Class Code trong PCI là gì?
- PCI Configuration Space là gì?
- BAR trong PCIe là gì?
- PCI Root Bridge là gì?
- PCI Bus Driver là gì?
- PCI I/O Protocol là gì?
- Bridge Window trong PCIe là gì?
- Device Path Node là gì?
Nguồn tham khảo public
- PCI-SIG Specifications
- UEFI Specification
- UEFI Platform Initialization Specification
- Tianocore EDK II
- EDK II Driver Writer’s Guide
Bài viết này hữu ích với bạn?
Bạn có thể chia sẻ cho người đang học firmware, BIOS/UEFI, embedded systems hoặc ủng hộ tác giả.
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.
PCI/PCIe Architecture Overview
Giải thích PCI/PCIe Architecture cho firmware engineer: bus/device/function, config space, BAR, bridge, root complex, enumeration và debug thiết bị mất.
BAR trong PCIe là gì?
Giải thích BAR trong PCIe: Base Address Register, MMIO/I/O BAR, 32-bit/64-bit BAR, prefetchable, sizing, resource allocation và debug MMIO fail.
Class Code trong PCI là gì?
Giải thích PCI Class Code: Base Class, Subclass, Prog IF, generic driver matching, storage/network/bridge class và debug driver bind sai.
Biến note thành bài viết hoàn chỉnh
Notes là nơi ghi nhanh khái niệm.