# Writing an OS Kernel from Scratch – Part 33: e1000 NIC Driver — Connect Your OS to the Network World!
“An operating system without a network is just an information island. Today, we implement the Intel e1000 NIC driver, letting MyOS ping the outside world!”
In previous chapters, we built a complete desktop system: ✅ Window Manager ✅ LVGL GUI ✅ File System
But all operations are confined to the local machine — unable to access the internet, unable to communicate with other machines.
A real operating system must support networking! And the Intel 8254x series (e1000) is the classic NIC perfectly emulated by QEMU, also the best starting point for learning network drivers.
Today, we will: ✅ Parse the e1000 hardware architecture ✅ Implement MMIO register access ✅ Configure receive/transmit descriptors ✅ Handle NIC interrupts ✅ Send the first ICMP Ping packet
Give your OS true networking capability!
🌐 1. e1000 Hardware Basics
Why choose e1000?
Native QEMU support: -netdev user,id=n1 -device e1000,netdev=n1
Complete documentation: Intel official “8254x Software Developer’s Manual”
Classic architecture: DMA descriptors + interrupt-driven
e1000 Key Components:
| Component | Role |
|---|---|
| MMIO Registers | Control the NIC (base address from PCI config space) |
| Receive Descriptor Ring | NIC stores received frames |
| Transmit Descriptor Ring | CPU submits frames to send |
| Interrupt System | Notifies CPU of frame reception/transmission completion |
💡 e1000 uses DMA to directly read/write physical memory, no CPU data copying required!
🔌 2. PCI Device Probing
1. Scan PCI bus
e1000 PCI Vendor ID = 0x8086 (Intel), Device ID = 0x100E (QEMU emulation)
2. Get BAR (Base Address Register)
🔑 MMIO registers are accessed via memory mapping, no inb/outb needed!
📡 3. e1000 Register Operations
1. Register definitions
2. Read/Write macros
📦 4. Receive/Transmit Descriptors
1. Descriptor structure
2. Initialize descriptor ring
⚡ 5. Interrupt Handling
1. Enable interrupts
2. Interrupt handler
📤 6. Sending the First Ping Packet
1. Build ICMP Echo Request
2. QEMU test command
🧪 7. Test: Receiving Ping Reply
1. Process received frames
2. Run results
✅ e1000 driver successfully sent and received network packets!
⚠️ 8. Key Cautions
1. Physical address vs virtual address: buffer_addr in descriptors must be a physical address, converted via virt_to_phys()
2. Cache coherency: x86 typically doesn’t need explicit cache flush (WC memory type), but ensure descriptor updates are visible to the device
3. Descriptor ring boundary: head/tail pointers need modulo arithmetic, avoid filling the entire ring (leave some room)
#OS #KernelDevelopment #e1000 #NICDriver #Networking #DMA #PCI #WritingFromScratch
Comments