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.

Cập nhật 16 phút đọc
PCI cover

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

01 Root

Start from root bridge

Firmware biết segment và bus range của root bridge.

02 Scan

Scan bus/device/function

Firmware thử đọc Vendor ID ở từng BDF.

03 Found

If Vendor ID valid

Device/function tồn tại và configuration space đọc được.

04 Bridge

If bridge found

Firmware gán secondary/subordinate bus và scan bus phía sau.

05 Resource

Assign BAR resources

BDF được gán MMIO/I/O resources phù hợp.

06 Handle

Create UEFI handle

Firmware install EFI_PCI_IO_PROTOCOL cho function đó.

07 Driver

Driver binds

DriverBinding Supported/Start dùng PciIo để match device.

Firmware dùng BDF để scan configuration space và tạo controller handle.

Bus, Device, Function là gì?

Ba phần của BDF
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
Segment/Domain trong PCI
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.

BDF dùng để đọc config space
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ỉ đó.

Vendor ID 0xFFFF khi đọc theo BDF
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.

Multi-function device
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
Bridge bus number ảnh hưởng BDF
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?

Khi nào BDF thay đổi?
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.

BDF vs UEFI Device Path
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ể.

BDF trong EFI_PCI_IO_PROTOCOL debug
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 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ó

Instrumentation cho BDF debug
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ì?

BDF log reading checklist
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

Nguồn tham khảo public

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ả.

Góp ý

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.

Biến note thành bài viết hoàn chỉnh

Notes là nơi ghi nhanh khái niệm.