Writing an OS Kernel from Scratch – Part 34: PCIe Basics and Driver Framework — The Highway of Modern Hardware
“The e1000 driver got us online, but modern NICs have long upgraded to PCIe! Today, we dive into the PCIe world, implementing configuration space access, MSI interrupts, and device enumeration!”
In the previous post, we implemented the e1000 NIC driver, but the code only used traditional PCI configuration mechanism (CF8/CFC ports). Modern hardware (including QEMU-emulated e1000) actually runs on the PCI Express (PCIe) bus.
PCIe isn’t just “faster PCI” — it’s a completely new high-speed serial interconnect architecture!
PCI vs PCIe: Architectural Revolution
Traditional PCI (parallel bus):
- Shared bus: all devices contend for the same bandwidth
- 33/66 MHz clock: max 133 MB/s bandwidth
- Shared interrupts: IRQ lines shared across devices
- Configuration mechanism: accessed via 0xCF8/0xCFC ports
PCIe (serial point-to-point):
- Point-to-point connection: each device has dedicated lanes
- High bandwidth: x1 lane = 250 MB/s (Gen1), x16 = 4 GB/s
- Message interrupts: MSI/MSI-X replace traditional IRQ
- Extended configuration space: 256B → 4KB
| Feature | PCI | PCIe |
|---|---|---|
| Topology | Shared bus | Tree (Root Complex + Switches) |
| Config space | 256 bytes | 4KB (extended Capability) |
| Interrupts | 4 IRQ lines | MSI/MSI-X (memory write interrupts) |
| Hotplug | Not supported | Native support |
PCIe is backward compatible with PCI configuration space’s first 256 bytes!
Comments