浏览代码

完成e1000e驱动 (#393)

* 测试RESET

* 测试RESET

* 基于轮询的实现

* 规范化部分unsafe的使用

* 完成中断处理函数,同时去除了不必要的内存拷贝行为,准备编写napi机制

* 实现现有协议栈下的部分napi机制;修复了内存泄漏的问题;添加了一部分代码注释

* 去除部分无用代码

* 去除一些无用代码

* 适配新的驱动模型

* 完成msi中断测试

* 去除一些无用代码

* 格式化代码

* 增加了一些注释,提高代码可读性

* 去除无关文件

* 优化了读取mac地址的方式,提高可读性
Wu Mianzhi 1 年之前
父节点
当前提交
77799ccaac

+ 3 - 3
kernel/src/driver/interrupt/apic/apic.c

@@ -13,7 +13,7 @@
 #pragma GCC push_options
 #pragma GCC optimize("O0")
 // 导出定义在irq.c中的中段门表
-extern void (*interrupt_table[25])(void);
+extern void (*interrupt_table[26])(void);
 extern uint32_t rs_current_pcb_preempt_count();
 extern uint32_t rs_current_pcb_pid();
 extern uint32_t rs_current_pcb_flags();
@@ -362,7 +362,7 @@ int apic_init()
     cli();
     kinfo("Initializing APIC...");
     // 初始化中断门, 中断使用rsp0防止在软中断时发生嵌套,然后处理器重新加载导致数据被抹掉
-    for (int i = 32; i <= 56; ++i)
+    for (int i = 32; i <= 57; ++i)
         set_intr_gate(i, 0, interrupt_table[i - 32]);
 
     // 设置local apic中断门
@@ -416,7 +416,7 @@ void do_IRQ(struct pt_regs *rsp, ul number)
     {
         // ==========外部中断控制器========
         irq_desc_t *irq = &interrupt_desc[number - 32];
-
+        
         // 执行中断上半部处理程序
         if (irq != NULL && irq->handler != NULL)
             irq->handler(number, irq->parameter, rsp);

+ 63 - 0
kernel/src/driver/net/dma.rs

@@ -0,0 +1,63 @@
+use crate::arch::mm::kernel_page_flags;
+
+use crate::arch::MMArch;
+
+use crate::mm::kernel_mapper::KernelMapper;
+use crate::mm::page::PageFlags;
+use crate::mm::{
+    allocator::page_frame::{
+        allocate_page_frames, deallocate_page_frames, PageFrameCount, PhysPageFrame,
+    },
+    MemoryManagementArch, PhysAddr, VirtAddr,
+};
+use core::ptr::NonNull;
+const PAGE_SIZE: usize = 4096;
+/// @brief 申请用于DMA的内存页
+/// @param pages 页数(4k一页)
+/// @return PhysAddr 获得的内存页的初始物理地址
+pub fn dma_alloc(pages: usize) -> (usize, NonNull<u8>) {
+    let page_num = PageFrameCount::new(
+        ((pages * PAGE_SIZE + MMArch::PAGE_SIZE - 1) / MMArch::PAGE_SIZE).next_power_of_two(),
+    );
+    unsafe {
+        let (paddr, count) = allocate_page_frames(page_num).expect("e1000e: alloc page failed");
+        let virt = MMArch::phys_2_virt(paddr).unwrap();
+        // 清空这块区域,防止出现脏数据
+        core::ptr::write_bytes(virt.data() as *mut u8, 0, count.data() * MMArch::PAGE_SIZE);
+
+        let dma_flags: PageFlags<MMArch> = PageFlags::mmio_flags();
+
+        let mut kernel_mapper = KernelMapper::lock();
+        let kernel_mapper = kernel_mapper.as_mut().unwrap();
+        let flusher = kernel_mapper
+            .remap(virt, dma_flags)
+            .expect("e1000e: remap failed");
+        flusher.flush();
+        return (
+            paddr.data(),
+            NonNull::new(MMArch::phys_2_virt(paddr).unwrap().data() as _).unwrap(),
+        );
+    }
+}
+/// @brief 释放用于DMA的内存页
+/// @param paddr 起始物理地址 pages 页数(4k一页)
+/// @return i32 0表示成功
+pub unsafe fn dma_dealloc(paddr: usize, vaddr: NonNull<u8>, pages: usize) -> i32 {
+    let page_count = PageFrameCount::new(
+        ((pages * PAGE_SIZE + MMArch::PAGE_SIZE - 1) / MMArch::PAGE_SIZE).next_power_of_two(),
+    );
+
+    // 恢复页面属性
+    let vaddr = VirtAddr::new(vaddr.as_ptr() as *mut u8 as usize);
+    let mut kernel_mapper = KernelMapper::lock();
+    let kernel_mapper = kernel_mapper.as_mut().unwrap();
+    let flusher = kernel_mapper
+        .remap(vaddr, kernel_page_flags(vaddr))
+        .expect("e1000e: remap failed");
+    flusher.flush();
+
+    unsafe {
+        deallocate_page_frames(PhysPageFrame::new(PhysAddr::new(paddr)), page_count);
+    }
+    return 0;
+}

+ 794 - 0
kernel/src/driver/net/e1000e/e1000e.rs

@@ -0,0 +1,794 @@
+// 参考手册: PCIe* GbE Controllers Open Source Software Developer’s Manual
+// Refernce: PCIe* GbE Controllers Open Source Software Developer’s Manual
+
+use alloc::vec::Vec;
+use core::intrinsics::unlikely;
+use core::mem::size_of;
+use core::ptr::NonNull;
+use core::slice::{from_raw_parts, from_raw_parts_mut};
+use core::sync::atomic::{compiler_fence, Ordering};
+
+use super::e1000e_driver::e1000e_driver_init;
+use crate::driver::net::dma::{dma_alloc, dma_dealloc};
+use crate::driver::pci::pci::{
+    get_pci_device_structure_mut, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError,
+    PCI_DEVICE_LINKEDLIST,
+};
+use crate::driver::pci::pci_irq::{IrqCommonMsg, IrqMsg, IrqSpecificMsg, PciInterrupt, IRQ};
+use crate::include::bindings::bindings::pt_regs;
+use crate::libs::volatile::{ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly};
+use crate::net::net_core::poll_ifaces_try_lock_onetime;
+use crate::{kdebug, kinfo};
+
+const PAGE_SIZE: usize = 4096;
+const NETWORK_CLASS: u8 = 0x2;
+const ETHERNET_SUBCLASS: u8 = 0x0;
+// e1000e系列网卡的device id列表,来源:https://admin.pci-ids.ucw.cz/read/PC/8086
+const E1000E_DEVICE_ID: [u16; 14] = [
+    0x10d3, // 8574L, qemu default
+    0x10cc, // 82567LM-2
+    0x10cd, // 82567LF-2
+    0x105f, // 82571EB
+    0x1060, // 82571EB
+    0x107f, // 82572EI
+    0x109a, // 82573L
+    0x10ea, // 82577LM
+    0x10eb, // 82577LC
+    0x10ef, // 82578DM
+    0x10f0, // 82578DC
+    0x1502, // 82579LM
+    0x1503, // 82579V
+    0x150c, // 82583V
+];
+
+// e1000e网卡与BAR有关的常量
+// BAR0空间大小(128KB)
+const E1000E_BAR_REG_SIZE: u32 = 128 * 1024;
+// BAR0空间对齐(64bit)
+const E1000E_BAR_REG_ALIGN: u8 = 64;
+// 单个寄存器大小(32bit, 4字节)
+const E1000E_REG_SIZE: u8 = 4;
+
+// TxBuffer和RxBuffer的大小(DMA页)
+const E1000E_DMA_PAGES: usize = 1;
+
+// 中断相关
+const E1000E_RECV_VECTOR: u16 = 57;
+
+// napi队列中暂时存储的buffer个数
+const E1000E_RECV_NAPI: usize = 1024;
+
+// 收/发包的描述符结构 pp.24 Table 3-1
+#[repr(C)]
+#[derive(Copy, Clone, Debug)]
+struct E1000ETransDesc {
+    addr: u64,
+    len: u16,
+    cso: u8,
+    cmd: u8,
+    status: u8,
+    css: u8,
+    special: u8,
+}
+// pp.54 Table 3-12
+#[repr(C)]
+#[derive(Copy, Clone, Debug)]
+struct E1000ERecvDesc {
+    addr: u64,
+    len: u16,
+    chksum: u16,
+    status: u16,
+    error: u8,
+    special: u8,
+}
+#[derive(Copy, Clone)]
+// Buffer的Copy只是指针操作,不涉及实际数据的复制,因此要小心使用,确保不同的buffer不会使用同一块内存
+pub struct E1000EBuffer {
+    buffer: NonNull<u8>,
+    paddr: usize,
+    // length字段为0则表示这个buffer是一个占位符,不指向实际内存
+    // the buffer is empty and no page is allocated if length field is set 0
+    length: usize,
+}
+
+impl E1000EBuffer {
+    pub fn new(length: usize) -> Self {
+        assert!(length <= PAGE_SIZE);
+        if unlikely(length == 0) {
+            // 在某些情况下,我们并不需要实际分配buffer,只需要提供一个占位符即可
+            // we dont need to allocate dma pages for buffer in some cases
+            E1000EBuffer {
+                buffer: NonNull::dangling(),
+                paddr: 0,
+                length: 0,
+            }
+        } else {
+            let (paddr, vaddr) = dma_alloc(E1000E_DMA_PAGES);
+            E1000EBuffer {
+                buffer: vaddr,
+                paddr,
+                length,
+            }
+        }
+    }
+
+    pub fn as_addr(&self) -> NonNull<u8> {
+        assert!(self.length != 0);
+        return self.buffer;
+    }
+
+    pub fn as_addr_u64(&self) -> u64 {
+        assert!(self.length != 0);
+        return self.buffer.as_ptr() as u64;
+    }
+
+    pub fn as_paddr(&self) -> usize {
+        assert!(self.length != 0);
+        return self.paddr;
+    }
+
+    pub fn as_slice(&self) -> &[u8] {
+        assert!(self.length != 0);
+        return unsafe { from_raw_parts(self.buffer.as_ptr(), self.length) };
+    }
+
+    pub fn as_mut_slice(&mut self) -> &mut [u8] {
+        assert!(self.length != 0);
+        return unsafe { from_raw_parts_mut(self.buffer.as_ptr(), self.length) };
+    }
+
+    pub fn set_length(&mut self, length: usize) {
+        self.length = length;
+    }
+
+    pub fn len(&self) -> usize {
+        return self.length;
+    }
+    // 释放buffer内部的dma_pages,需要小心使用
+    pub fn free_buffer(self) -> () {
+        if self.length != 0 {
+            unsafe { dma_dealloc(self.paddr, self.buffer, E1000E_DMA_PAGES) };
+        }
+    }
+}
+
+// 中断处理函数, 调用协议栈的poll函数,未来可能会用napi来替换这里
+// Interrupt handler
+unsafe extern "C" fn e1000e_irq_handler(irq_num: u64, irq_paramer: u64, regs: *mut pt_regs) {
+    poll_ifaces_try_lock_onetime().ok();
+}
+
+pub struct E1000EDevice {
+    // 设备寄存器
+    // device registers
+    general_regs: NonNull<GeneralRegs>,
+    interrupt_regs: NonNull<InterruptRegs>,
+    rctl_regs: NonNull<ReceiveCtrlRegs>,
+    receive_regs: NonNull<ReceiveRegs>,
+    tctl_regs: NonNull<TransmitCtrlRegs>,
+    transimit_regs: NonNull<TransimitRegs>,
+    pcie_regs: NonNull<PCIeRegs>,
+
+    // descriptor环形队列,在操作系统与设备之间共享
+    // descriptor rings are shared between os and device
+    recv_desc_ring: &'static mut [E1000ERecvDesc],
+    trans_desc_ring: &'static mut [E1000ETransDesc],
+    recv_ring_pa: usize,
+    trans_ring_pa: usize,
+
+    // 设备收/发包缓冲区数组
+    // buffers of receive/transmit packets
+    recv_buffers: Vec<E1000EBuffer>,
+    trans_buffers: Vec<E1000EBuffer>,
+    mac: [u8; 6],
+    first_trans: bool,
+    // napi队列,用于存放在中断关闭期间通过轮询收取的buffer
+    // the napi queue is designed to save buffer/packet when the interrupt is close
+    // NOTE: this feature is not completely implemented and not used in the current version
+    napi_buffers: Vec<E1000EBuffer>,
+    napi_buffer_head: usize,
+    napi_buffer_tail: usize,
+    napi_buffer_empty: bool,
+}
+
+impl E1000EDevice {
+    // 从PCI标准设备进行驱动初始化
+    // init the device for PCI standard device struct
+    pub fn new(device: &mut PciDeviceStructureGeneralDevice) -> Result<Self, E1000EPciError> {
+        // 从BAR0获取我们需要的寄存器
+        // Build registers sturcts from BAR0
+        device.bar_ioremap().unwrap()?;
+        device.enable_master();
+        let bar = device.bar().ok_or(E1000EPciError::BarGetFailed)?;
+        let bar0 = bar.get_bar(0)?;
+        let (address, size) = bar0
+            .memory_address_size()
+            .ok_or(E1000EPciError::UnexpectedBarType)?;
+        if address == 0 {
+            return Err(E1000EPciError::BarNotAllocated);
+        }
+        if size != E1000E_BAR_REG_SIZE {
+            return Err(E1000EPciError::UnexpectedBarSize);
+        }
+        let vaddress = bar0
+            .virtual_address()
+            .ok_or(E1000EPciError::BarGetVaddrFailed)?
+            .data() as u64;
+
+        // 初始化msi中断
+        // initialize msi interupt
+        let irq_vector = device.irq_vector_mut().unwrap();
+        irq_vector.push(E1000E_RECV_VECTOR);
+        device.irq_init(IRQ::PCI_IRQ_MSI).expect("IRQ Init Failed");
+        let msg = IrqMsg {
+            irq_common_message: IrqCommonMsg::init_from(
+                0,
+                "E1000E_RECV_IRQ",
+                0,
+                e1000e_irq_handler,
+                None,
+            ),
+            irq_specific_message: IrqSpecificMsg::msi_default(),
+        };
+        device.irq_install(msg)?;
+        device.irq_enable(true)?;
+
+        let general_regs: NonNull<GeneralRegs> =
+            get_register_ptr(vaddress, E1000E_GENERAL_REGS_OFFSET);
+        let interrupt_regs: NonNull<InterruptRegs> =
+            get_register_ptr(vaddress, E1000E_INTERRRUPT_REGS_OFFSET);
+        let rctl_regs: NonNull<ReceiveCtrlRegs> =
+            get_register_ptr(vaddress, E1000E_RECEIVE_CTRL_REG_OFFSET);
+        let receive_regs: NonNull<ReceiveRegs> =
+            get_register_ptr(vaddress, E1000E_RECEIVE_REGS_OFFSET);
+        let tctl_regs: NonNull<TransmitCtrlRegs> =
+            get_register_ptr(vaddress, E1000E_TRANSMIT_CTRL_REG_OFFSET);
+        let transimit_regs: NonNull<TransimitRegs> =
+            get_register_ptr(vaddress, E1000E_TRANSMIT_REGS_OFFSET);
+        let pcie_regs: NonNull<PCIeRegs> = get_register_ptr(vaddress, E1000E_PCIE_REGS_OFFSET);
+        let ra_regs: NonNull<ReceiveAddressRegs> =
+            get_register_ptr(vaddress, E1000E_RECEIVE_ADDRESS_REGS_OFFSET);
+        // 开始设备初始化 14.3
+        // Initialization Sequence
+        unsafe {
+            let mut ctrl = volread!(general_regs, ctrl);
+            // 关闭中断
+            // close the interrupt
+            volwrite!(interrupt_regs, imc, E1000E_IMC_CLEAR);
+            //SW RESET
+            volwrite!(general_regs, ctrl, ctrl | E1000E_CTRL_RST);
+            compiler_fence(Ordering::AcqRel);
+            // PHY RESET
+            ctrl = volread!(general_regs, ctrl);
+            volwrite!(general_regs, ctrl, ctrl | E1000E_CTRL_PHY_RST);
+            volwrite!(general_regs, ctrl, ctrl);
+            // 关闭中断
+            // close the interrupt
+            volwrite!(interrupt_regs, imc, E1000E_IMC_CLEAR);
+            let mut gcr = volread!(pcie_regs, gcr);
+            gcr = gcr | (1 << 22);
+            volwrite!(pcie_regs, gcr, gcr);
+            compiler_fence(Ordering::AcqRel);
+            // PHY Initialization 14.8.1
+            // MAC/PHY Link Setup 14.8.2
+            ctrl = volread!(general_regs, ctrl);
+            ctrl &= !(E1000E_CTRL_FRCSPD | E1000E_CTRL_FRCDPLX);
+            volwrite!(general_regs, ctrl, ctrl | E1000E_CTRL_SLU);
+        }
+        let status = unsafe { volread!(general_regs, status) };
+        kdebug!("Status: {status:#X}");
+
+        // 读取设备的mac地址
+        // Read mac address
+        let ral = unsafe { volread!(ra_regs, ral0) };
+        let rah = unsafe { volread!(ra_regs, rah0) };
+        let mac: [u8; 6] = [
+            ((ral >> 0) & 0xFF) as u8,
+            ((ral >> 8) & 0xFF) as u8,
+            ((ral >> 16) & 0xFF) as u8,
+            ((ral >> 24) & 0xFF) as u8,
+            ((rah >> 0) & 0xFF) as u8,
+            ((rah >> 8) & 0xFF) as u8,
+        ];
+        // 初始化receive和transimit descriptor环形队列
+        // initialize receive and transimit desciptor ring
+        let (recv_ring_pa, recv_ring_va) = dma_alloc(E1000E_DMA_PAGES);
+        let (trans_ring_pa, trans_ring_va) = dma_alloc(E1000E_DMA_PAGES);
+        let recv_ring_length = PAGE_SIZE / size_of::<E1000ERecvDesc>();
+        let trans_ring_length = PAGE_SIZE / size_of::<E1000ETransDesc>();
+
+        let recv_desc_ring = unsafe {
+            from_raw_parts_mut::<E1000ERecvDesc>(recv_ring_va.as_ptr().cast(), recv_ring_length)
+        };
+        let trans_desc_ring = unsafe {
+            from_raw_parts_mut::<E1000ETransDesc>(trans_ring_va.as_ptr().cast(), trans_ring_length)
+        };
+
+        // 初始化receive和transmit packet的缓冲区
+        // initialzie receive and transmit buffers
+        let mut recv_buffers: Vec<E1000EBuffer> = Vec::with_capacity(recv_ring_length);
+        let mut trans_buffers: Vec<E1000EBuffer> = Vec::with_capacity(trans_ring_length);
+
+        // 初始化缓冲区与descriptor,descriptor 中的addr字典应当指向buffer的物理地址
+        // Receive buffers of appropriate size should be allocated and pointers to these buffers should be stored in the descriptor ring.
+        for i in 0..recv_ring_length {
+            let buffer = E1000EBuffer::new(PAGE_SIZE);
+            recv_desc_ring[i].addr = buffer.as_paddr() as u64;
+            recv_desc_ring[i].status = 0;
+            recv_buffers.push(buffer);
+        }
+        // Same as receive buffers
+        for i in 0..trans_ring_length {
+            let buffer = E1000EBuffer::new(PAGE_SIZE);
+            trans_desc_ring[i].addr = buffer.as_paddr() as u64;
+            trans_desc_ring[i].status = 1;
+            trans_buffers.push(buffer);
+        }
+
+        // Receive Initialization 14.6
+        // Initialzie mutlicast table array to 0b
+        // 初始化MTA,遍历0x05200-0x053FC中每个寄存器,写入0b,一共128个寄存器
+        let mut mta_adress = vaddress + E1000E_MTA_REGS_START_OFFSET;
+        while mta_adress != vaddress + E1000E_MTA_REGS_END_OFFSET {
+            let mta: NonNull<MTARegs> = get_register_ptr(mta_adress, 0);
+            unsafe { volwrite!(mta, mta, 0) };
+            mta_adress = mta_adress + 4;
+        }
+        // 连续的寄存器读-写操作,放在同一个unsafe块中
+        unsafe {
+            // 设置descriptor环形队列的基地址
+            // Program the descriptor base address with the address of the region.
+            volwrite!(receive_regs, rdbal0, (recv_ring_pa) as u32);
+            volwrite!(receive_regs, rdbah0, (recv_ring_pa >> 32) as u32);
+            // 设置descriptor环形队列的长度
+            // Set the length register to the size of the descriptor ring.
+            volwrite!(receive_regs, rdlen0, PAGE_SIZE as u32);
+            // 设置队列的首尾指针
+            // Program the head and tail registers
+            volwrite!(receive_regs, rdh0, 0);
+            volwrite!(receive_regs, rdt0, (recv_ring_length - 1) as u32);
+            // 设置控制寄存器的相关功能 14.6.1
+            // Set the receive control register
+            volwrite!(
+                rctl_regs,
+                rctl,
+                E1000E_RCTL_EN
+                    | E1000E_RCTL_BAM
+                    | E1000E_RCTL_BSIZE_4K
+                    | E1000E_RCTL_BSEX
+                    | E1000E_RCTL_SECRC
+            );
+
+            // Transmit Initialization 14.7
+            // 开启发包descriptor的回写功能
+            // Program the TXDCTL register with the desired TX descriptor write-back policy
+            volwrite!(
+                transimit_regs,
+                txdctl,
+                E1000E_TXDCTL_WTHRESH | E1000E_TXDCTL_GRAN
+            );
+            // 设置descriptor环形队列的基地址,长度与首尾指针
+            // Program the descriptor base address with the address of the region
+            volwrite!(transimit_regs, tdbal0, trans_ring_pa as u32);
+            volwrite!(transimit_regs, tdbah0, (trans_ring_pa >> 32) as u32);
+            // Set the length register to the size of the descriptor ring.
+            volwrite!(transimit_regs, tdlen0, PAGE_SIZE as u32);
+            // Program the head and tail registerss
+            volwrite!(transimit_regs, tdh0, 0);
+            volwrite!(transimit_regs, tdt0, 0);
+            // Program the TIPG register
+            volwrite!(
+                tctl_regs,
+                tipg,
+                E1000E_TIPG_IPGT | E1000E_TIPG_IPGR1 | E1000E_TIPG_IPGR2
+            );
+            // Program the TCTL register.
+            volwrite!(
+                tctl_regs,
+                tctl,
+                E1000E_TCTL_EN | E1000E_TCTL_PSP | E1000E_TCTL_CT_VAL | E1000E_TCTL_COLD_VAL
+            );
+
+            let icr = volread!(interrupt_regs, icr);
+            volwrite!(interrupt_regs, icr, icr);
+            // 开启收包相关的中断
+            // Enable receive interrupts
+            let mut ims = volread!(interrupt_regs, ims);
+            ims = E1000E_IMS_LSC | E1000E_IMS_RXT0 | E1000E_IMS_RXDMT0 | E1000E_IMS_OTHER;
+            volwrite!(interrupt_regs, ims, ims);
+        }
+        return Ok(E1000EDevice {
+            general_regs,
+            interrupt_regs,
+            rctl_regs,
+            receive_regs,
+            tctl_regs,
+            transimit_regs,
+            pcie_regs,
+            recv_desc_ring,
+            trans_desc_ring,
+            recv_ring_pa,
+            trans_ring_pa,
+            recv_buffers,
+            trans_buffers,
+            mac,
+            first_trans: true,
+            napi_buffers: vec![E1000EBuffer::new(0); E1000E_RECV_NAPI],
+            napi_buffer_head: 0,
+            napi_buffer_tail: 0,
+            napi_buffer_empty: true,
+        });
+    }
+    pub fn e1000e_receive(&mut self) -> Option<E1000EBuffer> {
+        self.e1000e_intr();
+        let mut rdt = unsafe { volread!(self.receive_regs, rdt0) } as usize;
+        let index = (rdt + 1) % self.recv_desc_ring.len();
+        let desc = &mut self.recv_desc_ring[index];
+        if (desc.status & E1000E_RXD_STATUS_DD) == 0 {
+            return None;
+        }
+        let mut buffer = self.recv_buffers[index];
+        let new_buffer = E1000EBuffer::new(PAGE_SIZE);
+        self.recv_buffers[index] = new_buffer;
+        desc.addr = new_buffer.as_paddr() as u64;
+        buffer.set_length(desc.len as usize);
+        rdt = index;
+        unsafe { volwrite!(self.receive_regs, rdt0, rdt as u32) };
+        // kdebug!("e1000e: receive packet");
+        return Some(buffer);
+    }
+
+    pub fn e1000e_can_transmit(&self) -> bool {
+        let tdt = unsafe { volread!(self.transimit_regs, tdt0) } as usize;
+        let index = tdt % self.trans_desc_ring.len();
+        let desc = &self.trans_desc_ring[index];
+        if (desc.status & E1000E_TXD_STATUS_DD) == 0 {
+            return false;
+        }
+        true
+    }
+
+    pub fn e1000e_transmit(&mut self, packet: E1000EBuffer) {
+        let mut tdt = unsafe { volread!(self.transimit_regs, tdt0) } as usize;
+        let index = tdt % self.trans_desc_ring.len();
+        let desc = &mut self.trans_desc_ring[index];
+        let buffer = self.trans_buffers[index];
+        self.trans_buffers[index] = packet;
+        // recycle unused transmit buffer
+        buffer.free_buffer();
+        // Set the transmit descriptor
+        desc.addr = packet.as_paddr() as u64;
+        desc.len = packet.len() as u16;
+        desc.status = 0;
+        desc.cmd = E1000E_TXD_CMD_EOP | E1000E_TXD_CMD_RS | E1000E_TXD_CMD_IFCS;
+        tdt = (tdt + 1) % self.trans_desc_ring.len();
+        unsafe { volwrite!(self.transimit_regs, tdt0, tdt as u32) };
+        self.first_trans = false;
+    }
+    pub fn mac_address(&self) -> [u8; 6] {
+        return self.mac;
+    }
+    // 向ICR寄存器中的某一bit写入1b表示该中断已经被接收,同时会清空该位
+    // we need to clear ICR to tell e1000e we have read the interrupt
+    pub fn e1000e_intr(&mut self) {
+        let icr = unsafe { volread!(self.interrupt_regs, icr) };
+        // write 1b to any bit in ICR will clear the bit
+        unsafe { volwrite!(self.interrupt_regs, icr, icr) };
+    }
+
+    // 切换是否接受分组到达的中断
+    // change whether the receive timer interrupt is enabled
+    // Note: this method is not completely implemented and not used in the current version
+    pub fn e1000e_intr_set(&mut self, state: bool) {
+        let mut ims = unsafe { volread!(self.interrupt_regs, ims) };
+        match state {
+            true => ims = ims | E1000E_IMS_RXT0,
+            false => ims = ims & !E1000E_IMS_RXT0,
+        }
+        unsafe { volwrite!(self.interrupt_regs, ims, ims) };
+    }
+
+    // 实现了一部分napi机制的收包函数, 现在还没有投入使用
+    // This method is a partial implementation of napi (New API) techniques
+    // Note: this method is not completely implemented and not used in the current version
+    pub fn e1000e_receive2(&mut self) -> Option<E1000EBuffer> {
+        // 向设备表明我们已经接受到了之前的中断
+        // Tell e1000e we have received the interrupt
+        self.e1000e_intr();
+        // 如果napi队列不存在已经收到的分组...
+        // if napi queue is empty...
+        if self.napi_buffer_empty {
+            // 暂时关闭设备中断
+            // close interrupt
+            self.e1000e_intr_set(false);
+            loop {
+                if self.napi_buffer_tail == self.napi_buffer_head && self.napi_buffer_empty == false
+                {
+                    // napi缓冲队列已满,停止收包
+                    // napi queue is full, stop
+                    break;
+                }
+                match self.e1000e_receive() {
+                    Some(buffer) => {
+                        self.napi_buffers[self.napi_buffer_tail] = buffer;
+                        self.napi_buffer_tail = (self.napi_buffer_tail + 1) % E1000E_RECV_NAPI;
+                        self.napi_buffer_empty = false;
+                    }
+                    None => {
+                        // 设备队列中没有剩余的已到达的数据包
+                        // no packet remains in the device buffer
+                        break;
+                    }
+                };
+            }
+            // 重新打开设备中断
+            // open the interrupt
+            self.e1000e_intr_set(true);
+        }
+
+        let result = self.napi_buffers[self.napi_buffer_head];
+        match result.len() {
+            0 => {
+                // napi队列和网卡队列中都不存在数据包
+                // both napi queue and device buffer is empty, no packet will receive
+                return None;
+            }
+            _ => {
+                // 有剩余的已到达的数据包
+                // there is packet in napi queue
+                self.napi_buffer_head = (self.napi_buffer_head + 1) % E1000E_RECV_NAPI;
+                if self.napi_buffer_head == self.napi_buffer_tail {
+                    self.napi_buffer_empty = true;
+                }
+                return Some(result);
+            }
+        }
+    }
+}
+
+impl Drop for E1000EDevice {
+    fn drop(&mut self) {
+        // 释放已分配的所有dma页
+        // free all dma pages we have allocated
+        kdebug!("droping...");
+        let recv_ring_length = PAGE_SIZE / size_of::<E1000ERecvDesc>();
+        let trans_ring_length = PAGE_SIZE / size_of::<E1000ETransDesc>();
+        unsafe {
+            // 释放所有buffer中的dma页
+            // free all dma pages in buffers
+            for i in 0..recv_ring_length {
+                self.recv_buffers[i].free_buffer();
+            }
+            for i in 0..trans_ring_length {
+                self.trans_buffers[i].free_buffer();
+            }
+            // 释放descriptor ring
+            // free descriptor ring
+            dma_dealloc(
+                self.recv_ring_pa,
+                NonNull::new(self.recv_desc_ring).unwrap().cast(),
+                E1000E_DMA_PAGES,
+            );
+            dma_dealloc(
+                self.trans_ring_pa,
+                NonNull::new(self.trans_desc_ring).unwrap().cast(),
+                E1000E_DMA_PAGES,
+            );
+        }
+    }
+}
+
+#[no_mangle]
+pub extern "C" fn rs_e1000e_init() {
+    e1000e_init();
+}
+
+pub fn e1000e_init() -> () {
+    match e1000e_probe() {
+        Ok(code) => kinfo!("Successfully init e1000e device!"),
+        Err(error) => kinfo!("Error occurred!"),
+    }
+}
+
+pub fn e1000e_probe() -> Result<u64, E1000EPciError> {
+    let mut list = PCI_DEVICE_LINKEDLIST.write();
+    let result = get_pci_device_structure_mut(&mut list, NETWORK_CLASS, ETHERNET_SUBCLASS);
+    if result.is_empty() {
+        return Ok(0);
+    }
+    for device in result {
+        let standard_device = device.as_standard_device_mut().unwrap();
+        let header = &standard_device.common_header;
+        if header.vendor_id == 0x8086 {
+            // intel
+            if E1000E_DEVICE_ID.contains(&header.device_id) {
+                kdebug!(
+                    "Detected e1000e PCI device with device id {:#x}",
+                    header.device_id
+                );
+                let e1000e = E1000EDevice::new(standard_device)?;
+                e1000e_driver_init(e1000e);
+            }
+        }
+    }
+
+    return Ok(1);
+}
+
+// 用到的e1000e寄存器结构体
+// pp.275, Table 13-3
+// 设备通用寄存器
+struct GeneralRegs {
+    ctrl: Volatile<u32>,         //0x00000
+    ctrl_alias: Volatile<u32>,   //0x00004
+    status: ReadOnly<u32>,       //0x00008
+    status_align: ReadOnly<u32>, //0x0000c
+    eec: Volatile<u32>,          //0x00010
+    eerd: Volatile<u32>,         //0x00014
+    ctrl_ext: Volatile<u32>,     //0x00018
+    fla: Volatile<u32>,          //0x0001c
+    mdic: Volatile<u32>,         //0x00020
+}
+// 中断控制
+struct InterruptRegs {
+    icr: Volatile<u32>, //0x000c0 ICR寄存器应当为只读寄存器,但我们需要向其中写入来清除对应位
+    itr: Volatile<u32>, //0x000c4
+    ics: WriteOnly<u32>, //0x000c8
+    ics_align: ReadOnly<u32>, //0x000cc
+    ims: Volatile<u32>, //0x000d0
+    ims_align: ReadOnly<u32>, //0x000d4
+    imc: WriteOnly<u32>, //0x000d8
+}
+// 收包功能控制
+struct ReceiveCtrlRegs {
+    rctl: Volatile<u32>, //0x00100
+}
+// 发包功能控制
+struct TransmitCtrlRegs {
+    tctl: Volatile<u32>,     //0x00400
+    tctl_ext: Volatile<u32>, //0x00404
+    unused_1: ReadOnly<u32>, //0x00408
+    unused_2: ReadOnly<u32>, //0x0040c
+    tipg: Volatile<u32>,     //0x00410
+}
+// 收包功能相关
+struct ReceiveRegs {
+    rdbal0: Volatile<u32>,     //0x02800
+    rdbah0: Volatile<u32>,     //0x02804
+    rdlen0: Volatile<u32>,     //0x02808
+    rdl_align: ReadOnly<u32>,  //0x0280c
+    rdh0: Volatile<u32>,       //0x02810
+    rdh_align: ReadOnly<u32>,  //0x02814
+    rdt0: Volatile<u32>,       //0x02818
+    rdt_align: ReadOnly<u32>,  //0x281c
+    rdtr: Volatile<u32>,       //0x2820
+    rdtr_align: ReadOnly<u32>, //0x2824
+    rxdctl: Volatile<u32>,     //0x2828
+}
+// 发包功能相关
+struct TransimitRegs {
+    tdbal0: Volatile<u32>,      //0x03800
+    tdbah0: Volatile<u32>,      //0x03804
+    tdlen0: Volatile<u32>,      //0x03808
+    tdlen_algin: ReadOnly<u32>, //0x0380c
+    tdh0: Volatile<u32>,        //0x03810
+    tdh_align: ReadOnly<u32>,   //0x03814
+    tdt0: Volatile<u32>,        //0x03818
+    tdt_align: ReadOnly<u32>,   //0x0381c
+    tidv: Volatile<u32>,        //0x03820
+    tidv_align: ReadOnly<u32>,  //0x03824
+    txdctl: Volatile<u32>,      //0x03828
+    tadv: Volatile<u32>,        //0x0382c
+}
+// mac地址
+struct ReceiveAddressRegs {
+    ral0: Volatile<u32>, //0x05400
+    rah0: Volatile<u32>, //0x05404
+}
+// PCIe 通用控制
+struct PCIeRegs {
+    gcr: Volatile<u32>, //0x05b00
+}
+struct StatisticsRegs {}
+
+// 0x05200-0x053fc
+// 在Receive Initialization 中按照每次一个32bit寄存器的方式来遍历
+// Multicast Table Array Registers will be written per 32bit
+struct MTARegs {
+    mta: Volatile<u32>,
+}
+
+const E1000E_GENERAL_REGS_OFFSET: u64 = 0x00000;
+const E1000E_INTERRRUPT_REGS_OFFSET: u64 = 0x000c0;
+const E1000E_RECEIVE_CTRL_REG_OFFSET: u64 = 0x00100;
+const E1000E_RECEIVE_REGS_OFFSET: u64 = 0x02800;
+const E1000E_TRANSMIT_CTRL_REG_OFFSET: u64 = 0x00400;
+const E1000E_TRANSMIT_REGS_OFFSET: u64 = 0x03800;
+const E1000E_RECEIVE_ADDRESS_REGS_OFFSET: u64 = 0x05400;
+const E1000E_PCIE_REGS_OFFSET: u64 = 0x05b00;
+const E1000E_MTA_REGS_START_OFFSET: u64 = 0x05200;
+const E1000E_MTA_REGS_END_OFFSET: u64 = 0x053fc;
+// 寄存器的特定位
+//CTRL
+const E1000E_CTRL_SLU: u32 = 1 << 6;
+const E1000E_CTRL_FRCSPD: u32 = 1 << 11;
+const E1000E_CTRL_FRCDPLX: u32 = 1 << 12;
+const E1000E_CTRL_RST: u32 = 1 << 26;
+const E1000E_CTRL_RFCE: u32 = 1 << 27;
+const E1000E_CTRL_TFCE: u32 = 1 << 28;
+const E1000E_CTRL_PHY_RST: u32 = 1 << 31;
+
+// IMS
+const E1000E_IMS_LSC: u32 = 1 << 2;
+const E1000E_IMS_RXDMT0: u32 = 1 << 4;
+const E1000E_IMS_RXO: u32 = 1 << 6;
+const E1000E_IMS_RXT0: u32 = 1 << 7;
+const E1000E_IMS_RXQ0: u32 = 1 << 20;
+const E1000E_IMS_OTHER: u32 = 1 << 24; // qemu use this bit to set msi-x interrupt
+
+// IMC
+const E1000E_IMC_CLEAR: u32 = 0xffffffff;
+
+// RCTL
+const E1000E_RCTL_EN: u32 = 1 << 1;
+const E1000E_RCTL_BAM: u32 = 1 << 15;
+const E1000E_RCTL_BSIZE_4K: u32 = 3 << 16;
+const E1000E_RCTL_BSEX: u32 = 1 << 25;
+const E1000E_RCTL_SECRC: u32 = 1 << 26;
+
+// TCTL
+const E1000E_TCTL_EN: u32 = 1 << 1;
+const E1000E_TCTL_PSP: u32 = 1 << 3;
+const E1000E_TCTL_CT_VAL: u32 = 0x0f << 4; // suggested 16d collision, 手册建议值:16d
+const E1000E_TCTL_COLD_VAL: u32 = 0x03f << 12; // suggested 64 byte time for Full-Duplex, 手册建议值:64
+                                               // TXDCTL
+const E1000E_TXDCTL_WTHRESH: u32 = 1 << 16;
+const E1000E_TXDCTL_GRAN: u32 = 1 << 24;
+// TIPG
+const E1000E_TIPG_IPGT: u32 = 8;
+const E1000E_TIPG_IPGR1: u32 = 2 << 10;
+const E1000E_TIPG_IPGR2: u32 = 10 << 20;
+
+// RxDescriptorStatus
+const E1000E_RXD_STATUS_DD: u16 = 1 << 0;
+
+// TxDescriptorStatus
+const E1000E_TXD_STATUS_DD: u8 = 1 << 0;
+const E1000E_TXD_CMD_EOP: u8 = 1 << 0;
+const E1000E_TXD_CMD_IFCS: u8 = 1 << 1;
+const E1000E_TXD_CMD_RS: u8 = 1 << 3;
+
+// E1000E驱动初始化过程中可能的错误
+pub enum E1000EPciError {
+    // 获取到错误类型的BAR(IO BAR)
+    // An IO BAR was provided rather than a memory BAR.
+    UnexpectedBarType,
+    // 获取的BAR没有被分配到某个地址(address == 0)
+    // A BAR which we need was not allocated an address(address == 0).
+    BarNotAllocated,
+    //获取虚拟地址失败
+    BarGetVaddrFailed,
+    // 没有对应的BAR或者获取BAR失败
+    BarGetFailed,
+    // BAR的大小与预期不符(128KB)
+    // Size of BAR is not 128KB
+    UnexpectedBarSize,
+    Pci(PciError),
+}
+
+/// PCI error到VirtioPciError的转换,层层上报
+impl From<PciError> for E1000EPciError {
+    fn from(error: PciError) -> Self {
+        Self::Pci(error)
+    }
+}
+
+/**
+ * @brief 获取基地址的某个偏移量的指针,用于在mmio bar中构造寄存器结构体
+ * @brief used for build register struct in mmio bar
+ * @param vaddr: base address (in virtual memory)
+ * @param offset: offset
+ */
+fn get_register_ptr<T>(vaddr: u64, offset: u64) -> NonNull<T> {
+    NonNull::new((vaddr + offset) as *mut T).unwrap()
+}

+ 354 - 0
kernel/src/driver/net/e1000e/e1000e_driver.rs

@@ -0,0 +1,354 @@
+//这个文件的绝大部分内容是copy virtio_net.rs的,考虑到所有的驱动都要用操作系统提供的协议栈,我觉得可以把这些内容抽象出来
+
+use crate::{
+    driver::{
+        base::{
+            device::{
+                bus::Bus,
+                driver::{Driver, DriverError},
+                Device, DevicePrivateData, IdTable,
+            },
+            kobject::{KObjType, KObject, KObjectState},
+        },
+        net::NetDriver,
+    },
+    kdebug, kinfo,
+    libs::spinlock::SpinLock,
+    net::{generate_iface_id, NET_DRIVERS},
+    syscall::SystemError,
+    time::Instant,
+};
+use alloc::{string::String, sync::Arc};
+use core::{
+    cell::UnsafeCell,
+    fmt::Debug,
+    ops::{Deref, DerefMut},
+};
+use smoltcp::{phy, wire};
+
+use super::e1000e::{E1000EBuffer, E1000EDevice};
+
+pub struct E1000ERxToken(E1000EBuffer);
+pub struct E1000ETxToken {
+    driver: E1000EDriver,
+}
+pub struct E1000EDriver {
+    pub inner: Arc<SpinLock<E1000EDevice>>,
+}
+
+/// @brief 网卡驱动的包裹器,这是为了获取网卡驱动的可变引用而设计的。
+/// 参阅virtio_net.rs
+struct E1000EDriverWrapper(UnsafeCell<E1000EDriver>);
+unsafe impl Send for E1000EDriverWrapper {}
+unsafe impl Sync for E1000EDriverWrapper {}
+
+impl Deref for E1000EDriverWrapper {
+    type Target = E1000EDriver;
+    fn deref(&self) -> &Self::Target {
+        unsafe { &*self.0.get() }
+    }
+}
+impl DerefMut for E1000EDriverWrapper {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        unsafe { &mut *self.0.get() }
+    }
+}
+
+impl E1000EDriverWrapper {
+    fn force_get_mut(&self) -> &mut E1000EDriver {
+        unsafe { &mut *self.0.get() }
+    }
+}
+
+impl Debug for E1000EDriverWrapper {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_struct("E1000ENICDriver").finish()
+    }
+}
+
+pub struct E1000EInterface {
+    driver: E1000EDriverWrapper,
+    iface_id: usize,
+    iface: SpinLock<smoltcp::iface::Interface>,
+    name: String,
+}
+impl phy::RxToken for E1000ERxToken {
+    fn consume<R, F>(mut self, f: F) -> R
+    where
+        F: FnOnce(&mut [u8]) -> R,
+    {
+        let result = f(&mut self.0.as_mut_slice());
+        self.0.free_buffer();
+        return result;
+    }
+}
+
+impl phy::TxToken for E1000ETxToken {
+    fn consume<R, F>(self, len: usize, f: F) -> R
+    where
+        F: FnOnce(&mut [u8]) -> R,
+    {
+        let mut buffer = E1000EBuffer::new(4096);
+        let result = f(buffer.as_mut_slice());
+        let mut device = self.driver.inner.lock();
+        device.e1000e_transmit(buffer);
+        return result;
+    }
+}
+
+impl E1000EDriver {
+    pub fn new(device: E1000EDevice) -> Self {
+        let mut iface_config = smoltcp::iface::Config::new();
+
+        // todo: 随机设定这个值。
+        // 参见 https://docs.rs/smoltcp/latest/smoltcp/iface/struct.Config.html#structfield.random_seed
+        iface_config.random_seed = 12345;
+
+        iface_config.hardware_addr = Some(wire::HardwareAddress::Ethernet(
+            smoltcp::wire::EthernetAddress(device.mac_address()),
+        ));
+
+        let inner: Arc<SpinLock<E1000EDevice>> = Arc::new(SpinLock::new(device));
+        let result = E1000EDriver { inner };
+        return result;
+    }
+}
+
+impl Clone for E1000EDriver {
+    fn clone(&self) -> Self {
+        return E1000EDriver {
+            inner: self.inner.clone(),
+        };
+    }
+}
+
+impl phy::Device for E1000EDriver {
+    type RxToken<'a> = E1000ERxToken;
+    type TxToken<'a> = E1000ETxToken;
+
+    fn receive(
+        &mut self,
+        _timestamp: smoltcp::time::Instant,
+    ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
+        match self.inner.lock().e1000e_receive() {
+            Some(buffer) => Some((
+                E1000ERxToken(buffer),
+                E1000ETxToken {
+                    driver: self.clone(),
+                },
+            )),
+            None => {
+                return None;
+            }
+        }
+    }
+
+    fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option<Self::TxToken<'_>> {
+        match self.inner.lock().e1000e_can_transmit() {
+            true => Some(E1000ETxToken {
+                driver: self.clone(),
+            }),
+            false => None,
+        }
+    }
+
+    fn capabilities(&self) -> smoltcp::phy::DeviceCapabilities {
+        let mut caps = smoltcp::phy::DeviceCapabilities::default();
+        // 网卡的最大传输单元. 请与IP层的MTU进行区分。这个值应当是网卡的最大传输单元,而不是IP层的MTU。
+        // The maximum size of the received packet is limited by the 82574 hardware to 1536 bytes. Packets larger then 1536 bytes are silently discarded. Any packet smaller than 1536 bytes is processed by the 82574.
+        // 82574l manual pp205
+        caps.max_transmission_unit = 1536;
+        /*
+           Maximum burst size, in terms of MTU.
+           The network device is unable to send or receive bursts large than the value returned by this function.
+           If None, there is no fixed limit on burst size, e.g. if network buffers are dynamically allocated.
+        */
+        caps.max_burst_size = Some(1);
+        return caps;
+    }
+}
+
+impl E1000EInterface {
+    pub fn new(mut driver: E1000EDriver) -> Arc<Self> {
+        let iface_id = generate_iface_id();
+        let mut iface_config = smoltcp::iface::Config::new();
+
+        // todo: 随机设定这个值。
+        // 参见 https://docs.rs/smoltcp/latest/smoltcp/iface/struct.Config.html#structfield.random_seed
+        iface_config.random_seed = 12345;
+
+        iface_config.hardware_addr = Some(wire::HardwareAddress::Ethernet(
+            smoltcp::wire::EthernetAddress(driver.inner.lock().mac_address()),
+        ));
+        let iface = smoltcp::iface::Interface::new(iface_config, &mut driver);
+
+        let driver: E1000EDriverWrapper = E1000EDriverWrapper(UnsafeCell::new(driver));
+        let result = Arc::new(E1000EInterface {
+            driver,
+            iface_id,
+            iface: SpinLock::new(iface),
+            name: format!("eth{}", iface_id),
+        });
+
+        return result;
+    }
+}
+
+impl Debug for E1000EInterface {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_struct("E1000EInterface")
+            .field("iface_id", &self.iface_id)
+            .field("iface", &"smoltcp::iface::Interface")
+            .field("name", &self.name)
+            .finish()
+    }
+}
+
+impl Driver for E1000EInterface {
+    fn id_table(&self) -> Option<IdTable> {
+        todo!()
+    }
+
+    fn add_device(&self, _device: Arc<dyn Device>) {
+        todo!()
+    }
+
+    fn delete_device(&self, _device: &Arc<dyn Device>) {
+        todo!()
+    }
+
+    fn devices(&self) -> alloc::vec::Vec<Arc<dyn Device>> {
+        todo!()
+    }
+
+    fn bus(&self) -> Option<Arc<dyn Bus>> {
+        todo!()
+    }
+
+    fn set_bus(&self, _bus: Option<Arc<dyn Bus>>) {
+        todo!()
+    }
+}
+
+impl NetDriver for E1000EInterface {
+    fn mac(&self) -> smoltcp::wire::EthernetAddress {
+        let mac = self.driver.inner.lock().mac_address();
+        return smoltcp::wire::EthernetAddress::from_bytes(&mac);
+    }
+
+    #[inline]
+    fn nic_id(&self) -> usize {
+        return self.iface_id;
+    }
+
+    #[inline]
+    fn name(&self) -> String {
+        return self.name.clone();
+    }
+
+    fn update_ip_addrs(&self, ip_addrs: &[wire::IpCidr]) -> Result<(), SystemError> {
+        if ip_addrs.len() != 1 {
+            return Err(SystemError::EINVAL);
+        }
+
+        self.iface.lock().update_ip_addrs(|addrs| {
+            let dest = addrs.iter_mut().next();
+            if let None = dest {
+                addrs.push(ip_addrs[0]).expect("Push ipCidr failed: full");
+            } else {
+                let dest = dest.unwrap();
+                *dest = ip_addrs[0];
+            }
+        });
+        return Ok(());
+    }
+
+    fn poll(
+        &self,
+        sockets: &mut smoltcp::iface::SocketSet,
+    ) -> Result<(), crate::syscall::SystemError> {
+        let timestamp: smoltcp::time::Instant = Instant::now().into();
+        let mut guard = self.iface.lock();
+        let poll_res = guard.poll(timestamp, self.driver.force_get_mut(), sockets);
+        if poll_res {
+            return Ok(());
+        }
+        return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
+    }
+
+    #[inline(always)]
+    fn inner_iface(&self) -> &SpinLock<smoltcp::iface::Interface> {
+        return &self.iface;
+    }
+}
+
+impl KObject for E1000EInterface {
+    fn as_any_ref(&self) -> &dyn core::any::Any {
+        self
+    }
+
+    fn set_inode(&self, _inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) {
+        todo!()
+    }
+
+    fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> {
+        todo!()
+    }
+
+    fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
+        todo!()
+    }
+
+    fn set_parent(&self, _parent: Option<alloc::sync::Weak<dyn KObject>>) {
+        todo!()
+    }
+
+    fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> {
+        todo!()
+    }
+
+    fn set_kset(&self, _kset: Option<Arc<crate::driver::base::kset::KSet>>) {
+        todo!()
+    }
+
+    fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> {
+        todo!()
+    }
+
+    fn name(&self) -> String {
+        self.name.clone()
+    }
+
+    fn set_name(&self, _name: String) {
+        todo!()
+    }
+
+    fn kobj_state(
+        &self,
+    ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> {
+        todo!()
+    }
+
+    fn kobj_state_mut(
+        &self,
+    ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
+        todo!()
+    }
+
+    fn set_kobj_state(&self, _state: KObjectState) {
+        todo!()
+    }
+
+    fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {
+        todo!()
+    }
+}
+
+pub fn e1000e_driver_init(device: E1000EDevice) {
+    let mac = smoltcp::wire::EthernetAddress::from_bytes(&device.mac_address());
+    let driver = E1000EDriver::new(device);
+    let iface = E1000EInterface::new(driver);
+    // 将网卡的接口信息注册到全局的网卡接口信息表中
+    NET_DRIVERS.write().insert(iface.nic_id(), iface.clone());
+    kinfo!("e1000e driver init successfully!\tMAC: [{}]", mac);
+}

+ 2 - 0
kernel/src/driver/net/e1000e/mod.rs

@@ -0,0 +1,2 @@
+pub mod e1000e;
+pub mod e1000e_driver;

+ 2 - 0
kernel/src/driver/net/mod.rs

@@ -8,6 +8,8 @@ use crate::{libs::spinlock::SpinLock, syscall::SystemError};
 
 use super::base::device::driver::Driver;
 
+mod dma;
+pub mod e1000e;
 pub mod virtio_net;
 
 pub trait NetDriver: Driver {

+ 2 - 2
kernel/src/driver/net/virtio_net.rs

@@ -16,7 +16,7 @@ use crate::{
         },
         virtio::virtio_impl::HalImpl,
     },
-    kerror, kinfo,
+    kdebug, kerror, kinfo,
     libs::spinlock::SpinLock,
     net::{generate_iface_id, NET_DRIVERS},
     syscall::SystemError,
@@ -310,7 +310,7 @@ impl<T: Transport + 'static> NetDriver for VirtioInterface<T> {
         let mut guard = self.iface.lock();
         let poll_res = guard.poll(timestamp, self.driver.force_get_mut(), sockets);
         // todo: notify!!!
-        // kdebug!("Virtio Interface poll:{poll_res}");
+        kdebug!("Virtio Interface poll:{poll_res}");
         if poll_res {
             return Ok(());
         }

+ 3 - 1
kernel/src/exception/irq.c

@@ -87,9 +87,10 @@ Build_IRQ(0x35);
 Build_IRQ(0x36);
 Build_IRQ(0x37);
 Build_IRQ(0x38);
+Build_IRQ(0x39);
 
 // 初始化中断数组
-void (*interrupt_table[25])(void) = {
+void (*interrupt_table[26])(void) = {
     IRQ0x20interrupt,
     IRQ0x21interrupt,
     IRQ0x22interrupt,
@@ -115,6 +116,7 @@ void (*interrupt_table[25])(void) = {
     IRQ0x36interrupt,
     IRQ0x37interrupt,
     IRQ0x38interrupt,
+    IRQ0x39interrupt,
 };
 
 /**

+ 3 - 2
kernel/src/exception/irq.h

@@ -16,11 +16,11 @@
 #pragma GCC push_options
 #pragma GCC optimize ("O0")
 
-#define IRQ_NUM 25
+#define IRQ_NUM 26
 #define SMP_IRQ_NUM 10
 #define LOCAL_APIC_IRQ_NUM 50
 
-extern void (*interrupt_table[25])(void);
+extern void (*interrupt_table[26])(void);
 extern void do_IRQ(struct pt_regs *regs, ul number);
 
 
@@ -83,6 +83,7 @@ extern void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void);
 	54	PIRQG
 	55	PIRQH
 	56  VIRTIO_RECV
+	57  E1000E_RECV
 	
 	
 0x80		system call

+ 4 - 2
kernel/src/process/init.rs

@@ -4,7 +4,9 @@ use alloc::string::String;
 
 use crate::{
     arch::process::arch_switch_to_user,
-    driver::{disk::ahci::ahci_init, virtio::virtio::virtio_probe},
+    driver::{
+        disk::ahci::ahci_init, net::e1000e::e1000e::e1000e_init, virtio::virtio::virtio_probe,
+    },
     filesystem::vfs::core::mount_root_fs,
     kdebug, kerror,
     net::net_core::net_init,
@@ -22,7 +24,7 @@ pub fn initial_kernel_thread() -> i32 {
     mount_root_fs().expect("Failed to mount root fs");
 
     virtio_probe();
-
+    e1000e_init();
     net_init().unwrap_or_else(|err| {
         kerror!("Failed to initialize network: {:?}", err);
     });

+ 5 - 4
tools/run-qemu.sh

@@ -40,12 +40,12 @@ ARCH="x86_64"
 # 请根据自己的需要,在-d 后方加入所需的 trace 事件
 
 # 标准的trace events
-qemu_trace_std=cpu_reset,guest_errors,exec,cpu,trace:virtio*
+qemu_trace_std=cpu_reset,guest_errors,exec,cpu,trace:virtio*,trace:e1000e_rx*,trace:e1000e_tx*,trace:e1000e_irq*
 # 调试usb的trace
 qemu_trace_usb=trace:usb_xhci_reset,trace:usb_xhci_run,trace:usb_xhci_stop,trace:usb_xhci_irq_msi,trace:usb_xhci_irq_msix,trace:usb_xhci_port_reset,trace:msix_write_config,trace:usb_xhci_irq_msix,trace:usb_xhci_irq_msix_use,trace:usb_xhci_irq_msix_unuse,trace:usb_xhci_irq_msi,trace:usb_xhci_*
 qemu_accel=kvm
 if [ $(uname) == Darwin ]; then
-    qemu_accel=hvf
+    qemu_accel=hvf  
 fi
 
 QEMU=qemu-system-x86_64
@@ -62,8 +62,9 @@ QEMU_DRIVE="id=disk,file=${QEMU_DISK_IMAGE},if=none"
 
 # ps: 下面这条使用tap的方式,无法dhcp获取到ip,暂时不知道为什么
 # QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -net nic,netdev=nic0 -netdev tap,id=nic0,model=virtio-net-pci,script=qemu/ifup-nat,downscript=qemu/ifdown-nat -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
-#QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -nic user,model=virtio-net-pci,hostfwd=tcp::12580-:12580 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
-QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -device virtio-net-pci,vectors=5,netdev=hostnet0,id=net0 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
+# QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -device virtio-net-pci,vectors=5,netdev=hostnet0,id=net0 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 " 
+# E1000E
+QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -net nic,model=e1000e,netdev=hostnet0,id=net0 -netdev user,id=hostnet1,hostfwd=tcp::12581-:12581 -device virtio-net-pci,vectors=5,netdev=hostnet1,id=net1 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 " 
 QEMU_ARGUMENT="-d ${QEMU_DISK_IMAGE} -m ${QEMU_MEMORY} -smp ${QEMU_SMP} -boot order=d -monitor ${QEMU_MONITOR} -d ${qemu_trace_std} "
 
 QEMU_ARGUMENT+="-s -S -enable-kvm -cpu ${QEMU_CPU_FEATURES} -rtc ${QEMU_RTC_CLOCK} -serial ${QEMU_SERIAL} -drive ${QEMU_DRIVE} ${QEMU_DEVICES}"