# 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

Last modified: 2024年7月22日

Author

Comments

Write a Reply or Comment

Your email address will not be published.