Browse Source

增加对dhcpv4的支持(tcp、udp socket已写好,但由于缺少epoll机制,尚未完整测试) (#237)

* 为virtio网卡完成smoltcp的phy层配置

* raw socket

* 初步写完udp和tcp socket

* 能够正常通过dhcp获取ipv4地址(具有全局iface btree)

---------

Co-authored-by: guanjinquan <[email protected]>
login 1 year ago
parent
commit
13776c114b

+ 1 - 1
kernel/Cargo.toml

@@ -13,7 +13,7 @@ crate-type = ["staticlib"]
 x86 = "0.52.0"
 x86_64 = "0.14.10"
 bitflags = "1.3.2"
-virtio-drivers = "0.3.0"
+virtio-drivers = { git = "https://github.com/DragonOS-Community/virtio-drivers.git", rev = "f1d1cbb" }
 # 一个无锁MPSC队列
 thingbuf = { version = "0.1.3", default-features = false, features = ["alloc"] }
 # smoltcp 0.9.1

+ 1 - 0
kernel/src/arch/x86_64/mod.rs

@@ -6,4 +6,5 @@ pub mod fpu;
 pub mod interrupt;
 pub mod mm;
 pub mod pci;
+pub mod rand;
 pub mod sched;

+ 5 - 0
kernel/src/arch/x86_64/rand.rs

@@ -0,0 +1,5 @@
+use core::arch::x86_64::_rdtsc;
+
+pub fn rand() -> usize {
+    return unsafe { (_rdtsc() * _rdtsc() + 998244353_u64 * _rdtsc()) as usize };
+}

+ 1 - 1
kernel/src/driver/base/device/mod.rs

@@ -79,7 +79,7 @@ pub trait Device: Any + Send + Sync + Debug {
     /// @parameter: None
     /// @return: 实现该trait的设备所属类型
     fn get_type(&self) -> DeviceType;
-    
+
     /// @brief: 获取设备标识
     /// @parameter: None
     /// @return: 该设备唯一标识

+ 1 - 1
kernel/src/driver/base/platform/mod.rs

@@ -175,7 +175,7 @@ impl PlatformBusDriver {
                         Ok(()) => {
                             num = num + 1;
                             device.set_state(DeviceState::Initialized)
-                        },
+                        }
                         // 可以驱动很多设备,一个设备初始化出错即返回
                         Err(_) => return Err(DeviceError::InitializeFailed),
                     }

+ 6 - 0
kernel/src/driver/mod.rs

@@ -2,9 +2,15 @@ pub mod acpi;
 pub mod base;
 pub mod disk;
 pub mod keyboard;
+pub mod net;
 pub mod pci;
 pub mod timers;
 pub mod tty;
 pub mod uart;
 pub mod video;
 pub mod virtio;
+
+use core::fmt::Debug;
+pub trait Driver: Sync + Send + Debug {
+    fn as_any_ref(&'static self) -> &'static dyn core::any::Any;
+}

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

@@ -0,0 +1,29 @@
+use alloc::string::String;
+use smoltcp::{
+    iface,
+    wire::{self, EthernetAddress},
+};
+
+use crate::{libs::spinlock::SpinLock, syscall::SystemError};
+
+use super::Driver;
+
+pub mod virtio_net;
+
+pub trait NetDriver: Driver {
+    /// @brief 获取网卡的MAC地址
+    fn mac(&self) -> EthernetAddress;
+
+    fn name(&self) -> String;
+
+    /// @brief 获取网卡的id
+    fn nic_id(&self) -> usize;
+
+    fn poll(&self, sockets: &mut iface::SocketSet) -> Result<(), SystemError>;
+
+    fn update_ip_addrs(&self, ip_addrs: &[wire::IpCidr]) -> Result<(), SystemError>;
+
+    /// @brief 获取smoltcp的网卡接口类型
+    fn inner_iface(&self) -> &SpinLock<smoltcp::iface::Interface>;
+    // fn as_any_ref(&'static self) -> &'static dyn core::any::Any;
+}

+ 307 - 0
kernel/src/driver/net/virtio_net.rs

@@ -0,0 +1,307 @@
+use core::{
+    cell::UnsafeCell,
+    fmt::Debug,
+    ops::{Deref, DerefMut},
+};
+
+use alloc::{string::String, sync::Arc};
+use smoltcp::{phy, wire};
+use virtio_drivers::{device::net::VirtIONet, transport::Transport};
+
+use crate::{
+    driver::{virtio::virtio_impl::HalImpl, Driver},
+    kdebug, kerror, kinfo,
+    libs::spinlock::SpinLock,
+    net::{generate_iface_id, NET_DRIVERS},
+    syscall::SystemError,
+    time::Instant,
+};
+
+use super::NetDriver;
+
+/// @brief Virtio网络设备驱动(加锁)
+pub struct VirtioNICDriver<T: Transport> {
+    pub inner: Arc<SpinLock<VirtIONet<HalImpl, T, 2>>>,
+}
+
+impl<T: Transport> Clone for VirtioNICDriver<T> {
+    fn clone(&self) -> Self {
+        return VirtioNICDriver {
+            inner: self.inner.clone(),
+        };
+    }
+}
+
+/// @brief 网卡驱动的包裹器,这是为了获取网卡驱动的可变引用而设计的。
+/// 由于smoltcp的设计,导致需要在poll的时候获取网卡驱动的可变引用,
+/// 同时需要在token的consume里面获取可变引用。为了避免双重加锁,所以需要这个包裹器。
+struct VirtioNICDriverWrapper<T: Transport>(UnsafeCell<VirtioNICDriver<T>>);
+unsafe impl<T: Transport> Send for VirtioNICDriverWrapper<T> {}
+unsafe impl<T: Transport> Sync for VirtioNICDriverWrapper<T> {}
+
+impl<T: Transport> Deref for VirtioNICDriverWrapper<T> {
+    type Target = VirtioNICDriver<T>;
+    fn deref(&self) -> &Self::Target {
+        unsafe { &*self.0.get() }
+    }
+}
+impl<T: Transport> DerefMut for VirtioNICDriverWrapper<T> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        unsafe { &mut *self.0.get() }
+    }
+}
+
+impl<T: Transport> VirtioNICDriverWrapper<T> {
+    fn force_get_mut(&self) -> &mut VirtioNICDriver<T> {
+        unsafe { &mut *self.0.get() }
+    }
+}
+
+impl<T: Transport> Debug for VirtioNICDriver<T> {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_struct("VirtioNICDriver").finish()
+    }
+}
+
+pub struct VirtioInterface<T: Transport> {
+    driver: VirtioNICDriverWrapper<T>,
+    iface_id: usize,
+    iface: SpinLock<smoltcp::iface::Interface>,
+    name: String,
+}
+
+impl<T: Transport> Debug for VirtioInterface<T> {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_struct("VirtioInterface")
+            .field("driver", self.driver.deref())
+            .field("iface_id", &self.iface_id)
+            .field("iface", &"smoltcp::iface::Interface")
+            .field("name", &self.name)
+            .finish()
+    }
+}
+
+impl<T: Transport> VirtioInterface<T> {
+    pub fn new(mut driver: VirtioNICDriver<T>) -> 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: VirtioNICDriverWrapper<T> = VirtioNICDriverWrapper(UnsafeCell::new(driver));
+        let result = Arc::new(VirtioInterface {
+            driver,
+            iface_id,
+            iface: SpinLock::new(iface),
+            name: format!("eth{}", iface_id),
+        });
+
+        return result;
+    }
+}
+
+impl<T: 'static + Transport> VirtioNICDriver<T> {
+    pub fn new(driver_net: VirtIONet<HalImpl, T, 2>) -> 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(driver_net.mac_address()),
+        ));
+
+        let inner: Arc<SpinLock<VirtIONet<HalImpl, T, 2>>> = Arc::new(SpinLock::new(driver_net));
+        let result = VirtioNICDriver { inner };
+        return result;
+    }
+}
+
+pub struct VirtioNetToken<T: Transport> {
+    driver: VirtioNICDriver<T>,
+    rx_buffer: Option<virtio_drivers::device::net::RxBuffer>,
+}
+
+impl<'a, T: Transport> VirtioNetToken<T> {
+    pub fn new(
+        driver: VirtioNICDriver<T>,
+        rx_buffer: Option<virtio_drivers::device::net::RxBuffer>,
+    ) -> Self {
+        return Self { driver, rx_buffer };
+    }
+}
+
+impl<T: Transport> phy::Device for VirtioNICDriver<T> {
+    type RxToken<'a> = VirtioNetToken<T> where Self: 'a;
+    type TxToken<'a> = VirtioNetToken<T> where Self: 'a;
+
+    fn receive(
+        &mut self,
+        _timestamp: smoltcp::time::Instant,
+    ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
+        match self.inner.lock().receive() {
+            Ok(buf) => Some((
+                VirtioNetToken::new(self.clone(), Some(buf)),
+                VirtioNetToken::new(self.clone(), None),
+            )),
+            Err(virtio_drivers::Error::NotReady) => None,
+            Err(err) => panic!("VirtIO receive failed: {}", err),
+        }
+    }
+
+    fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option<Self::TxToken<'_>> {
+        // kdebug!("VirtioNet: transmit");
+        if self.inner.lock().can_send() {
+            // kdebug!("VirtioNet: can send");
+            return Some(VirtioNetToken::new(self.clone(), None));
+        } else {
+            // kdebug!("VirtioNet: can not send");
+            return None;
+        }
+    }
+
+    fn capabilities(&self) -> phy::DeviceCapabilities {
+        let mut caps = phy::DeviceCapabilities::default();
+        // 网卡的最大传输单元. 请与IP层的MTU进行区分。这个值应当是网卡的最大传输单元,而不是IP层的MTU。
+        caps.max_transmission_unit = 2000;
+        /*
+           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<T: Transport> phy::TxToken for VirtioNetToken<T> {
+    fn consume<R, F>(self, len: usize, f: F) -> R
+    where
+        F: FnOnce(&mut [u8]) -> R,
+    {
+        // // 为了线程安全,这里需要对VirtioNet进行加【写锁】,以保证对设备的互斥访问。
+
+        let mut driver_net = self.driver.inner.lock();
+        let mut tx_buf = driver_net.new_tx_buffer(len);
+        let result = f(tx_buf.packet_mut());
+        driver_net.send(tx_buf).expect("virtio_net send failed");
+        return result;
+    }
+}
+
+impl<T: Transport> phy::RxToken for VirtioNetToken<T> {
+    fn consume<R, F>(self, f: F) -> R
+    where
+        F: FnOnce(&mut [u8]) -> R,
+    {
+        // 为了线程安全,这里需要对VirtioNet进行加【写锁】,以保证对设备的互斥访问。
+        let mut rx_buf = self.rx_buffer.unwrap();
+        let result = f(rx_buf.packet_mut());
+        self.driver
+            .inner
+            .lock()
+            .recycle_rx_buffer(rx_buf)
+            .expect("virtio_net recv failed");
+        result
+    }
+}
+
+/// @brief virtio-net 驱动的初始化与测试
+pub fn virtio_net<T: Transport + 'static>(transport: T) {
+    let driver_net: VirtIONet<HalImpl, T, 2> =
+        match VirtIONet::<HalImpl, T, 2>::new(transport, 4096) {
+            Ok(net) => net,
+            Err(_) => {
+                kerror!("VirtIONet init failed");
+                return;
+            }
+        };
+    let mac = smoltcp::wire::EthernetAddress::from_bytes(&driver_net.mac_address());
+    let driver: VirtioNICDriver<T> = VirtioNICDriver::new(driver_net);
+    let iface = VirtioInterface::new(driver);
+    // 将网卡的接口信息注册到全局的网卡接口信息表中
+    NET_DRIVERS.write().insert(iface.nic_id(), iface.clone());
+    kinfo!(
+        "Virtio-net driver init successfully!\tNetDevID: [{}], MAC: [{}]",
+        iface.name(),
+        mac
+    );
+}
+
+impl<T: Transport> Driver for VirtioInterface<T> {
+    fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
+        self
+    }
+}
+
+impl<T: Transport> NetDriver for VirtioInterface<T> {
+    fn mac(&self) -> smoltcp::wire::EthernetAddress {
+        let mac: [u8; 6] = 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);
+        // todo: notify!!!
+        // kdebug!("Virtio Interface poll:{poll_res}");
+        if poll_res {
+            return Ok(());
+        }
+        return Err(SystemError::EAGAIN);
+    }
+
+    #[inline(always)]
+    fn inner_iface(&self) -> &SpinLock<smoltcp::iface::Interface> {
+        return &self.iface;
+    }
+    // fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
+    //     return self;
+    // }
+}
+
+// 向编译器保证,VirtioNICDriver在线程之间是安全的.
+// 由于smoltcp只会在token内真正操作网卡设备,并且在VirtioNetToken的consume
+// 方法内,会对VirtioNet进行加【写锁】,因此,能够保证对设备操作的的互斥访问,
+// 因此VirtioNICDriver在线程之间是安全的。
+// unsafe impl<T: Transport> Sync for VirtioNICDriver<T> {}
+// unsafe impl<T: Transport> Send for VirtioNICDriver<T> {}

+ 3 - 11
kernel/src/driver/pci/pci.rs

@@ -44,16 +44,12 @@ impl PciDeviceLinkedList {
     }
     /// @brief 获取可读的linkedlist(读锁守卫)
     /// @return RwLockReadGuard<LinkedList<Box<dyn PciDeviceStructure>>>  读锁守卫
-    pub fn read(
-        &self,
-    ) -> RwLockReadGuard<LinkedList<Box<dyn PciDeviceStructure>>> {
+    pub fn read(&self) -> RwLockReadGuard<LinkedList<Box<dyn PciDeviceStructure>>> {
         self.list.read()
     }
     /// @brief 获取可写的linkedlist(写锁守卫)
     /// @return RwLockWriteGuard<LinkedList<Box<dyn PciDeviceStructure>>>  写锁守卫
-    pub fn write(
-        &self,
-    ) -> RwLockWriteGuard<LinkedList<Box<dyn PciDeviceStructure>>> {
+    pub fn write(&self) -> RwLockWriteGuard<LinkedList<Box<dyn PciDeviceStructure>>> {
         self.list.write()
     }
     /// @brief 获取链表中PCI结构体数目
@@ -554,11 +550,7 @@ impl PciRoot {
     /// @param bus_device_function 在同一个group中pci设备的唯一标识符
     /// @param register_offset 寄存器在设备中的offset
     /// @return u32 寄存器读值结果
-    pub fn read_config(
-        &self,
-        bus_device_function: BusDeviceFunction,
-        register_offset: u16,
-    ) -> u32 {
+    pub fn read_config(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 {
         let address = self.cam_offset(bus_device_function, register_offset);
         unsafe {
             // Right shift to convert from byte offset to word offset.

+ 13 - 11
kernel/src/driver/virtio/transport_pci.rs

@@ -73,7 +73,7 @@ fn device_type(pci_device_id: u16) -> DeviceType {
 /// PCI transport for VirtIO.
 ///
 /// Ref: 4.1 Virtio Over PCI Bus
-#[derive(Debug)]
+#[derive(Debug, Clone)]
 pub struct PciTransport {
     device_type: DeviceType,
     /// The bus, device and function identifier for the VirtIO device.
@@ -104,8 +104,8 @@ impl PciTransport {
         }
         let device_type = device_type(header.device_id);
         // Find the PCI capabilities we need.
-        let mut common_cfg = None;
-        let mut notify_cfg = None;
+        let mut common_cfg: Option<VirtioCapabilityInfo> = None;
+        let mut notify_cfg: Option<VirtioCapabilityInfo> = None;
         let mut notify_off_multiplier = 0;
         let mut isr_cfg = None;
         let mut device_cfg = None;
@@ -361,7 +361,7 @@ struct CommonCfg {
 }
 
 /// Information about a VirtIO structure within some BAR, as provided by a `virtio_pci_cap`.
-///cfg空间在哪个bar的多少偏移处,长度多少
+/// cfg空间在哪个bar的多少偏移处,长度多少
 #[derive(Clone, Debug, Eq, PartialEq)]
 struct VirtioCapabilityInfo {
     /// The bar in which the structure can be found.
@@ -445,16 +445,17 @@ impl Display for VirtioPciError {
         }
     }
 }
-///PCI error到VirtioPciError的转换,层层上报
+
+/// PCI error到VirtioPciError的转换,层层上报
 impl From<PciError> for VirtioPciError {
     fn from(error: PciError) -> Self {
         Self::Pci(error)
     }
 }
 
-///@brief 获取虚拟地址并将其转化为对应类型的指针
-///@param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息
-///@return Result<NonNull<T>, VirtioPciError> 成功则返回对应类型的指针,失败则返回Error
+/// @brief 获取虚拟地址并将其转化为对应类型的指针
+/// @param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息
+/// @return Result<NonNull<T>, VirtioPciError> 成功则返回对应类型的指针,失败则返回Error
 fn get_bar_region<T>(
     device_bar: &PciStandardDeviceBar,
     struct_info: &VirtioCapabilityInfo,
@@ -486,9 +487,9 @@ fn get_bar_region<T>(
     Ok(vaddr.cast())
 }
 
-///@brief 获取虚拟地址并将其转化为对应类型的
-///@param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息切片的指针
-///@return Result<NonNull<[T]>, VirtioPciError> 成功则返回对应类型的指针切片,失败则返回Error
+/// @brief 获取虚拟地址并将其转化为对应类型的
+/// @param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息切片的指针
+/// @return Result<NonNull<[T]>, VirtioPciError> 成功则返回对应类型的指针切片,失败则返回Error
 fn get_bar_region_slice<T>(
     device_bar: &PciStandardDeviceBar,
     struct_info: &VirtioCapabilityInfo,
@@ -501,6 +502,7 @@ fn get_bar_region_slice<T>(
         struct_info.length as usize / size_of::<T>(),
     ))
 }
+
 fn nonnull_slice_from_raw_parts<T>(data: NonNull<T>, len: usize) -> NonNull<[T]> {
     NonNull::new(ptr::slice_from_raw_parts_mut(data.as_ptr(), len)).unwrap()
 }

+ 1 - 1
kernel/src/driver/virtio/virtio.h

@@ -2,4 +2,4 @@
 #include <common/glib.h>
 
 //寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备后续也可添加)
-void  c_virtio_probe();
+extern void  rs_virtio_probe();

+ 5 - 56
kernel/src/driver/virtio/virtio.rs

@@ -1,5 +1,6 @@
 use super::transport_pci::PciTransport;
 use super::virtio_impl::HalImpl;
+use crate::driver::net::virtio_net::virtio_net;
 use crate::driver::pci::pci::PciDeviceStructureGeneralDevice;
 use crate::driver::pci::pci::{
     get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST,
@@ -7,8 +8,8 @@ use crate::driver::pci::pci::{
 use crate::libs::rwlock::RwLockWriteGuard;
 use crate::{kdebug, kerror, kwarn};
 use alloc::{boxed::Box, collections::LinkedList};
-use virtio_drivers::device::net::VirtIONet;
 use virtio_drivers::transport::{DeviceType, Transport};
+
 const NETWORK_CLASS: u8 = 0x2;
 const ETHERNET_SUBCLASS: u8 = 0x0;
 
@@ -18,9 +19,9 @@ enum VirtioError {
     NetDeviceNotFound,
 }
 
-///@brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加)(for c)
+/// @brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加)(for c)
 #[no_mangle]
-pub extern "C" fn c_virtio_probe() {
+pub extern "C" fn rs_virtio_probe() {
     virtio_probe();
 }
 
@@ -49,7 +50,7 @@ pub fn virtio_probe() {
 }
 
 ///@brief 为virtio设备寻找对应的驱动进行初始化
-fn virtio_device_init(transport: impl Transport) {
+fn virtio_device_init(transport: impl Transport + 'static) {
     match transport.device_type() {
         DeviceType::Block => {
             kwarn!("Not support virtio_block device for now");
@@ -67,58 +68,6 @@ fn virtio_device_init(transport: impl Transport) {
     }
 }
 
-///@brief virtio-net 驱动的初始化与测试
-fn virtio_net<T: Transport>(transport: T) {
-    let driver_net = match VirtIONet::<HalImpl, T>::new(transport) {
-        Ok(net) => {
-            kdebug!("Virtio-net driver init successfully.");
-            net
-        }
-        Err(_) => {
-            kerror!("VirtIONet init failed");
-            return;
-        }
-    };
-    // let mut buf = [0u8; 0x100];
-    // // let len = match driver_net.recv(&mut buf)
-    // // {
-    // //     Ok(len) =>{len},
-    // //     Err(_) =>{kerror!("virtio_net recv failed");return;}
-    // // };
-    // match driver_net.can_send() {
-    //     true => {
-    //         kdebug!("Virtio-net can send");
-    //     }
-    //     false => {
-    //         kdebug!("Virtio-net can not send");
-    //     }
-    // }
-    // // match driver_net.can_recv() {
-    // //     true => {
-    // //         kdebug!("can recv")
-    // //     }
-    // //     false => {
-    // //         kdebug!("can not recv");
-    // //     }
-    // // }
-
-    // let len = 100;
-    // //kdebug!("recv: {:?}", &buf[..len]);
-    // match driver_net.send(&buf[..len]) {
-    //     Ok(_) => {
-    //         kdebug!("virtio_net send success");
-    //     }
-    //     Err(_) => {
-    //         kerror!("virtio_net send failed");
-    //         return;
-    //     }
-    // }
-
-    let mac = driver_net.mac();
-    kdebug!("virtio_net MAC={:?}", mac);
-    kdebug!("virtio-net test finished");
-}
-
 /// @brief 寻找所有的virtio设备
 /// @param list 链表的写锁
 /// @return Result<LinkedList<&'a mut Pci_Device_Structure_General_Device>, VirtioError>  成功则返回包含所有virtio设备结构体的可变引用的链表,失败则返回err

+ 5 - 5
kernel/src/driver/virtio/virtio_impl.rs

@@ -8,7 +8,7 @@ use core::mem::size_of;
 use core::ptr::NonNull;
 use virtio_drivers::{BufferDirection, Hal, PhysAddr, PAGE_SIZE};
 pub struct HalImpl;
-impl Hal for HalImpl {
+unsafe impl Hal for HalImpl {
     /// @brief 申请用于DMA的内存页
     /// @param pages 页数(4k一页)
     /// @return PhysAddr 获得的内存页的初始物理地址
@@ -27,7 +27,7 @@ impl Hal for HalImpl {
     /// @brief 释放用于DMA的内存页
     /// @param paddr 起始物理地址 pages 页数(4k一页)
     /// @return i32 0表示成功
-    fn dma_dealloc(paddr: PhysAddr, _vaddr: NonNull<u8>, pages: usize) -> i32 {
+    unsafe fn dma_dealloc(paddr: PhysAddr, _vaddr: NonNull<u8>, pages: usize) -> i32 {
         let page_num = (pages * PAGE_SIZE - 1 + PAGE_2M_SIZE as usize) / PAGE_2M_SIZE as usize;
         unsafe {
             let pa = (memory_management_struct.pages_struct as usize
@@ -40,20 +40,20 @@ impl Hal for HalImpl {
     /// @brief mmio物理地址转换为虚拟地址,不需要使用
     /// @param paddr 起始物理地址
     /// @return NonNull<u8> 虚拟地址的指针
-    fn mmio_phys_to_virt(_paddr: PhysAddr, _size: usize) -> NonNull<u8> {
+    unsafe fn mmio_phys_to_virt(_paddr: PhysAddr, _size: usize) -> NonNull<u8> {
         NonNull::new((0) as _).unwrap()
     }
     /// @brief 与真实物理设备共享
     /// @param buffer 要共享的buffer _direction:设备到driver或driver到设备
     /// @return buffer在内存中的物理地址
-    fn share(buffer: NonNull<[u8]>, _direction: BufferDirection) -> PhysAddr {
+    unsafe fn share(buffer: NonNull<[u8]>, _direction: BufferDirection) -> PhysAddr {
         let vaddr = buffer.as_ptr() as *mut u8 as usize;
         //kdebug!("virt:{:x}", vaddr);
         // Nothing to do, as the host already has access to all memory.
         virt_2_phys(vaddr)
     }
     /// @brief 停止共享(让主机可以访问全部内存的话什么都不用做)
-    fn unshare(_paddr: PhysAddr, _buffer: NonNull<[u8]>, _direction: BufferDirection) {
+    unsafe fn unshare(_paddr: PhysAddr, _buffer: NonNull<[u8]>, _direction: BufferDirection) {
         // Nothing to do, as the host already has access to all memory and we didn't copy the buffer
         // anywhere else.
     }

+ 2 - 1
kernel/src/include/bindings/wrapper.h

@@ -19,6 +19,7 @@
 #include <common/crc8.h>
 #include <common/gfp.h>
 #include <common/glib.h>
+#include <common/idr.h>
 #include <common/kfifo.h>
 #include <common/kthread.h>
 #include <common/list.h>
@@ -44,4 +45,4 @@
 #include <process/process.h>
 #include <sched/sched.h>
 #include <smp/smp.h>
-#include <time/sleep.h>
+#include <time/sleep.h>

+ 2 - 2
kernel/src/ktest/test-idr.c

@@ -190,7 +190,7 @@ static long ktest_idr_case2(uint64_t arg0, uint64_t arg1)
     DECLARE_IDR(k_idr);
 
     // 获取 1000‘000 个ID
-    const int N = 1e6;
+    const int N = 1048576;
     // const int N = 1048576;
     const int M = 2e5;
 
@@ -570,7 +570,7 @@ static long ktest_idr_case6(uint64_t arg0, uint64_t arg1)
 static ktest_case_table kt_idr_func_table[] = {
     ktest_idr_case0,
     ktest_idr_case1,
-    // ktest_idr_case2, // 为了加快启动速度, 暂时注释掉这个测试
+    ktest_idr_case2, // 为了加快启动速度, 暂时注释掉这个测试
     ktest_idr_case3,
     ktest_idr_case4,
     ktest_idr_case5,

+ 3 - 1
kernel/src/lib.rs

@@ -5,7 +5,7 @@
 #![feature(alloc_error_handler)]
 #![feature(panic_info_message)]
 #![feature(drain_filter)] // 允许Vec的drain_filter特性
-#![feature(c_void_variant)] // used in kernel/src/exception/softirq.rs
+#![feature(c_void_variant)]
 #[allow(non_upper_case_globals)]
 #[allow(non_camel_case_types)]
 #[allow(non_snake_case)]
@@ -52,6 +52,7 @@ use mm::allocator::KernelAllocator;
 use crate::{
     arch::asm::current::current_pcb,
     include::bindings::bindings::{process_do_exit, BLACK, GREEN},
+    net::net_core::net_init,
 };
 
 // 声明全局的slab分配器
@@ -98,5 +99,6 @@ pub fn panic(info: &PanicInfo) -> ! {
 #[no_mangle]
 pub extern "C" fn __rust_demo_func() -> i32 {
     printk_color!(GREEN, BLACK, "__rust_demo_func()\n");
+    net_init().expect("Failed to init network");
     return 0;
 }

+ 1 - 1
kernel/src/libs/rwlock.rs

@@ -239,7 +239,7 @@ impl<T> RwLock<T> {
     }
 
     #[allow(dead_code)]
-    pub fn get_mut(&mut self) -> &mut T {
+    pub unsafe fn get_mut(&mut self) -> &mut T {
         unsafe { &mut *self.data.get() }
     }
 }

+ 19 - 0
kernel/src/net/endpoints.rs

@@ -0,0 +1,19 @@
+pub use smoltcp::wire::IpEndpoint;
+
+/// @brief 链路层端点
+#[derive(Debug, Clone)]
+pub struct LinkLayerEndpoint {
+    /// 网卡的接口号
+    pub interface: usize,
+}
+
+impl LinkLayerEndpoint {
+    /// @brief 创建一个链路层端点
+    ///
+    /// @param interface 网卡的接口号
+    ///
+    /// @return 返回创建的链路层端点
+    pub fn new(interface: usize) -> Self {
+        Self { interface }
+    }
+}

+ 246 - 4
kernel/src/net/mod.rs

@@ -1,9 +1,251 @@
-use core::fmt::Debug;
+use core::{
+    fmt::{self, Debug},
+    sync::atomic::AtomicUsize,
+};
 
-use crate::syscall::SystemError;
+use alloc::{boxed::Box, collections::BTreeMap, sync::Arc};
+
+use crate::{driver::net::NetDriver, libs::rwlock::RwLock, syscall::SystemError};
+use smoltcp::wire::IpEndpoint;
+
+use self::socket::SocketMetadata;
+
+pub mod endpoints;
+pub mod net_core;
+pub mod socket;
+
+lazy_static! {
+    /// @brief 所有网络接口的列表
+    pub static ref NET_DRIVERS: RwLock<BTreeMap<usize, Arc<dyn NetDriver>>> = RwLock::new(BTreeMap::new());
+}
+
+/// @brief 生成网络接口的id (全局自增)
+pub fn generate_iface_id() -> usize {
+    static IFACE_ID: AtomicUsize = AtomicUsize::new(0);
+    return IFACE_ID
+        .fetch_add(1, core::sync::atomic::Ordering::SeqCst)
+        .into();
+}
+
+/// @brief 用于指定socket的关闭类型
+#[derive(Debug, Clone)]
+pub enum ShutdownType {
+    ShutRd,   // Disables further receive operations.
+    ShutWr,   // Disables further send operations.
+    ShutRdwr, // Disables further send and receive operations.
+}
+
+#[derive(Debug, Clone)]
+pub enum Endpoint {
+    /// 链路层端点
+    LinkLayer(endpoints::LinkLayerEndpoint),
+    /// 网络层端点
+    Ip(IpEndpoint),
+    // todo: 增加NetLink机制后,增加NetLink端点
+}
 
 pub trait Socket: Sync + Send + Debug {
-    fn read(&self, buf: &mut [u8]) -> Result<usize, SystemError>;
+    /// @brief 从socket中读取数据,如果socket是阻塞的,那么直到读取到数据才返回
+    ///
+    /// @param buf 读取到的数据存放的缓冲区
+    ///
+    /// @return - 成功:(返回读取的数据的长度,读取数据的端点).
+    ///         - 失败:错误码
+    fn read(&self, buf: &mut [u8]) -> Result<(usize, Endpoint), SystemError>;
+
+    /// @brief 向socket中写入数据。如果socket是阻塞的,那么直到写入的数据全部写入socket中才返回
+    ///
+    /// @param buf 要写入的数据
+    /// @param to 要写入的目的端点,如果是None,那么写入的数据将会被丢弃
+    ///
+    /// @return 返回写入的数据的长度
+    fn write(&self, buf: &[u8], to: Option<Endpoint>) -> Result<usize, SystemError>;
+
+    /// @brief 对应于POSIX的connect函数,用于连接到指定的远程服务器端点
+    ///
+    /// It is used to establish a connection to a remote server.
+    /// When a socket is connected to a remote server,
+    /// the operating system will establish a network connection with the server
+    /// and allow data to be sent and received between the local socket and the remote server.
+    ///
+    /// @param endpoint 要连接的端点
+    ///
+    /// @return 返回连接是否成功
+    fn connect(&mut self, endpoint: Endpoint) -> Result<(), SystemError>;
+
+    /// @brief 对应于POSIX的bind函数,用于绑定到本机指定的端点
+    ///
+    /// The bind() function is used to associate a socket with a particular IP address and port number on the local machine.
+    ///
+    /// @param endpoint 要绑定的端点
+    ///
+    /// @return 返回绑定是否成功
+    fn bind(&self, _endpoint: Endpoint) -> Result<(), SystemError> {
+        return Err(SystemError::ENOSYS);
+    }
+
+    /// @brief 对应于 POSIX 的 shutdown 函数,用于关闭socket。
+    ///
+    /// shutdown() 函数用于启动网络连接的正常关闭。
+    /// 当在两个端点之间建立网络连接时,任一端点都可以通过调用其端点对象上的 shutdown() 函数来启动关闭序列。
+    /// 此函数向远程端点发送关闭消息以指示本地端点不再接受新数据。
+    ///
+    /// @return 返回是否成功关闭
+    fn shutdown(&self, _type: ShutdownType) -> Result<(), SystemError> {
+        return Err(SystemError::ENOSYS);
+    }
+
+    /// @brief 对应于POSIX的listen函数,用于监听端点
+    ///
+    /// @param backlog 最大的等待连接数
+    ///
+    /// @return 返回监听是否成功
+    fn listen(&mut self, _backlog: usize) -> Result<(), SystemError> {
+        return Err(SystemError::ENOSYS);
+    }
+
+    /// @brief 对应于POSIX的accept函数,用于接受连接
+    ///
+    /// @param endpoint 用于返回连接的端点
+    ///
+    /// @return 返回接受连接是否成功
+    fn accept(&mut self) -> Result<(Box<dyn Socket>, Endpoint), SystemError> {
+        return Err(SystemError::ENOSYS);
+    }
+
+    /// @brief 获取socket的端点
+    ///
+    /// @return 返回socket的端点
+    fn endpoint(&self) -> Option<Endpoint> {
+        return None;
+    }
+
+    /// @brief 获取socket的对端端点
+    ///
+    /// @return 返回socket的对端端点
+    fn peer_endpoint(&self) -> Option<Endpoint> {
+        return None;
+    }
+
+    /// @brief
+    ///     The purpose of the poll function is to provide
+    ///     a non-blocking way to check if a socket is ready for reading or writing,
+    ///     so that you can efficiently handle multiple sockets in a single thread or event loop.
+    ///
+    /// @return (in, out, err)
+    ///
+    ///     The first boolean value indicates whether the socket is ready for reading. If it is true, then there is data available to be read from the socket without blocking.
+    ///     The second boolean value indicates whether the socket is ready for writing. If it is true, then data can be written to the socket without blocking.
+    ///     The third boolean value indicates whether the socket has encountered an error condition. If it is true, then the socket is in an error state and should be closed or reset
+    ///
+    fn poll(&self) -> (bool, bool, bool) {
+        return (false, false, false);
+    }
+
+    /// @brief socket的ioctl函数
+    ///
+    /// @param cmd ioctl命令
+    /// @param arg0 ioctl命令的第一个参数
+    /// @param arg1 ioctl命令的第二个参数
+    /// @param arg2 ioctl命令的第三个参数
+    ///
+    /// @return 返回ioctl命令的返回值
+    fn ioctl(
+        &self,
+        _cmd: usize,
+        _arg0: usize,
+        _arg1: usize,
+        _arg2: usize,
+    ) -> Result<usize, SystemError> {
+        return Ok(0);
+    }
+
+    /// @brief 获取socket的元数据
+    fn metadata(&self) -> Result<SocketMetadata, SystemError>;
+
+    fn box_clone(&self) -> Box<dyn Socket>;
+}
+
+impl Clone for Box<dyn Socket> {
+    fn clone(&self) -> Box<dyn Socket> {
+        self.box_clone()
+    }
+}
+
+/// IP datagram encapsulated protocol.
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+#[repr(u8)]
+pub enum Protocol {
+    HopByHop = 0x00,
+    Icmp = 0x01,
+    Igmp = 0x02,
+    Tcp = 0x06,
+    Udp = 0x11,
+    Ipv6Route = 0x2b,
+    Ipv6Frag = 0x2c,
+    Icmpv6 = 0x3a,
+    Ipv6NoNxt = 0x3b,
+    Ipv6Opts = 0x3c,
+    Unknown(u8),
+}
+
+impl fmt::Display for Protocol {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Protocol::HopByHop => write!(f, "Hop-by-Hop"),
+            Protocol::Icmp => write!(f, "ICMP"),
+            Protocol::Igmp => write!(f, "IGMP"),
+            Protocol::Tcp => write!(f, "TCP"),
+            Protocol::Udp => write!(f, "UDP"),
+            Protocol::Ipv6Route => write!(f, "IPv6-Route"),
+            Protocol::Ipv6Frag => write!(f, "IPv6-Frag"),
+            Protocol::Icmpv6 => write!(f, "ICMPv6"),
+            Protocol::Ipv6NoNxt => write!(f, "IPv6-NoNxt"),
+            Protocol::Ipv6Opts => write!(f, "IPv6-Opts"),
+            Protocol::Unknown(id) => write!(f, "0x{id:02x}"),
+        }
+    }
+}
+
+impl From<smoltcp::wire::IpProtocol> for Protocol {
+    fn from(value: smoltcp::wire::IpProtocol) -> Self {
+        let x: u8 = value.into();
+        Protocol::from(x)
+    }
+}
+
+impl From<u8> for Protocol {
+    fn from(value: u8) -> Self {
+        match value {
+            0x00 => Protocol::HopByHop,
+            0x01 => Protocol::Icmp,
+            0x02 => Protocol::Igmp,
+            0x06 => Protocol::Tcp,
+            0x11 => Protocol::Udp,
+            0x2b => Protocol::Ipv6Route,
+            0x2c => Protocol::Ipv6Frag,
+            0x3a => Protocol::Icmpv6,
+            0x3b => Protocol::Ipv6NoNxt,
+            0x3c => Protocol::Ipv6Opts,
+            _ => Protocol::Unknown(value),
+        }
+    }
+}
 
-    fn write(&self, buf: &[u8]) -> Result<usize, SystemError>;
+impl Into<u8> for Protocol {
+    fn into(self) -> u8 {
+        match self {
+            Protocol::HopByHop => 0x00,
+            Protocol::Icmp => 0x01,
+            Protocol::Igmp => 0x02,
+            Protocol::Tcp => 0x06,
+            Protocol::Udp => 0x11,
+            Protocol::Ipv6Route => 0x2b,
+            Protocol::Ipv6Frag => 0x2c,
+            Protocol::Icmpv6 => 0x3a,
+            Protocol::Ipv6NoNxt => 0x3b,
+            Protocol::Ipv6Opts => 0x3c,
+            Protocol::Unknown(id) => id,
+        }
+    }
 }

+ 87 - 0
kernel/src/net/net_core.rs

@@ -0,0 +1,87 @@
+use smoltcp::{socket::dhcpv4, wire};
+
+use crate::{kdebug, kinfo, net::NET_DRIVERS, syscall::SystemError};
+
+pub fn net_init() -> Result<(), SystemError> {
+    dhcp_query()?;
+    return Ok(());
+}
+fn dhcp_query() -> Result<(), SystemError> {
+    let binding = NET_DRIVERS.write();
+
+    let net_face = binding.get(&0).unwrap().clone();
+
+    drop(binding);
+
+    // Create sockets
+    let mut dhcp_socket = dhcpv4::Socket::new();
+
+    // Set a ridiculously short max lease time to show DHCP renews work properly.
+    // This will cause the DHCP client to start renewing after 5 seconds, and give up the
+    // lease after 10 seconds if renew hasn't succeeded.
+    // IMPORTANT: This should be removed in production.
+    dhcp_socket.set_max_lease_duration(Some(smoltcp::time::Duration::from_secs(10)));
+
+    let mut sockets = smoltcp::iface::SocketSet::new(vec![]);
+    let dhcp_handle = sockets.add(dhcp_socket);
+
+    const DHCP_TRY_ROUND: u8 = 10;
+    for i in 0..DHCP_TRY_ROUND {
+        kdebug!("DHCP try round: {}", i);
+        let _flag = net_face.poll(&mut sockets);
+        let event = sockets.get_mut::<dhcpv4::Socket>(dhcp_handle).poll();
+        // kdebug!("event = {event:?} !!!");
+
+        match event {
+            None => {}
+
+            Some(dhcpv4::Event::Configured(config)) => {
+                // kdebug!("Find Config!! {config:?}");
+                // kdebug!("Find ip address: {}", config.address);
+                // kdebug!("iface.ip_addrs={:?}", net_face.inner_iface.ip_addrs());
+
+                net_face
+                    .update_ip_addrs(&[wire::IpCidr::Ipv4(config.address)])
+                    .ok();
+
+                if let Some(router) = config.router {
+                    net_face
+                        .inner_iface()
+                        .lock()
+                        .routes_mut()
+                        .add_default_ipv4_route(router)
+                        .unwrap();
+                    let cidr = net_face.inner_iface().lock().ip_addrs().first().cloned();
+                    if cidr.is_some() {
+                        let cidr = cidr.unwrap();
+                        kinfo!("Successfully allocated ip by Dhcpv4! Ip:{}", cidr);
+                        return Ok(());
+                    }
+                } else {
+                    net_face
+                        .inner_iface()
+                        .lock()
+                        .routes_mut()
+                        .remove_default_ipv4_route();
+                }
+            }
+
+            Some(dhcpv4::Event::Deconfigured) => {
+                kdebug!("Dhcp v4 deconfigured");
+                net_face
+                    .update_ip_addrs(&[smoltcp::wire::IpCidr::Ipv4(wire::Ipv4Cidr::new(
+                        wire::Ipv4Address::UNSPECIFIED,
+                        0,
+                    ))])
+                    .ok();
+                net_face
+                    .inner_iface()
+                    .lock()
+                    .routes_mut()
+                    .remove_default_ipv4_route();
+            }
+        }
+    }
+
+    return Err(SystemError::ETIMEDOUT);
+}

+ 615 - 0
kernel/src/net/socket.rs

@@ -0,0 +1,615 @@
+#![allow(dead_code)]
+use alloc::{boxed::Box, vec::Vec};
+use smoltcp::{
+    iface::{SocketHandle, SocketSet},
+    socket::{raw, tcp, udp},
+    wire::{IpAddress, IpEndpoint, IpProtocol, Ipv4Address, Ipv4Packet, Ipv6Address},
+};
+
+use crate::{
+    arch::rand::rand, kdebug, kerror, kwarn, libs::spinlock::SpinLock, syscall::SystemError,
+};
+
+use super::{Endpoint, Protocol, Socket, NET_DRIVERS};
+
+lazy_static! {
+    /// 所有socket的集合
+    /// TODO: 优化这里,自己实现SocketSet!!!现在这样的话,不管全局有多少个网卡,每个时间点都只会有1个进程能够访问socket
+    pub static ref SOCKET_SET: SpinLock<SocketSet<'static >> = SpinLock::new(SocketSet::new(vec![]));
+}
+
+/// @brief socket的句柄管理组件。
+/// 它在smoltcp的SocketHandle上封装了一层,增加更多的功能。
+/// 比如,在socket被关闭时,自动释放socket的资源,通知系统的其他组件。
+#[derive(Debug)]
+pub struct GlobalSocketHandle(SocketHandle);
+
+impl GlobalSocketHandle {
+    pub fn new(handle: SocketHandle) -> Self {
+        Self(handle)
+    }
+}
+
+impl Clone for GlobalSocketHandle {
+    fn clone(&self) -> Self {
+        Self(self.0)
+    }
+}
+
+impl Drop for GlobalSocketHandle {
+    fn drop(&mut self) {
+        let mut socket_set_guard = SOCKET_SET.lock();
+        socket_set_guard.remove(self.0); // 删除的时候,会发送一条FINISH的信息?
+        drop(socket_set_guard);
+    }
+}
+
+/// @brief socket的类型
+#[derive(Debug)]
+pub enum SocketType {
+    /// 原始的socket
+    RawSocket,
+    /// 用于Tcp通信的 Socket
+    TcpSocket,
+    /// 用于Udp通信的 Socket
+    UdpSocket,
+}
+
+bitflags! {
+    /// @brief socket的选项
+    #[derive(Default)]
+    pub struct SocketOptions: u32 {
+        /// 是否阻塞
+        const BLOCK = 1 << 0;
+        /// 是否允许广播
+        const BROADCAST = 1 << 1;
+        /// 是否允许多播
+        const MULTICAST = 1 << 2;
+        /// 是否允许重用地址
+        const REUSEADDR = 1 << 3;
+        /// 是否允许重用端口
+        const REUSEPORT = 1 << 4;
+    }
+}
+
+#[derive(Debug)]
+/// @brief 在trait Socket的metadata函数中返回该结构体供外部使用
+pub struct SocketMetadata {
+    /// socket的类型
+    socket_type: SocketType,
+    /// 发送缓冲区的大小
+    send_buf_size: usize,
+    /// 接收缓冲区的大小
+    recv_buf_size: usize,
+    /// 元数据的缓冲区的大小
+    metadata_buf_size: usize,
+    /// socket的选项
+    options: SocketOptions,
+}
+
+/// @brief 表示原始的socket。原始套接字绕过传输层协议(如 TCP 或 UDP)并提供对网络层协议(如 IP)的直接访问。
+///
+/// ref: https://man7.org/linux/man-pages/man7/raw.7.html
+#[derive(Debug, Clone)]
+pub struct RawSocket {
+    handle: GlobalSocketHandle,
+    /// 用户发送的数据包是否包含了IP头.
+    /// 如果是true,用户发送的数据包,必须包含IP头。(即用户要自行设置IP头+数据)
+    /// 如果是false,用户发送的数据包,不包含IP头。(即用户只要设置数据)
+    header_included: bool,
+    /// socket的选项
+    options: SocketOptions,
+}
+
+impl RawSocket {
+    /// 元数据的缓冲区的大小
+    pub const DEFAULT_METADATA_BUF_SIZE: usize = 1024;
+    /// 默认的发送缓冲区的大小 transmiss
+    pub const DEFAULT_RX_BUF_SIZE: usize = 64 * 1024;
+    /// 默认的接收缓冲区的大小 receive
+    pub const DEFAULT_TX_BUF_SIZE: usize = 64 * 1024;
+
+    /// @brief 创建一个原始的socket
+    ///
+    /// @param protocol 协议号
+    /// @param options socket的选项
+    ///
+    /// @return 返回创建的原始的socket
+    pub fn new(protocol: Protocol, options: SocketOptions) -> Self {
+        let tx_buffer = raw::PacketBuffer::new(
+            vec![raw::PacketMetadata::EMPTY; Self::DEFAULT_METADATA_BUF_SIZE],
+            vec![0; Self::DEFAULT_TX_BUF_SIZE],
+        );
+        let rx_buffer = raw::PacketBuffer::new(
+            vec![raw::PacketMetadata::EMPTY; Self::DEFAULT_METADATA_BUF_SIZE],
+            vec![0; Self::DEFAULT_RX_BUF_SIZE],
+        );
+        let protocol: u8 = protocol.into();
+        let socket = raw::Socket::new(
+            smoltcp::wire::IpVersion::Ipv4,
+            IpProtocol::from(protocol),
+            tx_buffer,
+            rx_buffer,
+        );
+
+        // 把socket添加到socket集合中,并得到socket的句柄
+        let handle: GlobalSocketHandle = GlobalSocketHandle::new(SOCKET_SET.lock().add(socket));
+
+        return Self {
+            handle,
+            header_included: false,
+            options,
+        };
+    }
+}
+
+impl Socket for RawSocket {
+    fn read(&self, buf: &mut [u8]) -> Result<(usize, Endpoint), SystemError> {
+        loop {
+            // 如何优化这里?
+            let mut socket_set_guard = SOCKET_SET.lock();
+            let socket = socket_set_guard.get_mut::<raw::Socket>(self.handle.0);
+
+            match socket.recv_slice(buf) {
+                Ok(len) => {
+                    let packet = Ipv4Packet::new_unchecked(buf);
+                    return Ok((
+                        len,
+                        Endpoint::Ip(smoltcp::wire::IpEndpoint {
+                            addr: IpAddress::Ipv4(packet.src_addr()),
+                            port: 0,
+                        }),
+                    ));
+                }
+                Err(smoltcp::socket::raw::RecvError::Exhausted) => {
+                    if !self.options.contains(SocketOptions::BLOCK) {
+                        // 如果是非阻塞的socket,就返回错误
+                        return Err(SystemError::EAGAIN);
+                    }
+                }
+            }
+            drop(socket);
+            drop(socket_set_guard);
+        }
+    }
+
+    fn write(&self, buf: &[u8], to: Option<super::Endpoint>) -> Result<usize, SystemError> {
+        // 如果用户发送的数据包,包含IP头,则直接发送
+        if self.header_included {
+            let mut socket_set_guard = SOCKET_SET.lock();
+            let socket = socket_set_guard.get_mut::<raw::Socket>(self.handle.0);
+            match socket.send_slice(buf) {
+                Ok(_len) => {
+                    return Ok(buf.len());
+                }
+                Err(smoltcp::socket::raw::SendError::BufferFull) => {
+                    return Err(SystemError::ENOBUFS);
+                }
+            }
+        } else {
+            // 如果用户发送的数据包,不包含IP头,则需要自己构造IP头
+
+            if let Some(Endpoint::Ip(endpoint)) = to {
+                let mut socket_set_guard = SOCKET_SET.lock();
+                let socket: &mut raw::Socket =
+                    socket_set_guard.get_mut::<raw::Socket>(self.handle.0);
+
+                // 暴力解决方案:只考虑0号网卡。 TODO:考虑多网卡的情况!!!
+                let iface = NET_DRIVERS.read().get(&0).unwrap().clone();
+
+                // 构造IP头
+                let ipv4_src_addr: Option<smoltcp::wire::Ipv4Address> =
+                    iface.inner_iface().lock().ipv4_addr();
+                if ipv4_src_addr.is_none() {
+                    return Err(SystemError::ENETUNREACH);
+                }
+                let ipv4_src_addr = ipv4_src_addr.unwrap();
+
+                if let IpAddress::Ipv4(ipv4_dst) = endpoint.addr {
+                    let len = buf.len();
+
+                    // 创建20字节的IPv4头部
+                    let mut buffer: Vec<u8> = vec![0u8; len + 20];
+                    let mut packet: Ipv4Packet<&mut Vec<u8>> =
+                        Ipv4Packet::new_unchecked(&mut buffer);
+
+                    // 封装ipv4 header
+                    packet.set_version(4);
+                    packet.set_header_len(20);
+                    packet.set_total_len((20 + len) as u16);
+                    packet.set_src_addr(ipv4_src_addr);
+                    packet.set_dst_addr(ipv4_dst);
+
+                    // 设置ipv4 header的protocol字段
+                    packet.set_next_header(socket.ip_protocol().into());
+
+                    // 获取IP数据包的负载字段
+                    let payload: &mut [u8] = packet.payload_mut();
+                    payload.copy_from_slice(buf);
+
+                    // 填充checksum字段
+                    packet.fill_checksum();
+
+                    // 发送数据包
+                    socket.send_slice(&buffer).unwrap();
+
+                    drop(socket);
+                    drop(socket_set_guard);
+
+                    // poll?
+                    return Ok(len);
+                } else {
+                    kwarn!("Unsupport Ip protocol type!");
+                    return Err(SystemError::EINVAL);
+                }
+            } else {
+                // 如果没有指定目的地址,则返回错误
+                return Err(SystemError::ENOTCONN);
+            }
+        }
+    }
+
+    fn connect(&mut self, _endpoint: super::Endpoint) -> Result<(), SystemError> {
+        return Ok(());
+    }
+
+    fn metadata(&self) -> Result<SocketMetadata, SystemError> {
+        todo!()
+    }
+
+    fn box_clone(&self) -> alloc::boxed::Box<dyn Socket> {
+        return Box::new(self.clone());
+    }
+}
+
+/// @brief 表示udp socket
+///
+/// https://man7.org/linux/man-pages/man7/udp.7.html
+#[derive(Debug, Clone)]
+pub struct UdpSocket {
+    pub handle: GlobalSocketHandle,
+    remote_endpoint: Option<Endpoint>, // 记录远程endpoint提供给connect(), 应该使用IP地址。
+    options: SocketOptions,
+}
+
+impl UdpSocket {
+    /// 元数据的缓冲区的大小
+    pub const DEFAULT_METADATA_BUF_SIZE: usize = 1024;
+    /// 默认的发送缓冲区的大小 transmiss
+    pub const DEFAULT_RX_BUF_SIZE: usize = 64 * 1024;
+    /// 默认的接收缓冲区的大小 receive
+    pub const DEFAULT_TX_BUF_SIZE: usize = 64 * 1024;
+
+    /// @brief 创建一个原始的socket
+    ///
+    /// @param protocol 协议号
+    /// @param options socket的选项
+    ///
+    /// @return 返回创建的原始的socket
+    pub fn new(options: SocketOptions) -> Self {
+        let tx_buffer = udp::PacketBuffer::new(
+            vec![udp::PacketMetadata::EMPTY; Self::DEFAULT_METADATA_BUF_SIZE],
+            vec![0; Self::DEFAULT_TX_BUF_SIZE],
+        );
+        let rx_buffer = udp::PacketBuffer::new(
+            vec![udp::PacketMetadata::EMPTY; Self::DEFAULT_METADATA_BUF_SIZE],
+            vec![0; Self::DEFAULT_RX_BUF_SIZE],
+        );
+        let socket = udp::Socket::new(tx_buffer, rx_buffer);
+
+        // 把socket添加到socket集合中,并得到socket的句柄
+        let handle: GlobalSocketHandle = GlobalSocketHandle::new(SOCKET_SET.lock().add(socket));
+
+        return Self {
+            handle,
+            remote_endpoint: None,
+            options,
+        };
+    }
+}
+
+impl Socket for UdpSocket {
+    /// @brief 在read函数执行之前,请先bind到本地的指定端口
+    fn read(&self, buf: &mut [u8]) -> Result<(usize, Endpoint), SystemError> {
+        loop {
+            kdebug!("Wait22 to Read");
+
+            let mut socket_set_guard = SOCKET_SET.lock();
+            let socket = socket_set_guard.get_mut::<udp::Socket>(self.handle.0);
+
+            kdebug!("Wait to Read");
+
+            if socket.can_recv() {
+                kdebug!("Can Receive");
+                if let Ok((size, endpoint)) = socket.recv_slice(buf) {
+                    drop(socket);
+                    drop(socket_set_guard);
+
+                    return Ok((size, Endpoint::Ip(endpoint)));
+                }
+            } else {
+                // 没有数据可以读取. 如果没有bind到指定端口,也会导致rx_buf为空
+                return Err(SystemError::EAGAIN);
+            }
+        }
+    }
+
+    fn write(&self, buf: &[u8], to: Option<super::Endpoint>) -> Result<usize, SystemError> {
+        let endpoint: &IpEndpoint = {
+            if let Some(Endpoint::Ip(ref endpoint)) = to {
+                endpoint
+            } else if let Some(Endpoint::Ip(ref endpoint)) = self.remote_endpoint {
+                endpoint
+            } else {
+                return Err(SystemError::ENOTCONN);
+            }
+        };
+
+        let mut socket_set_guard = SOCKET_SET.lock();
+        let socket = socket_set_guard.get_mut::<udp::Socket>(self.handle.0);
+
+        if socket.endpoint().port == 0 {
+            let temp_port = get_ephemeral_port();
+
+            match endpoint.addr {
+                // 远程remote endpoint使用什么协议,发送的时候使用的协议是一样的吧
+                // 否则就用 self.endpoint().addr.unwrap()
+                IpAddress::Ipv4(_) => {
+                    socket
+                        .bind(IpEndpoint::new(
+                            smoltcp::wire::IpAddress::Ipv4(Ipv4Address::UNSPECIFIED),
+                            temp_port,
+                        ))
+                        .unwrap();
+                }
+                IpAddress::Ipv6(_) => {
+                    socket
+                        .bind(IpEndpoint::new(
+                            smoltcp::wire::IpAddress::Ipv6(Ipv6Address::UNSPECIFIED),
+                            temp_port,
+                        ))
+                        .unwrap();
+                }
+            }
+        }
+
+        return if socket.can_send() {
+            match socket.send_slice(&buf, *endpoint) {
+                Ok(()) => {
+                    // avoid deadlock
+                    drop(socket);
+                    drop(socket_set_guard);
+
+                    Ok(buf.len())
+                }
+                Err(_) => Err(SystemError::ENOBUFS),
+            }
+        } else {
+            Err(SystemError::ENOBUFS)
+        };
+    }
+
+    fn bind(&self, endpoint: Endpoint) -> Result<(), SystemError> {
+        let mut sockets = SOCKET_SET.lock();
+        let socket = sockets.get_mut::<udp::Socket>(self.handle.0);
+
+        return if let Endpoint::Ip(ip) = endpoint {
+            match socket.bind(ip) {
+                Ok(()) => Ok(()),
+                Err(_) => Err(SystemError::EINVAL),
+            }
+        } else {
+            Err(SystemError::EINVAL)
+        };
+    }
+
+    /// @brief
+    fn connect(&mut self, endpoint: super::Endpoint) -> Result<(), SystemError> {
+        return if let Endpoint::Ip(_) = endpoint {
+            self.remote_endpoint = Some(endpoint);
+            Ok(())
+        } else {
+            Err(SystemError::EINVAL)
+        };
+    }
+
+    fn metadata(&self) -> Result<SocketMetadata, SystemError> {
+        todo!()
+    }
+
+    fn box_clone(&self) -> alloc::boxed::Box<dyn Socket> {
+        return Box::new(self.clone());
+    }
+}
+
+/// @brief 表示 tcp socket
+///
+/// https://man7.org/linux/man-pages/man7/tcp.7.html
+#[derive(Debug, Clone)]
+pub struct TcpSocket {
+    handle: GlobalSocketHandle,
+    local_endpoint: Option<IpEndpoint>, // save local endpoint for bind()
+    is_listening: bool,
+    options: SocketOptions,
+}
+
+impl TcpSocket {
+    /// 元数据的缓冲区的大小
+    pub const DEFAULT_METADATA_BUF_SIZE: usize = 1024;
+    /// 默认的发送缓冲区的大小 transmiss
+    pub const DEFAULT_RX_BUF_SIZE: usize = 64 * 1024;
+    /// 默认的接收缓冲区的大小 receive
+    pub const DEFAULT_TX_BUF_SIZE: usize = 64 * 1024;
+
+    /// @brief 创建一个原始的socket
+    ///
+    /// @param protocol 协议号
+    /// @param options socket的选项
+    ///
+    /// @return 返回创建的原始的socket
+    pub fn new(options: SocketOptions) -> Self {
+        let tx_buffer = tcp::SocketBuffer::new(vec![0; Self::DEFAULT_TX_BUF_SIZE]);
+        let rx_buffer = tcp::SocketBuffer::new(vec![0; Self::DEFAULT_RX_BUF_SIZE]);
+        let socket = tcp::Socket::new(tx_buffer, rx_buffer);
+
+        // 把socket添加到socket集合中,并得到socket的句柄
+        let handle: GlobalSocketHandle = GlobalSocketHandle::new(SOCKET_SET.lock().add(socket));
+
+        return Self {
+            handle,
+            local_endpoint: None,
+            is_listening: false,
+            options,
+        };
+    }
+}
+
+impl Socket for TcpSocket {
+    /// @breif
+    fn read(&self, buf: &mut [u8]) -> Result<(usize, Endpoint), SystemError> {
+        loop {
+            let mut socket_set_guard = SOCKET_SET.lock();
+            let socket = socket_set_guard.get_mut::<tcp::Socket>(self.handle.0);
+
+            if socket.may_recv() {
+                if let Ok(size) = socket.recv_slice(buf) {
+                    if size > 0 {
+                        let endpoint = if let Some(p) = socket.remote_endpoint() {
+                            p
+                        } else {
+                            return Err(SystemError::ENOTCONN);
+                        };
+
+                        drop(socket);
+                        drop(socket_set_guard);
+
+                        return Ok((size, Endpoint::Ip(endpoint)));
+                    }
+                }
+            } else {
+                return Err(SystemError::EAGAIN);
+            }
+        }
+    }
+
+    fn write(&self, buf: &[u8], _to: Option<super::Endpoint>) -> Result<usize, SystemError> {
+        let mut socket_set_guard = SOCKET_SET.lock();
+        let socket = socket_set_guard.get_mut::<tcp::Socket>(self.handle.0);
+
+        if socket.is_open() {
+            if socket.can_send() {
+                match socket.send_slice(buf) {
+                    Ok(size) => {
+                        drop(socket);
+                        drop(socket_set_guard);
+
+                        return Ok(size);
+                    }
+                    Err(e) => {
+                        kerror!("Tcp Socket Write Error {e:?}");
+                        return Err(SystemError::ENOBUFS);
+                    }
+                }
+            } else {
+                return Err(SystemError::ENOBUFS);
+            }
+        }
+
+        return Err(SystemError::ENOTCONN);
+    }
+
+    fn connect(&mut self, _endpoint: super::Endpoint) -> Result<(), SystemError> {
+        // let mut sockets = SOCKET_SET.lock();
+        // let mut socket = sockets.get::<tcp::Socket>(self.handle.0);
+
+        // if let Endpoint::Ip(ip) = endpoint {
+        //     let temp_port = if ip.port == 0 {
+        //         get_ephemeral_port()
+        //     } else {
+        //         ip.port
+        //     };
+
+        //     return match socket.connect(iface.context(), temp_port) {
+        //         Ok(()) => {
+        //             // avoid deadlock
+        //             drop(socket);
+        //             drop(sockets);
+
+        //             // wait for connection result
+        //             loop {
+        //                 // poll_ifaces();
+
+        //                 let mut sockets = SOCKET_SET.lock();
+        //                 let socket = sockets.get::<tcp::Socket>(self.handle.0);
+        //                 match socket.state() {
+        //                     State::SynSent => {
+        //                         // still connecting
+        //                         drop(socket);
+        //                         kdebug!("poll for connection wait");
+        //                         // SOCKET_ACTIVITY.wait(sockets);
+        //                     }
+        //                     State::Established => {
+        //                         break Ok(());
+        //                     }
+        //                     _ => {
+        //                         break Err(SystemError::ECONNREFUSED);
+        //                     }
+        //                 }
+        //             }
+        //         }
+        //         Err(_) => Err(SystemError::ENOBUFS),
+        //     };
+        // } else {
+        //     return Err(SystemError::EINVAL);
+        // }
+        return Err(SystemError::EINVAL);
+    }
+
+    /// @brief tcp socket 监听 local_endpoint 端口
+    fn listen(&mut self, _backlog: usize) -> Result<(), SystemError> {
+        if self.is_listening {
+            return Ok(());
+        }
+
+        let local_endpoint = self.local_endpoint.ok_or(SystemError::EINVAL)?;
+        let mut sockets = SOCKET_SET.lock();
+        let socket = sockets.get_mut::<tcp::Socket>(self.handle.0);
+
+        if socket.is_listening() {
+            return Ok(());
+        }
+
+        return match socket.listen(local_endpoint) {
+            Ok(()) => {
+                self.is_listening = true;
+                Ok(())
+            }
+            Err(_) => Err(SystemError::EINVAL),
+        };
+    }
+
+    fn metadata(&self) -> Result<SocketMetadata, SystemError> {
+        todo!()
+    }
+
+    fn box_clone(&self) -> alloc::boxed::Box<dyn Socket> {
+        return Box::new(self.clone());
+    }
+}
+
+/// @breif 自动分配一个未被使用的PORT
+pub fn get_ephemeral_port() -> u16 {
+    // TODO selects non-conflict high port
+    static mut EPHEMERAL_PORT: u16 = 0;
+    unsafe {
+        if EPHEMERAL_PORT == 0 {
+            EPHEMERAL_PORT = (49152 + rand() % (65536 - 49152)) as u16;
+        }
+        if EPHEMERAL_PORT == 65535 {
+            EPHEMERAL_PORT = 49152;
+        } else {
+            EPHEMERAL_PORT = EPHEMERAL_PORT + 1;
+        }
+        EPHEMERAL_PORT
+    }
+}

+ 7 - 6
kernel/src/process/process.c

@@ -544,7 +544,7 @@ ul initial_kernel_thread(ul arg)
     // block_io_scheduler_init();
     ahci_init();
     mount_root_fs();
-    c_virtio_probe();
+    rs_virtio_probe();
     // 使用单独的内核线程来初始化usb驱动程序
     // 注释:由于目前usb驱动程序不完善,因此先将其注释掉
     // int usb_pid = kernel_thread(usb_init, 0, 0);
@@ -560,11 +560,12 @@ ul initial_kernel_thread(ul arg)
     // __test_completion();
 
     // // 对一些组件进行单元测试
-    // uint64_t tpid[] = {
-    //     ktest_start(ktest_test_bitree, 0), ktest_start(ktest_test_kfifo, 0), ktest_start(ktest_test_mutex, 0),
-    //     ktest_start(ktest_test_idr, 0),
-    //     // usb_pid,
-    // };
+    uint64_t tpid[] = {
+        // ktest_start(ktest_test_bitree, 0), ktest_start(ktest_test_kfifo, 0), ktest_start(ktest_test_mutex, 0),
+        // ktest_start(ktest_test_idr, 0),
+        // usb_pid,
+    };
+
     // kinfo("Waiting test thread exit...");
     // // 等待测试进程退出
     // for (int i = 0; i < sizeof(tpid) / sizeof(uint64_t); ++i)

+ 0 - 1
kernel/src/syscall/mod.rs

@@ -1,4 +1,3 @@
-
 use num_traits::{FromPrimitive, ToPrimitive};
 
 #[repr(i32)]

+ 334 - 0
kernel/src/time/mod.rs

@@ -1,7 +1,23 @@
+use core::{fmt, ops};
+
+use self::timekeep::ktime_get_real_ns;
+
 pub mod sleep;
 pub mod timekeep;
 pub mod timer;
 
+/* Time structures. (Partitially taken from smoltcp)
+
+The `time` module contains structures used to represent both
+absolute and relative time.
+
+ - [Instant] is used to represent absolute time.
+ - [Duration] is used to represent relative time.
+
+[Instant]: struct.Instant.html
+[Duration]: struct.Duration.html
+*/
+
 /// 表示时间的结构体
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
 pub struct TimeSpec {
@@ -10,6 +26,7 @@ pub struct TimeSpec {
 }
 
 impl TimeSpec {
+    #[allow(dead_code)]
     pub fn new(sec: i64, nsec: i64) -> TimeSpec {
         return TimeSpec {
             tv_sec: sec,
@@ -17,3 +34,320 @@ impl TimeSpec {
         };
     }
 }
+
+/// A representation of an absolute time value.
+///
+/// The `Instant` type is a wrapper around a `i64` value that
+/// represents a number of microseconds, monotonically increasing
+/// since an arbitrary moment in time, such as system startup.
+///
+/// * A value of `0` is inherently arbitrary.
+/// * A value less than `0` indicates a time before the starting
+///   point.
+#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
+#[cfg_attr(feature = "defmt", derive(defmt::Format))]
+pub struct Instant {
+    micros: i64,
+}
+
+#[allow(dead_code)]
+impl Instant {
+    pub const ZERO: Instant = Instant::from_micros_const(0);
+
+    /// Create a new `Instant` from a number of microseconds.
+    pub fn from_micros<T: Into<i64>>(micros: T) -> Instant {
+        Instant {
+            micros: micros.into(),
+        }
+    }
+
+    pub const fn from_micros_const(micros: i64) -> Instant {
+        Instant { micros }
+    }
+
+    /// Create a new `Instant` from a number of milliseconds.
+    pub fn from_millis<T: Into<i64>>(millis: T) -> Instant {
+        Instant {
+            micros: millis.into() * 1000,
+        }
+    }
+
+    /// Create a new `Instant` from a number of milliseconds.
+    pub const fn from_millis_const(millis: i64) -> Instant {
+        Instant {
+            micros: millis * 1000,
+        }
+    }
+
+    /// Create a new `Instant` from a number of seconds.
+    pub fn from_secs<T: Into<i64>>(secs: T) -> Instant {
+        Instant {
+            micros: secs.into() * 1000000,
+        }
+    }
+
+    /// Create a new `Instant` from the current time
+    pub fn now() -> Instant {
+        Self::from_micros(ktime_get_real_ns() / 1000)
+    }
+
+    /// The fractional number of milliseconds that have passed
+    /// since the beginning of time.
+    pub const fn millis(&self) -> i64 {
+        self.micros % 1000000 / 1000
+    }
+
+    /// The fractional number of microseconds that have passed
+    /// since the beginning of time.
+    pub const fn micros(&self) -> i64 {
+        self.micros % 1000000
+    }
+
+    /// The number of whole seconds that have passed since the
+    /// beginning of time.
+    pub const fn secs(&self) -> i64 {
+        self.micros / 1000000
+    }
+
+    /// The total number of milliseconds that have passed since
+    /// the beginning of time.
+    pub const fn total_millis(&self) -> i64 {
+        self.micros / 1000
+    }
+    /// The total number of milliseconds that have passed since
+    /// the beginning of time.
+    pub const fn total_micros(&self) -> i64 {
+        self.micros
+    }
+}
+
+impl fmt::Display for Instant {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}.{:0>3}s", self.secs(), self.millis())
+    }
+}
+
+impl ops::Add<Duration> for Instant {
+    type Output = Instant;
+
+    fn add(self, rhs: Duration) -> Instant {
+        Instant::from_micros(self.micros + rhs.total_micros() as i64)
+    }
+}
+
+impl ops::AddAssign<Duration> for Instant {
+    fn add_assign(&mut self, rhs: Duration) {
+        self.micros += rhs.total_micros() as i64;
+    }
+}
+
+impl ops::Sub<Duration> for Instant {
+    type Output = Instant;
+
+    fn sub(self, rhs: Duration) -> Instant {
+        Instant::from_micros(self.micros - rhs.total_micros() as i64)
+    }
+}
+
+impl ops::SubAssign<Duration> for Instant {
+    fn sub_assign(&mut self, rhs: Duration) {
+        self.micros -= rhs.total_micros() as i64;
+    }
+}
+
+impl ops::Sub<Instant> for Instant {
+    type Output = Duration;
+
+    fn sub(self, rhs: Instant) -> Duration {
+        Duration::from_micros((self.micros - rhs.micros).unsigned_abs())
+    }
+}
+
+/// A relative amount of time.
+#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
+#[cfg_attr(feature = "defmt", derive(defmt::Format))]
+pub struct Duration {
+    micros: u64,
+}
+
+impl Duration {
+    pub const ZERO: Duration = Duration::from_micros(0);
+    /// Create a new `Duration` from a number of microseconds.
+    pub const fn from_micros(micros: u64) -> Duration {
+        Duration { micros }
+    }
+
+    /// Create a new `Duration` from a number of milliseconds.
+    pub const fn from_millis(millis: u64) -> Duration {
+        Duration {
+            micros: millis * 1000,
+        }
+    }
+
+    /// Create a new `Instant` from a number of seconds.
+    pub const fn from_secs(secs: u64) -> Duration {
+        Duration {
+            micros: secs * 1000000,
+        }
+    }
+
+    /// The fractional number of milliseconds in this `Duration`.
+    pub const fn millis(&self) -> u64 {
+        self.micros / 1000 % 1000
+    }
+
+    /// The fractional number of milliseconds in this `Duration`.
+    pub const fn micros(&self) -> u64 {
+        self.micros % 1000000
+    }
+
+    /// The number of whole seconds in this `Duration`.
+    pub const fn secs(&self) -> u64 {
+        self.micros / 1000000
+    }
+
+    /// The total number of milliseconds in this `Duration`.
+    pub const fn total_millis(&self) -> u64 {
+        self.micros / 1000
+    }
+
+    /// The total number of microseconds in this `Duration`.
+    pub const fn total_micros(&self) -> u64 {
+        self.micros
+    }
+}
+
+impl fmt::Display for Duration {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}.{:03}s", self.secs(), self.millis())
+    }
+}
+
+impl ops::Add<Duration> for Duration {
+    type Output = Duration;
+
+    fn add(self, rhs: Duration) -> Duration {
+        Duration::from_micros(self.micros + rhs.total_micros())
+    }
+}
+
+impl ops::AddAssign<Duration> for Duration {
+    fn add_assign(&mut self, rhs: Duration) {
+        self.micros += rhs.total_micros();
+    }
+}
+
+impl ops::Sub<Duration> for Duration {
+    type Output = Duration;
+
+    fn sub(self, rhs: Duration) -> Duration {
+        Duration::from_micros(
+            self.micros
+                .checked_sub(rhs.total_micros())
+                .expect("overflow when subtracting durations"),
+        )
+    }
+}
+
+impl ops::SubAssign<Duration> for Duration {
+    fn sub_assign(&mut self, rhs: Duration) {
+        self.micros = self
+            .micros
+            .checked_sub(rhs.total_micros())
+            .expect("overflow when subtracting durations");
+    }
+}
+
+impl ops::Mul<u32> for Duration {
+    type Output = Duration;
+
+    fn mul(self, rhs: u32) -> Duration {
+        Duration::from_micros(self.micros * rhs as u64)
+    }
+}
+
+impl ops::MulAssign<u32> for Duration {
+    fn mul_assign(&mut self, rhs: u32) {
+        self.micros *= rhs as u64;
+    }
+}
+
+impl ops::Div<u32> for Duration {
+    type Output = Duration;
+
+    fn div(self, rhs: u32) -> Duration {
+        Duration::from_micros(self.micros / rhs as u64)
+    }
+}
+
+impl ops::DivAssign<u32> for Duration {
+    fn div_assign(&mut self, rhs: u32) {
+        self.micros /= rhs as u64;
+    }
+}
+
+impl ops::Shl<u32> for Duration {
+    type Output = Duration;
+
+    fn shl(self, rhs: u32) -> Duration {
+        Duration::from_micros(self.micros << rhs)
+    }
+}
+
+impl ops::ShlAssign<u32> for Duration {
+    fn shl_assign(&mut self, rhs: u32) {
+        self.micros <<= rhs;
+    }
+}
+
+impl ops::Shr<u32> for Duration {
+    type Output = Duration;
+
+    fn shr(self, rhs: u32) -> Duration {
+        Duration::from_micros(self.micros >> rhs)
+    }
+}
+
+impl ops::ShrAssign<u32> for Duration {
+    fn shr_assign(&mut self, rhs: u32) {
+        self.micros >>= rhs;
+    }
+}
+
+impl From<::core::time::Duration> for Duration {
+    fn from(other: ::core::time::Duration) -> Duration {
+        Duration::from_micros(other.as_secs() * 1000000 + other.subsec_micros() as u64)
+    }
+}
+
+impl From<Duration> for ::core::time::Duration {
+    fn from(val: Duration) -> Self {
+        ::core::time::Duration::from_micros(val.total_micros())
+    }
+}
+
+/// 支持与smoltcp的时间转换
+impl From<smoltcp::time::Instant> for Instant {
+    fn from(val: smoltcp::time::Instant) -> Self {
+        Instant::from_micros(val.micros())
+    }
+}
+
+impl Into<smoltcp::time::Instant> for Instant {
+    fn into(self) -> smoltcp::time::Instant {
+        smoltcp::time::Instant::from_millis(self.millis())
+    }
+}
+
+/// 支持与smoltcp的时间转换
+impl From<smoltcp::time::Duration> for Duration {
+    fn from(val: smoltcp::time::Duration) -> Self {
+        Duration::from_micros(val.micros())
+    }
+}
+
+impl Into<smoltcp::time::Duration> for Duration {
+    fn into(self) -> smoltcp::time::Duration {
+        smoltcp::time::Duration::from_millis(self.millis())
+    }
+}

+ 27 - 0
tools/configure_network.sh

@@ -0,0 +1,27 @@
+# Replace with your wired Ethernet interface name
+ETH=eno1
+
+sudo modprobe bridge
+sudo modprobe br_netfilter
+
+sudo sysctl -w net.bridge.bridge-nf-call-arptables=0
+sudo sysctl -w net.bridge.bridge-nf-call-ip6tables=0
+sudo sysctl -w net.bridge.bridge-nf-call-iptables=0
+
+sudo ip tuntap add name tap0 mode tap user $USER
+sudo brctl addbr br0
+sudo brctl addif br0 tap0
+sudo brctl addif br0 $ETH
+sudo ip link set tap0 up
+sudo ip link set $ETH up
+sudo ip link set br0 up
+
+
+# This connects your host system to the internet, so you can use it
+# at the same time you run the examples.
+sudo dhcpcd br0
+
+sudo mkdir -p /usr/local/etc/qemu
+sudo mkdir -p /etc/qemu
+sudo sh -c 'echo "allow br0" > /usr/local/etc/qemu/bridge.conf'
+sudo sh -c 'echo "allow br0" > /etc/qemu/bridge.conf'

+ 2 - 2
tools/run-qemu.sh

@@ -6,7 +6,7 @@ echo "$@"
 allflags=$(qemu-system-x86_64 -cpu help | awk '/flags/ {y=1; getline}; y {print}' | tr ' ' '\n' | grep -Ev "^$" | sed -r 's|^|+|' | tr '\n' ',' | sed -r "s|,$||")
 ARCH="x86_64"
 #ARCH="i386"
-# 请根据自己的需要,在-d 后方加入所需的trace事件
+# 请根据自己的需要,在-d 后方加入所需的 trace 事件
 
 # 标准的trace events
 qemu_trace_std=cpu_reset,guest_errors,exec,cpu,trace:virtio*
@@ -29,7 +29,7 @@ QEMU_RTC_CLOCK="clock=host,base=localtime"
 QEMU_SERIAL="file:../serial_opt.txt"
 QEMU_DRIVE="id=disk,file=${QEMU_DISK_IMAGE},if=none"
 
-QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -nic user,model=virtio  -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel}"
+QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -nic user,model=virtio-net-pci -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel}"
 
 QEMU_ARGUMENT="-d ${QEMU_DISK_IMAGE} -m ${QEMU_MEMORY} -smp ${QEMU_SMP} -boot order=d -monitor ${QEMU_MONITOR} -d ${qemu_trace_std} "