Ch 4: BAR & MMIO — Device 자원의 호스트 주소 매핑
#한 줄 요약
“BAR은 device가 host address space에 자기 자원을 광고하는 register입니다.” — Type 0 header에 6개 BAR 슬롯이 있고, Memory (32/64-bit, prefetchable 여부)·I/O의 4 종류. Size는 BAR에 all-1s 쓰고 읽어 mask로 결정. ReBAR는 64 GB BAR까지 협상 가능. SR-IOV VF BAR는 stride로 여러 VF를 매핑.
Ch 3 Configuration Space에서 BAR 슬롯이 0x10~0x24 6개임을 봤습니다. 이 장은 BAR의 동작 원리·size negotiation·ReBAR·VF BAR을 본격적으로 분해합니다.
#BAR — 4 종류
각 BAR는 Bit 0~2가 type 표시:
| Type | bit 0 | bit 1~2 | 추가 비트 | 사용 |
|---|---|---|---|---|
| Memory BAR 32-bit | 0 | 00 | Prefetchable (bit 3) | MMIO 32-bit |
| Memory BAR 64-bit | 0 | 10 | Prefetchable (bit 3) | MMIO 64-bit, BAR 2개 슬롯 사용 |
| I/O BAR | 1 | — | reserved | Legacy I/O space |
| Reserved | 0 | 01·11 | — | — |
I/O BAR는 64 KB legacy I/O port. 현대 device는 거의 안 씀. 대부분 Memory BAR만 사용.
#BAR Size 결정 — Probing
OS·BIOS는 각 BAR의 size를 probing으로 알아냅니다:
| 단계 | 동작 |
|---|---|
| 1 | BAR에 원래 값 읽어 저장 |
| 2 | BAR에 all-1s (0xFFFFFFFF) write |
| 3 | BAR 다시 read |
| 4 | 읽은 값에서 type 비트 (0 |
| 5 | bitwise NOT + 1 → BAR size (power of 2) |
| 6 | 원래 값 복원 |
예: BAR에 all-1s 쓰고 읽었더니 0xFFF00000. mask out 후 NOT + 1 = 0x00100000 (1 MB). 즉 이 BAR이 1 MB 자원임.
device가 “내 BAR은 N byte”라고 광고하는 메커니즘. host가 그 size만큼 address range를 할당.
#64-bit BAR
64-bit Memory BAR는 2개 BAR 슬롯 사용:
| 슬롯 | 의미 |
|---|---|
| BAR N | 하위 32-bit + type 비트 |
| BAR N+1 | 상위 32-bit |
BAR0·BAR1가 하나의 64-bit BAR이면 BAR2·BAR3·BAR4·BAR5만 남은 4 슬롯. GPU·NPU 같은 대용량 device는 64-bit BAR 필수 — 4 GB 이상 자원은 32-bit BAR 표현 불가.
#Prefetchable
*Prefetchable bit (Memory BAR의 bit 3)*가 2가지 의미:
| 비트 | 의미 |
|---|---|
| 1 | RC가 speculative prefetch 가능. side-effect 없음 보장 |
| 0 | side-effect 있음 — register 매번 정확한 transaction 필요 |
GPU VRAM·RAM 영역은 prefetchable. MMIO control register는 non-prefetchable. prefetchable만이 64-bit BAR 가능 — 32-bit 주소 공간 위로 매핑하려면 speculative 안전성 보장이 필요해서.
#Resource Enumeration — BIOS·OS 역할
| 단계 | 행위 |
|---|---|
| 1 | UEFI/BIOS가 enumeration — 모든 BAR size probe·tentative address 할당 |
| 2 | RC·switch의 MMIO window 설정 |
| 3 | Linux PCI subsystem이 재할당 시도 — pci_assign_resource |
| 4 | /sys/bus/pci/devices/.../resource에 최종 할당된 BAR 정보 노출 |
| 5 | Driver가 MMIO mapping — pci_iomap()·ioremap() |
Resource conflict가 흔한 문제. BAR size > 사용 가능 MMIO window면 device 비활성화. dmesg | grep "BAR.*can't"로 진단.
#Expansion ROM BAR
*offset 0x30 (Type 0)·0x38 (Type 1)*에 Option ROM BAR. device boot ROM 자원:
| 항목 | 의미 |
|---|---|
| bit 0 | ROM Enable (0이면 access 안 됨) |
| bit 1~10 | reserved |
| bit 11~31 | ROM base address |
NIC·GPU의 legacy BIOS Option ROM이 이 영역에 매핑. UEFI Secure Boot에서 서명 검증. VGA Option ROM이 PC boot의 진입점.
#Resizable BAR (ReBAR)
기존 BAR은 device가 광고한 size 그대로 사용. ReBAR는 runtime에 BAR size 협상 가능하게 함:
| 항목 | 의미 |
|---|---|
| Capability ID | 0x0023 (Extended Cap) |
| Sizes 지원 | 1 MB ~ 8 TB (40-bit 표현) |
| 협상 | BIOS·driver가 device가 광고한 지원 size 중 선택 |
GPU에 ReBAR enable하면 전체 VRAM (예: 24 GB) 을 BAR로 매핑. 이전엔 256 MB BAR만 매핑되어 partial copy. ReBAR로 zero-copy direct mapping 가능 — AMD SAM (Smart Access Memory)·NVIDIA Resizable BAR이 이 기능.
BIOS에서 ReBAR 활성화 + UEFI mode + 64-bit OS가 필수 조건.
#SR-IOV VF BAR
*SR-IOV (ID 0x0010)*는 *Physical Function (PF)*이 *여러 Virtual Function (VF)*를 광고하는 메커니즘. VF BAR는 별도 layout:
| 필드 | 의미 |
|---|---|
| VF BAR0~5 | 각 VF가 가질 BAR 정의 (template) |
| VF Stride | 한 VF BAR이 다음 VF로 얼마나 떨어진 offset |
| NumVFs | 활성 VF 수 (PF가 런타임에 설정) |
| First VF Offset | VF 번호 시작 offset |
N개 VF 활성화하면 VF BAR N개가 stride로 매핑. 예: VF BAR0 = 4 KB, stride = 4 KB, NumVFs = 8 → 32 KB MMIO range가 8개 VF의 BAR로 mapping.
Driver는 PF + VF 별도. Mellanox NIC·Intel 100 GbE 등이 SR-IOV 채택.
#BAR Mapping — Linux 측
/sys/bus/pci/devices/<BDF>/resource 파일의 각 줄이 한 BAR:
| 컬럼 | 의미 |
|---|---|
| start | BAR base physical address |
| end | last physical address |
| flags | type·prefetchable 등 |
pci_iomap(pdev, bar_num, max_size)이 driver가 BAR에 ioremap 적용. Returns virtual address — kernel space에서 readl/writel로 access.
// Driver 예ctrl_base = pci_iomap(pdev, 0, 4096);writel(0x00000001, ctrl_base + REG_ENABLE);#자주 하는 실수
#”BAR Size = device 메모리 크기”
BAR Size는 device가 광고한 자원 크기이지 실제 사용 용량과 다를 수 있음. 일부 device는 BAR 영역의 일부만 valid. driver가 layout 명확히 알고 access.
#”Memory BAR면 prefetchable”
Control register 영역은 non-prefetchable. RAM/VRAM 영역은 prefetchable. 모든 Memory BAR가 prefetchable 아님. RC의 deeper power state 진입에 영향.
#”ReBAR이 자동”
BIOS·UEFI 설정·OS driver·UEFI mode + GOP·64-bit OS 모두 필요. Windows·Linux 일부 driver는 ReBAR 명시 활성화 안 하면 사용 안 함. NVIDIA·AMD는 Resizable BAR 설정 옵션.
#”VF BAR이 단독 BAR”
VF BAR은 PF의 SR-IOV Cap에 template. NumVFs 설정 안 하면 매핑 안 됨. VF는 별도 BDF·별도 driver지만 BAR은 stride로 PF가 통제.
#”BAR 6개면 충분”
64-bit BAR은 2 슬롯 사용. 4 GB 이상 자원이 3개면 BAR 6개 다 사용. 복잡 device는 내부 mailbox·doorbell 영역 분리로 BAR 다수 사용.
#정리
- BAR은 device가 host address space에 자원 광고하는 register. Type 0 header에 6 슬롯.
- 4 종류: Memory 32-bit·Memory 64-bit·I/O·reserved. I/O는 현대 거의 unused.
- Size는 all-1s 쓰고 read해서 mask로 결정.
- 64-bit BAR은 2 슬롯 사용. prefetchable bit가 speculative 안전성 보장.
- Resource enumeration은 BIOS → Linux PCI subsystem.
/sys/.../resource로 확인. - Expansion ROM BAR에 device boot ROM (Option ROM·UEFI GOP).
- ReBAR가 runtime BAR size 협상 — GPU 전체 VRAM 매핑 (AMD SAM, NVIDIA RBAR).
- SR-IOV VF BAR은 stride로 다수 VF에 매핑.
#다음 편
Ch 5: Interrupts — INTx·MSI·MSI-X에서 PCIe 인터럽트 전송 메커니즘 3가지와 per-vector masking·APIC redirection을 본격적으로 분해합니다.
#관련 항목
- Ch 3: Configuration Space
- Ch 10: Linux PCI Basics — pci_iomap·driver matching
- Ch 12: Virtualization I — SR-IOV·VFIO
#시리즈 자료 출처 안내
본 글의 1차 자료·정책은 Ch 1 footer 참고.
PCIe Deep Dive · 4 of 19
- 1Ch 1: PCIe Fundamentals — 계층 구조와 토폴로지
- 2Ch 2: TLP — Transaction Layer Packet
- 3Ch 3: Configuration Space — 4 KB ECAM·Capability Linked List
- 4Ch 4: BAR & MMIO — Device 자원의 호스트 주소 매핑
- 5Ch 5: Interrupts — INTx·MSI·MSI-X·Interrupt Remapping
- 6Ch 6: Power Management — D-state·L-state·ASPM
- 7Ch 7: Error Handling — Correctable·Uncorrectable·AER·DPC
- 8Ch 8: Data Link Layer — DLLP·ACK/NAK·Flow Control·FLIT Mode
- 9Ch 9: Physical Layer — LTSSM·Equalization·SerDes
- 10Ch 10: Linux PCI Basics — Enumeration·Driver Model·sysfs
- 11Ch 11: DMA·IOMMU — Coherent·Streaming·ATS·PRI·PASID·IOMMUFD
- 12Ch 12: Virtualization I — Pass-through·SR-IOV·VFIO·DPDK·SPDK
- 13Ch 13: Virtualization II — vIOMMU·Scalable IOV·VirtIO·IDE·TDISP
- 14Ch 14: Linux Operations — Hot-plug·AER Recovery·DPC·ARI
- 15Ch 15: Tools — lspci·setpci·pcimem·protocol analyzer
- 16Ch 16: Troubleshooting — 실무 시나리오북
- 17Ch 17: Performance — Bandwidth·Latency·Tuning
- 18Ch 18: Register Maps — Config Space·Capability 비트 reference
- 19Ch 19: 고급 기능 — Lane Margining·10-bit Tag·TPH·ACS·L0p
관련 글
Ch 12: Virtualization I — Pass-through·SR-IOV·VFIO·DPDK·SPDK
PCIe hardware virtualization — SR-IOV PF/VF·VFIO container/group/device·DPDK·SPDK·ACS·FLR.
Ch 19: 고급 기능 — Lane Margining·10-bit Tag·TPH·ACS·L0p
코어 동작 너머의 PCIe spec 기능들 — Lane Margining(신호 마진 측정)·10-bit Tag(outstanding 확장)·TPH(캐시 주입 힌트)·ACS(격리)·L0p(부분폭 저전력)을 실무 관점에서 정리합니다.
Ch 18: Register Maps — Config Space·Capability 비트 reference
PCIe register reference — Type 0/1 header·PCIe Cap·AER·MSI·MSI-X·SR-IOV·ACS·LTR의 주요 비트 layout.
이 글을 참조하는 글 (5)
- Ch 12: Virtualization I — Pass-through·SR-IOV·VFIO·DPDK·SPDK— PCIe Deep Dive
- Ch 11: DMA·IOMMU — Coherent·Streaming·ATS·PRI·PASID·IOMMUFD— PCIe Deep Dive
- Ch 10: Linux PCI Basics — Enumeration·Driver Model·sysfs— PCIe Deep Dive
- Ch 5: Interrupts — INTx·MSI·MSI-X·Interrupt Remapping— PCIe Deep Dive
- Ch 3: Configuration Space — 4 KB ECAM·Capability Linked List— PCIe Deep Dive