Browse Source

feat(driver): 把virtio添加到sysfs (#752)

LoGin 10 months ago
parent
commit
e32effb150

+ 3 - 3
kernel/src/arch/x86_64/driver/apic/x2apic.rs

@@ -5,7 +5,7 @@ use x86::msr::{
     IA32_X2APIC_VERSION,
 };
 
-use crate::{kdebug, kinfo};
+use crate::kinfo;
 
 use super::{hw_irq::ApicId, LVTRegister, LocalAPIC, LVT};
 
@@ -55,9 +55,9 @@ impl LocalAPIC for X2Apic {
                     kinfo!("x2APIC EOI broadcast suppression enabled.");
                 }
             }
-            kdebug!("x2apic: to mask all lvt");
+            // kdebug!("x2apic: to mask all lvt");
             self.mask_all_lvt();
-            kdebug!("x2apic: all lvt masked");
+            // kdebug!("x2apic: all lvt masked");
         }
         true
     }

+ 3 - 3
kernel/src/driver/base/device/bus.rs

@@ -147,12 +147,12 @@ pub trait Bus: Debug + Send + Sync {
 
     fn resume(&self, device: &Arc<dyn Device>) -> Result<(), SystemError>;
 
-    /// match platform device to platform driver.
+    /// match device to driver.
     ///
     /// ## 参数
     ///
-    /// * `device` - platform device
-    /// * `driver` - platform driver
+    /// * `device` - device
+    /// * `driver` - driver
     ///
     /// ## 返回
     ///

+ 7 - 2
kernel/src/driver/base/device/dd.rs

@@ -180,7 +180,7 @@ impl DeviceManager {
     ///
     /// 如果传递的设备已成功完成对驱动程序的探测,则返回true,否则返回false。
     pub fn device_is_bound(&self, dev: &Arc<dyn Device>) -> bool {
-        return dev.driver().is_some();
+        return driver_manager().driver_is_bound(dev);
     }
 
     /// 把一个驱动绑定到设备上
@@ -199,6 +199,11 @@ impl DeviceManager {
     pub fn device_bind_driver(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
         let r = driver_manager().driver_sysfs_add(dev);
         if let Err(e) = r {
+            kerror!(
+                "device_bind_driver: driver_sysfs_add failed, dev: '{}', err: {:?}",
+                dev.name(),
+                e
+            );
             self.device_links_force_bind(dev);
             driver_manager().driver_bound(dev);
             return Err(e);
@@ -606,7 +611,7 @@ impl Attribute for DeviceAttrStateSynced {
 }
 
 #[derive(Debug)]
-struct DeviceAttrCoredump;
+pub(super) struct DeviceAttrCoredump;
 
 impl Attribute for DeviceAttrCoredump {
     fn name(&self) -> &str {

+ 37 - 3
kernel/src/driver/base/device/driver.rs

@@ -3,10 +3,14 @@ use super::{
     Device, DeviceMatchName, DeviceMatcher, IdTable,
 };
 use crate::{
-    driver::base::kobject::KObject,
+    driver::base::{
+        device::{bus::BusNotifyEvent, dd::DeviceAttrCoredump, device_manager},
+        kobject::KObject,
+    },
     filesystem::sysfs::{sysfs_instance, Attribute, AttributeGroup},
 };
 use alloc::{
+    string::ToString,
     sync::{Arc, Weak},
     vec::Vec,
 };
@@ -226,8 +230,38 @@ impl DriverManager {
     }
 
     /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#434
-    pub fn driver_sysfs_add(&self, _dev: &Arc<dyn Device>) -> Result<(), SystemError> {
-        todo!("DriverManager::driver_sysfs_add()");
+    pub fn driver_sysfs_add(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
+        if let Some(bus) = dev.bus().and_then(|bus| bus.upgrade()) {
+            bus.subsystem()
+                .bus_notifier()
+                .call_chain(BusNotifyEvent::BindDriver, Some(dev), None);
+        }
+        let driver_kobj = dev.driver().unwrap() as Arc<dyn KObject>;
+        let device_kobj = dev.clone() as Arc<dyn KObject>;
+
+        let err_remove_device = |e| {
+            sysfs_instance().remove_link(&driver_kobj, dev.name());
+            Err(e)
+        };
+
+        let err_remove_driver = |e| {
+            sysfs_instance().remove_link(&device_kobj, "driver".to_string());
+            err_remove_device(e)
+        };
+
+        sysfs_instance().create_link(Some(&driver_kobj), &device_kobj, device_kobj.name())?;
+
+        if let Err(e) =
+            sysfs_instance().create_link(Some(&device_kobj), &driver_kobj, "driver".to_string())
+        {
+            return err_remove_device(e);
+        }
+
+        if let Err(e) = device_manager().create_file(dev, &DeviceAttrCoredump) {
+            return err_remove_driver(e);
+        }
+
+        return Ok(());
     }
 
     pub fn add_groups(

+ 5 - 0
kernel/src/driver/base/subsys.rs

@@ -22,6 +22,7 @@ use super::{
         driver::Driver,
         Device,
     },
+    kobject::KObject,
     kset::KSet,
 };
 
@@ -82,6 +83,10 @@ impl SubSysPrivate {
         };
     }
 
+    pub fn name(&self) -> String {
+        return self.subsys.name();
+    }
+
     pub fn subsys(&self) -> Arc<KSet> {
         return self.subsys.clone();
     }

+ 29 - 12
kernel/src/driver/net/e1000e/e1000e_driver.rs

@@ -4,14 +4,15 @@ use crate::{
     arch::rand::rand,
     driver::{
         base::{
-            device::{bus::Bus, driver::Driver, Device, IdTable},
+            class::Class,
+            device::{bus::Bus, driver::Driver, Device, DeviceType, IdTable},
             kobject::{KObjType, KObject, KObjectState},
         },
-        net::NetDriver,
+        net::NetDevice,
     },
     kinfo,
     libs::spinlock::SpinLock,
-    net::{generate_iface_id, NET_DRIVERS},
+    net::{generate_iface_id, NET_DEVICES},
     time::Instant,
 };
 use alloc::{
@@ -205,33 +206,49 @@ impl Debug for E1000EInterface {
     }
 }
 
-impl Driver for E1000EInterface {
-    fn id_table(&self) -> Option<IdTable> {
+impl Device for E1000EInterface {
+    fn dev_type(&self) -> DeviceType {
         todo!()
     }
 
-    fn add_device(&self, _device: Arc<dyn Device>) {
+    fn id_table(&self) -> IdTable {
         todo!()
     }
 
-    fn delete_device(&self, _device: &Arc<dyn Device>) {
+    fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
         todo!()
     }
 
-    fn devices(&self) -> alloc::vec::Vec<Arc<dyn Device>> {
+    fn set_class(&self, _class: Option<Weak<dyn Class>>) {
         todo!()
     }
 
-    fn bus(&self) -> Option<Weak<dyn Bus>> {
+    fn driver(&self) -> Option<Arc<dyn Driver>> {
         todo!()
     }
 
-    fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
+    fn set_driver(&self, _driver: Option<Weak<dyn Driver>>) {
+        todo!()
+    }
+
+    fn is_dead(&self) -> bool {
+        todo!()
+    }
+
+    fn can_match(&self) -> bool {
+        todo!()
+    }
+
+    fn set_can_match(&self, _can_match: bool) {
+        todo!()
+    }
+
+    fn state_synced(&self) -> bool {
         todo!()
     }
 }
 
-impl NetDriver for E1000EInterface {
+impl NetDevice for E1000EInterface {
     fn mac(&self) -> smoltcp::wire::EthernetAddress {
         let mac = self.driver.inner.lock().mac_address();
         return smoltcp::wire::EthernetAddress::from_bytes(&mac);
@@ -347,7 +364,7 @@ pub fn e1000e_driver_init(device: E1000EDevice) {
     let driver = E1000EDriver::new(device);
     let iface = E1000EInterface::new(driver);
     // 将网卡的接口信息注册到全局的网卡接口信息表中
-    NET_DRIVERS
+    NET_DEVICES
         .write_irqsave()
         .insert(iface.nic_id(), iface.clone());
     kinfo!("e1000e driver init successfully!\tMAC: [{}]", mac);

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

@@ -4,7 +4,7 @@ use smoltcp::{
     wire::{self, EthernetAddress},
 };
 
-use super::base::device::driver::Driver;
+use super::base::device::Device;
 use crate::libs::spinlock::SpinLock;
 use system_error::SystemError;
 
@@ -13,7 +13,7 @@ pub mod e1000e;
 pub mod irq_handle;
 pub mod virtio_net;
 
-pub trait NetDriver: Driver {
+pub trait NetDevice: Device {
     /// @brief 获取网卡的MAC地址
     fn mac(&self) -> EthernetAddress;
 

+ 444 - 147
kernel/src/driver/net/virtio_net.rs

@@ -1,123 +1,206 @@
 use core::{
+    any::Any,
     cell::UnsafeCell,
     fmt::Debug,
     ops::{Deref, DerefMut},
 };
 
 use alloc::{
-    string::String,
+    string::{String, ToString},
     sync::{Arc, Weak},
+    vec::Vec,
 };
 use smoltcp::{iface, phy, wire};
-use virtio_drivers::{device::net::VirtIONet, transport::Transport};
+use unified_init::macros::unified_init;
+use virtio_drivers::device::net::VirtIONet;
 
-use super::NetDriver;
+use super::NetDevice;
 use crate::{
     arch::rand::rand,
     driver::{
         base::{
-            device::{bus::Bus, driver::Driver, Device, DeviceId, IdTable},
-            kobject::{KObjType, KObject, KObjectState},
+            class::Class,
+            device::{
+                bus::Bus,
+                driver::{Driver, DriverCommonData},
+                Device, DeviceCommonData, DeviceId, DeviceType, IdTable,
+            },
+            kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
+            kset::KSet,
+        },
+        virtio::{
+            irq::virtio_irq_manager,
+            sysfs::{virtio_bus, virtio_device_manager, virtio_driver_manager},
+            transport::VirtIOTransport,
+            virtio_impl::HalImpl,
+            VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_VENDOR_ID,
         },
-        virtio::{irq::virtio_irq_manager, virtio_impl::HalImpl, VirtIODevice},
     },
     exception::{irqdesc::IrqReturn, IrqNumber},
-    kerror, kinfo,
-    libs::spinlock::SpinLock,
-    net::{generate_iface_id, net_core::poll_ifaces_try_lock_onetime, NET_DRIVERS},
+    filesystem::kernfs::KernFSInode,
+    init::initcall::INITCALL_POSTCORE,
+    kerror,
+    libs::{
+        rwlock::{RwLockReadGuard, RwLockWriteGuard},
+        spinlock::{SpinLock, SpinLockGuard},
+    },
+    net::{generate_iface_id, net_core::poll_ifaces_try_lock_onetime, NET_DEVICES},
     time::Instant,
 };
 use system_error::SystemError;
 
-/// @brief Virtio网络设备驱动(加锁)
-pub struct VirtioNICDriver<T: Transport> {
-    pub inner: Arc<SpinLock<VirtIONet<HalImpl, T, 2>>>,
+static mut VIRTIO_NET_DRIVER: Option<Arc<VirtIONetDriver>> = None;
+
+const DEVICE_NAME: &str = "virtio_net";
+
+#[inline(always)]
+fn virtio_net_driver() -> Arc<VirtIONetDriver> {
+    unsafe { VIRTIO_NET_DRIVER.as_ref().unwrap().clone() }
 }
 
-impl<T: Transport> Clone for VirtioNICDriver<T> {
-    fn clone(&self) -> Self {
-        return VirtioNICDriver {
-            inner: self.inner.clone(),
-        };
+pub struct VirtIoNetImpl {
+    inner: VirtIONet<HalImpl, VirtIOTransport, 2>,
+}
+
+impl VirtIoNetImpl {
+    const fn new(inner: VirtIONet<HalImpl, VirtIOTransport, 2>) -> Self {
+        Self { inner }
+    }
+}
+
+impl Deref for VirtIoNetImpl {
+    type Target = VirtIONet<HalImpl, VirtIOTransport, 2>;
+    fn deref(&self) -> &Self::Target {
+        &self.inner
+    }
+}
+
+impl DerefMut for VirtIoNetImpl {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.inner
     }
 }
 
-/// 网卡驱动的包裹器,这是为了获取网卡驱动的可变引用而设计的。
-///
-/// 由于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> {}
+unsafe impl Send for VirtIoNetImpl {}
+unsafe impl Sync for VirtIoNetImpl {}
+
+#[derive(Debug)]
+struct VirtIONicDeviceInnerWrapper(UnsafeCell<VirtIONicDeviceInner>);
+unsafe impl Send for VirtIONicDeviceInnerWrapper {}
+unsafe impl Sync for VirtIONicDeviceInnerWrapper {}
 
-impl<T: Transport> Deref for VirtioNICDriverWrapper<T> {
-    type Target = VirtioNICDriver<T>;
+impl Deref for VirtIONicDeviceInnerWrapper {
+    type Target = VirtIONicDeviceInner;
     fn deref(&self) -> &Self::Target {
         unsafe { &*self.0.get() }
     }
 }
-impl<T: Transport> DerefMut for VirtioNICDriverWrapper<T> {
+impl DerefMut for VirtIONicDeviceInnerWrapper {
     fn deref_mut(&mut self) -> &mut Self::Target {
         unsafe { &mut *self.0.get() }
     }
 }
 
 #[allow(clippy::mut_from_ref)]
-impl<T: Transport> VirtioNICDriverWrapper<T> {
-    fn force_get_mut(&self) -> &mut VirtioNICDriver<T> {
+impl VirtIONicDeviceInnerWrapper {
+    fn force_get_mut(&self) -> &mut <VirtIONicDeviceInnerWrapper as Deref>::Target {
         unsafe { &mut *self.0.get() }
     }
 }
 
-impl<T: Transport> Debug for VirtioNICDriver<T> {
+/// Virtio网络设备驱动(加锁)
+pub struct VirtIONicDeviceInner {
+    pub inner: Arc<SpinLock<VirtIoNetImpl>>,
+}
+
+impl Clone for VirtIONicDeviceInner {
+    fn clone(&self) -> Self {
+        return VirtIONicDeviceInner {
+            inner: self.inner.clone(),
+        };
+    }
+}
+
+impl Debug for VirtIONicDeviceInner {
     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        f.debug_struct("VirtioNICDriver").finish()
+        f.debug_struct("VirtIONicDriver").finish()
     }
 }
 
-pub struct VirtioInterface<T: Transport> {
-    driver: VirtioNICDriverWrapper<T>,
+#[cast_to([sync] VirtIODevice)]
+pub struct VirtioInterface {
+    device_inner: VirtIONicDeviceInnerWrapper,
     iface_id: usize,
-    iface: SpinLock<iface::Interface>,
-    name: String,
+    iface_name: String,
     dev_id: Arc<DeviceId>,
+    iface: SpinLock<iface::Interface>,
+    inner: SpinLock<InnerVirtIOInterface>,
+    locked_kobj_state: LockedKObjectState,
+}
+
+#[derive(Debug)]
+struct InnerVirtIOInterface {
+    name: Option<String>,
+    virtio_index: Option<VirtIODeviceIndex>,
+    device_common: DeviceCommonData,
+    kobj_common: KObjectCommonData,
 }
 
-impl<T: Transport> Debug for VirtioInterface<T> {
+impl core::fmt::Debug for VirtioInterface {
     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)
+            .field("iface_name", &self.iface_name)
+            .field("dev_id", &self.dev_id)
+            .field("inner", &self.inner)
+            .field("locked_kobj_state", &self.locked_kobj_state)
             .finish()
     }
 }
 
-impl<T: Transport> VirtioInterface<T> {
-    pub fn new(mut driver: VirtioNICDriver<T>, dev_id: Arc<DeviceId>) -> Arc<Self> {
+impl VirtioInterface {
+    pub fn new(mut device_inner: VirtIONicDeviceInner, dev_id: Arc<DeviceId>) -> Arc<Self> {
         let iface_id = generate_iface_id();
         let mut iface_config = iface::Config::new(wire::HardwareAddress::Ethernet(
-            wire::EthernetAddress(driver.inner.lock().mac_address()),
+            wire::EthernetAddress(device_inner.inner.lock().mac_address()),
         ));
         iface_config.random_seed = rand() as u64;
 
-        let iface = iface::Interface::new(iface_config, &mut driver, Instant::now().into());
+        let iface = iface::Interface::new(iface_config, &mut device_inner, Instant::now().into());
 
-        let driver: VirtioNICDriverWrapper<T> = VirtioNICDriverWrapper(UnsafeCell::new(driver));
         let result = Arc::new(VirtioInterface {
-            driver,
+            device_inner: VirtIONicDeviceInnerWrapper(UnsafeCell::new(device_inner)),
             iface_id,
+            locked_kobj_state: LockedKObjectState::default(),
             iface: SpinLock::new(iface),
-            name: format!("eth{}", iface_id),
+            iface_name: format!("eth{}", iface_id),
             dev_id,
+            inner: SpinLock::new(InnerVirtIOInterface {
+                name: None,
+                virtio_index: None,
+                device_common: DeviceCommonData::default(),
+                kobj_common: KObjectCommonData::default(),
+            }),
         });
 
+        result.inner().device_common.driver =
+            Some(Arc::downgrade(&virtio_net_driver()) as Weak<dyn Driver>);
+
         return result;
     }
+
+    fn inner(&self) -> SpinLockGuard<InnerVirtIOInterface> {
+        return self.inner.lock();
+    }
+
+    /// 获取网卡接口的名称
+    #[allow(dead_code)]
+    pub fn iface_name(&self) -> String {
+        self.iface_name.clone()
+    }
 }
 
-impl<T: Transport + 'static> VirtIODevice for VirtioInterface<T> {
+impl VirtIODevice for VirtioInterface {
     fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError> {
         poll_ifaces_try_lock_onetime().ok();
         return Ok(IrqReturn::Handled);
@@ -126,46 +209,133 @@ impl<T: Transport + 'static> VirtIODevice for VirtioInterface<T> {
     fn dev_id(&self) -> &Arc<DeviceId> {
         return &self.dev_id;
     }
+    fn set_virtio_device_index(&self, index: VirtIODeviceIndex) {
+        self.inner().virtio_index = Some(index);
+    }
+
+    fn virtio_device_index(&self) -> Option<VirtIODeviceIndex> {
+        return self.inner().virtio_index;
+    }
+
+    fn set_device_name(&self, name: String) {
+        self.inner().name = Some(name);
+    }
+
+    fn device_name(&self) -> String {
+        self.inner()
+            .name
+            .clone()
+            .unwrap_or_else(|| "virtio_net".to_string())
+    }
+
+    fn device_type_id(&self) -> u32 {
+        virtio_drivers::transport::DeviceType::Network as u32
+    }
+
+    fn vendor(&self) -> u32 {
+        VIRTIO_VENDOR_ID.into()
+    }
 }
 
-impl<T: Transport> Drop for VirtioInterface<T> {
+impl Drop for VirtioInterface {
     fn drop(&mut self) {
         // 从全局的网卡接口信息表中删除这个网卡的接口信息
-        NET_DRIVERS.write_irqsave().remove(&self.iface_id);
+        NET_DEVICES.write_irqsave().remove(&self.iface_id);
+    }
+}
+
+impl Device for VirtioInterface {
+    fn dev_type(&self) -> DeviceType {
+        DeviceType::Net
+    }
+
+    fn id_table(&self) -> IdTable {
+        IdTable::new(DEVICE_NAME.to_string(), None)
+    }
+
+    fn bus(&self) -> Option<Weak<dyn Bus>> {
+        self.inner().device_common.bus.clone()
+    }
+
+    fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
+        self.inner().device_common.bus = bus;
+    }
+
+    fn class(&self) -> Option<Arc<dyn Class>> {
+        let mut guard = self.inner();
+        let r = guard.device_common.class.clone()?.upgrade();
+        if r.is_none() {
+            guard.device_common.class = None;
+        }
+
+        return r;
+    }
+
+    fn set_class(&self, class: Option<Weak<dyn Class>>) {
+        self.inner().device_common.class = class;
+    }
+
+    fn driver(&self) -> Option<Arc<dyn Driver>> {
+        let r = self.inner().device_common.driver.clone()?.upgrade();
+        if r.is_none() {
+            self.inner().device_common.driver = None;
+        }
+
+        return r;
+    }
+
+    fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
+        self.inner().device_common.driver = driver;
+    }
+
+    fn is_dead(&self) -> bool {
+        false
+    }
+
+    fn can_match(&self) -> bool {
+        true
+    }
+
+    fn set_can_match(&self, can_match: bool) {
+        self.inner().device_common.can_match = can_match;
+    }
+
+    fn state_synced(&self) -> bool {
+        true
     }
 }
 
-impl<T: 'static + Transport> VirtioNICDriver<T> {
-    pub fn new(driver_net: VirtIONet<HalImpl, T, 2>) -> Self {
+impl VirtIONicDeviceInner {
+    pub fn new(driver_net: VirtIONet<HalImpl, VirtIOTransport, 2>) -> Self {
         let mut iface_config = iface::Config::new(wire::HardwareAddress::Ethernet(
             wire::EthernetAddress(driver_net.mac_address()),
         ));
 
         iface_config.random_seed = rand() as u64;
 
-        let inner: Arc<SpinLock<VirtIONet<HalImpl, T, 2>>> = Arc::new(SpinLock::new(driver_net));
-        let result = VirtioNICDriver { inner };
+        let inner = Arc::new(SpinLock::new(VirtIoNetImpl::new(driver_net)));
+        let result = VirtIONicDeviceInner { inner };
         return result;
     }
 }
 
-pub struct VirtioNetToken<T: Transport> {
-    driver: VirtioNICDriver<T>,
+pub struct VirtioNetToken {
+    driver: VirtIONicDeviceInner,
     rx_buffer: Option<virtio_drivers::device::net::RxBuffer>,
 }
 
-impl<T: Transport> VirtioNetToken<T> {
+impl VirtioNetToken {
     pub fn new(
-        driver: VirtioNICDriver<T>,
+        driver: VirtIONicDeviceInner,
         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;
+impl phy::Device for VirtIONicDeviceInner {
+    type RxToken<'a> = VirtioNetToken where Self: 'a;
+    type TxToken<'a> = VirtioNetToken where Self: 'a;
 
     fn receive(
         &mut self,
@@ -206,13 +376,12 @@ impl<T: Transport> phy::Device for VirtioNICDriver<T> {
     }
 }
 
-impl<T: Transport> phy::TxToken for VirtioNetToken<T> {
+impl phy::TxToken for VirtioNetToken {
     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());
@@ -221,7 +390,7 @@ impl<T: Transport> phy::TxToken for VirtioNetToken<T> {
     }
 }
 
-impl<T: Transport> phy::RxToken for VirtioNetToken<T> {
+impl phy::RxToken for VirtioNetToken {
     fn consume<R, F>(self, f: F) -> R
     where
         F: FnOnce(&mut [u8]) -> R,
@@ -239,9 +408,9 @@ impl<T: Transport> phy::RxToken for VirtioNetToken<T> {
 }
 
 /// @brief virtio-net 驱动的初始化与测试
-pub fn virtio_net<T: Transport + 'static>(transport: T, dev_id: Arc<DeviceId>) {
-    let driver_net: VirtIONet<HalImpl, T, 2> =
-        match VirtIONet::<HalImpl, T, 2>::new(transport, 4096) {
+pub fn virtio_net(transport: VirtIOTransport, dev_id: Arc<DeviceId>) {
+    let driver_net: VirtIONet<HalImpl, VirtIOTransport, 2> =
+        match VirtIONet::<HalImpl, VirtIOTransport, 2>::new(transport, 4096) {
             Ok(net) => net,
             Err(_) => {
                 kerror!("VirtIONet init failed");
@@ -249,53 +418,17 @@ pub fn virtio_net<T: Transport + 'static>(transport: T, dev_id: Arc<DeviceId>) {
             }
         };
     let mac = wire::EthernetAddress::from_bytes(&driver_net.mac_address());
-    let driver: VirtioNICDriver<T> = VirtioNICDriver::new(driver_net);
-    let iface = VirtioInterface::new(driver, dev_id);
-    let name = iface.name.clone();
-    // 将网卡的接口信息注册到全局的网卡接口信息表中
-    NET_DRIVERS
-        .write_irqsave()
-        .insert(iface.nic_id(), iface.clone());
-
-    virtio_irq_manager()
-        .register_device(iface.clone())
-        .expect("Register virtio net failed");
-    kinfo!(
-        "Virtio-net driver init successfully!\tNetDevID: [{}], MAC: [{}]",
-        name,
-        mac
-    );
-}
-
-impl<T: Transport + 'static> Driver for VirtioInterface<T> {
-    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<Weak<dyn Bus>> {
-        todo!()
-    }
-
-    fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
-        todo!()
-    }
+    let dev_inner = VirtIONicDeviceInner::new(driver_net);
+    let iface = VirtioInterface::new(dev_inner, dev_id);
+    kdebug!("To add virtio net: {}, mac: {}", iface.device_name(), mac);
+    virtio_device_manager()
+        .device_add(iface.clone() as Arc<dyn VirtIODevice>)
+        .expect("Add virtio net failed");
 }
 
-impl<T: Transport + 'static> NetDriver for VirtioInterface<T> {
+impl NetDevice for VirtioInterface {
     fn mac(&self) -> wire::EthernetAddress {
-        let mac: [u8; 6] = self.driver.inner.lock().mac_address();
+        let mac: [u8; 6] = self.device_inner.inner.lock().mac_address();
         return wire::EthernetAddress::from_bytes(&mac);
     }
 
@@ -306,7 +439,7 @@ impl<T: Transport + 'static> NetDriver for VirtioInterface<T> {
 
     #[inline]
     fn name(&self) -> String {
-        return self.name.clone();
+        return self.iface_name.clone();
     }
 
     fn update_ip_addrs(&self, ip_addrs: &[wire::IpCidr]) -> Result<(), SystemError> {
@@ -331,7 +464,7 @@ impl<T: Transport + 'static> NetDriver for VirtioInterface<T> {
     fn poll(&self, sockets: &mut iface::SocketSet) -> Result<(), 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);
+        let poll_res = guard.poll(timestamp, self.device_inner.force_get_mut(), sockets);
         // todo: notify!!!
         // kdebug!("Virtio Interface poll:{poll_res}");
         if poll_res {
@@ -349,71 +482,235 @@ impl<T: Transport + 'static> NetDriver for VirtioInterface<T> {
     // }
 }
 
-impl<T: Transport + 'static> KObject for VirtioInterface<T> {
+impl KObject for VirtioInterface {
     fn as_any_ref(&self) -> &dyn core::any::Any {
         self
     }
 
-    fn set_inode(&self, _inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) {
-        todo!()
+    fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
+        self.inner().kobj_common.kern_inode = inode;
     }
 
-    fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> {
-        todo!()
+    fn inode(&self) -> Option<Arc<KernFSInode>> {
+        self.inner().kobj_common.kern_inode.clone()
     }
 
-    fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
-        todo!()
+    fn parent(&self) -> Option<Weak<dyn KObject>> {
+        self.inner().kobj_common.parent.clone()
     }
 
-    fn set_parent(&self, _parent: Option<alloc::sync::Weak<dyn KObject>>) {
-        todo!()
+    fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
+        self.inner().kobj_common.parent = parent;
     }
 
-    fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> {
-        todo!()
+    fn kset(&self) -> Option<Arc<KSet>> {
+        self.inner().kobj_common.kset.clone()
     }
 
-    fn set_kset(&self, _kset: Option<Arc<crate::driver::base::kset::KSet>>) {
-        todo!()
+    fn set_kset(&self, kset: Option<Arc<KSet>>) {
+        self.inner().kobj_common.kset = kset;
     }
 
-    fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> {
-        todo!()
+    fn kobj_type(&self) -> Option<&'static dyn KObjType> {
+        self.inner().kobj_common.kobj_type
     }
 
     fn name(&self) -> String {
-        self.name.clone()
+        self.device_name()
     }
 
     fn set_name(&self, _name: String) {
-        todo!()
+        // do nothing
+    }
+
+    fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
+        self.locked_kobj_state.read()
+    }
+
+    fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
+        self.locked_kobj_state.write()
     }
 
-    fn kobj_state(
-        &self,
-    ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> {
-        todo!()
+    fn set_kobj_state(&self, state: KObjectState) {
+        *self.locked_kobj_state.write() = state;
+    }
+
+    fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
+        self.inner().kobj_common.kobj_type = ktype;
+    }
+}
+
+#[unified_init(INITCALL_POSTCORE)]
+fn virtio_net_driver_init() -> Result<(), SystemError> {
+    let driver = VirtIONetDriver::new();
+    virtio_driver_manager()
+        .register(driver.clone() as Arc<dyn VirtIODriver>)
+        .expect("Add virtio net driver failed");
+    unsafe {
+        VIRTIO_NET_DRIVER = Some(driver);
     }
 
-    fn kobj_state_mut(
-        &self,
-    ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
-        todo!()
+    return Ok(());
+}
+#[derive(Debug)]
+#[cast_to([sync] VirtIODriver)]
+struct VirtIONetDriver {
+    inner: SpinLock<InnerVirtIODriver>,
+    kobj_state: LockedKObjectState,
+}
+
+impl VirtIONetDriver {
+    pub fn new() -> Arc<Self> {
+        let inner = InnerVirtIODriver {
+            driver_common: DriverCommonData::default(),
+            kobj_common: KObjectCommonData::default(),
+        };
+        Arc::new(VirtIONetDriver {
+            inner: SpinLock::new(inner),
+            kobj_state: LockedKObjectState::default(),
+        })
     }
 
-    fn set_kobj_state(&self, _state: KObjectState) {
-        todo!()
+    fn inner(&self) -> SpinLockGuard<InnerVirtIODriver> {
+        return self.inner.lock();
     }
+}
 
-    fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {
-        todo!()
+#[derive(Debug)]
+struct InnerVirtIODriver {
+    driver_common: DriverCommonData,
+    kobj_common: KObjectCommonData,
+}
+
+impl VirtIODriver for VirtIONetDriver {
+    fn probe(&self, device: &Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
+        let iface = device
+            .clone()
+            .arc_any()
+            .downcast::<VirtioInterface>()
+            .map_err(|_| {
+                kerror!(
+                "VirtIONetDriver::probe() failed: device is not a VirtioInterface. Device: '{:?}'",
+                device.name()
+            );
+                SystemError::EINVAL
+            })?;
+
+        // 将网卡的接口信息注册到全局的网卡接口信息表中
+        NET_DEVICES
+            .write_irqsave()
+            .insert(iface.nic_id(), iface.clone());
+
+        virtio_irq_manager()
+            .register_device(iface.clone())
+            .expect("Register virtio net failed");
+
+        return Ok(());
     }
 }
 
-// 向编译器保证,VirtioNICDriver在线程之间是安全的.
-// 由于smoltcp只会在token内真正操作网卡设备,并且在VirtioNetToken的consume
-// 方法内,会对VirtioNet进行加【写锁】,因此,能够保证对设备操作的的互斥访问,
-// 因此VirtioNICDriver在线程之间是安全的。
-// unsafe impl<T: Transport> Sync for VirtioNICDriver<T> {}
-// unsafe impl<T: Transport> Send for VirtioNICDriver<T> {}
+impl Driver for VirtIONetDriver {
+    fn id_table(&self) -> Option<IdTable> {
+        Some(IdTable::new(DEVICE_NAME.to_string(), None))
+    }
+
+    fn add_device(&self, device: Arc<dyn Device>) {
+        let iface = device
+            .arc_any()
+            .downcast::<VirtioInterface>()
+            .expect("VirtIONetDriver::add_device() failed: device is not a VirtioInterface");
+
+        self.inner()
+            .driver_common
+            .devices
+            .push(iface as Arc<dyn Device>);
+    }
+
+    fn delete_device(&self, device: &Arc<dyn Device>) {
+        let _iface = device
+            .clone()
+            .arc_any()
+            .downcast::<VirtioInterface>()
+            .expect("VirtIONetDriver::delete_device() failed: device is not a VirtioInterface");
+
+        let mut guard = self.inner();
+        let index = guard
+            .driver_common
+            .devices
+            .iter()
+            .position(|dev| Arc::ptr_eq(device, dev))
+            .expect("VirtIONetDriver::delete_device() failed: device not found");
+
+        guard.driver_common.devices.remove(index);
+    }
+
+    fn devices(&self) -> Vec<Arc<dyn Device>> {
+        self.inner().driver_common.devices.clone()
+    }
+
+    fn bus(&self) -> Option<Weak<dyn Bus>> {
+        Some(Arc::downgrade(&virtio_bus()) as Weak<dyn Bus>)
+    }
+
+    fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
+        // do nothing
+    }
+}
+
+impl KObject for VirtIONetDriver {
+    fn as_any_ref(&self) -> &dyn Any {
+        self
+    }
+
+    fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
+        self.inner().kobj_common.kern_inode = inode;
+    }
+
+    fn inode(&self) -> Option<Arc<KernFSInode>> {
+        self.inner().kobj_common.kern_inode.clone()
+    }
+
+    fn parent(&self) -> Option<Weak<dyn KObject>> {
+        self.inner().kobj_common.parent.clone()
+    }
+
+    fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
+        self.inner().kobj_common.parent = parent;
+    }
+
+    fn kset(&self) -> Option<Arc<KSet>> {
+        self.inner().kobj_common.kset.clone()
+    }
+
+    fn set_kset(&self, kset: Option<Arc<KSet>>) {
+        self.inner().kobj_common.kset = kset;
+    }
+
+    fn kobj_type(&self) -> Option<&'static dyn KObjType> {
+        self.inner().kobj_common.kobj_type
+    }
+
+    fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
+        self.inner().kobj_common.kobj_type = ktype;
+    }
+
+    fn name(&self) -> String {
+        DEVICE_NAME.to_string()
+    }
+
+    fn set_name(&self, _name: String) {
+        // do nothing
+    }
+
+    fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
+        self.kobj_state.read()
+    }
+
+    fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
+        self.kobj_state.write()
+    }
+
+    fn set_kobj_state(&self, state: KObjectState) {
+        *self.kobj_state.write() = state;
+    }
+}

+ 53 - 10
kernel/src/driver/pci/pci.rs

@@ -95,11 +95,45 @@ impl PciDeviceLinkedList {
     }
 }
 
-/// @brief 在链表中寻找满足条件的PCI设备结构体并返回其可变引用
-/// @param list 链表的写锁守卫  
-/// @param class_code 寄存器值
-/// @param subclass 寄存器值,与class_code一起确定设备类型
-/// @return Vec<&'a mut Box<(dyn PciDeviceStructure)  包含链表中所有满足条件的PCI结构体的可变引用的容器
+/// # 获取具有特定供应商ID的PCI设备结构的引用
+///
+/// 这个函数通过供应商ID搜索PCI设备结构列表,并返回匹配该ID的所有设备结构的引用。
+///
+/// ## 参数
+///
+/// - list: 一个可变的PCI设备结构链表,类型为`&'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>`。
+/// - vendor_id: 要查找的PCI供应商ID,类型为`u16`。
+///
+/// ## 返回值
+///
+/// - 返回匹配的供应商ID的PCI设备结构的引用。
+pub fn get_pci_device_structures_mut_by_vendor_id<'a>(
+    list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
+    vendor_id: u16,
+) -> Vec<&'a mut Box<(dyn PciDeviceStructure)>> {
+    let mut result = Vec::new();
+    for box_pci_device_structure in list.iter_mut() {
+        let common_header = (*box_pci_device_structure).common_header();
+        if common_header.vendor_id == vendor_id {
+            result.push(box_pci_device_structure);
+        }
+    }
+    result
+}
+
+/// # get_pci_device_structure_mut - 在链表中寻找满足条件的PCI设备结构体并返回其可变引用
+///
+/// 该函数遍历给定的PCI设备链表,寻找其common_header中class_code和subclass字段与给定值匹配的设备结构体。
+/// 对于每一个匹配的设备结构体,函数返回一个可变引用。
+///
+/// ## 参数
+///
+/// - list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>> — 链表的写锁守卫,用于访问和遍历PCI设备链表。
+/// - class_code: u8 — PCI设备class code寄存器值,用于分类设备的功能。
+/// - subclass: u8 — PCI设备subclass寄存器值,与class_code一起确定设备的子类型。
+///
+/// ## 返回值
+/// - 包含链表中所有满足条件的PCI结构体的可变引用的容器。
 pub fn get_pci_device_structure_mut<'a>(
     list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
     class_code: u8,
@@ -114,11 +148,20 @@ pub fn get_pci_device_structure_mut<'a>(
     }
     result
 }
-/// @brief 在链表中寻找满足条件的PCI设备结构体并返回其不可变引用
-/// @param list 链表的读锁守卫  
-/// @param class_code 寄存器值
-/// @param subclass 寄存器值,与class_code一起确定设备类型
-/// @return Vec<&'a Box<(dyn PciDeviceStructure)  包含链表中所有满足条件的PCI结构体的不可变引用的容器
+
+/// # get_pci_device_structure - 在链表中寻找满足条件的PCI设备结构体并返回其不可变引用
+///
+/// 该函数遍历给定的PCI设备链表,寻找其common_header中class_code和subclass字段与给定值匹配的设备结构体。
+/// 对于每一个匹配的设备结构体,函数返回一个可变引用。
+///
+/// ## 参数
+///
+/// - list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>> — 链表的写锁守卫,用于访问和遍历PCI设备链表。
+/// - class_code: u8 — PCI设备class code寄存器值,用于分类设备的功能。
+/// - subclass: u8 — PCI设备subclass寄存器值,与class_code一起确定设备的子类型。
+///
+/// ## 返回值
+/// - 包含链表中所有满足条件的PCI结构体的不可变引用的容器。
 #[allow(clippy::borrowed_box)]
 pub fn get_pci_device_structure<'a>(
     list: &'a mut RwLockReadGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,

+ 4 - 4
kernel/src/driver/serial/serial8250/mod.rs

@@ -94,6 +94,10 @@ impl Serial8250Manager {
         // todo: 把驱动注册到uart层、tty层
         uart_manager().register_driver(&(serial8250_isa_driver.clone() as Arc<dyn UartDriver>))?;
 
+        // 把驱动注册到platform总线
+        platform_driver_manager()
+            .register(serial8250_isa_driver.clone() as Arc<dyn PlatformDriver>)?;
+
         // 注册isa设备到platform总线
         platform_device_manager()
             .device_add(serial8250_isa_dev.clone() as Arc<dyn PlatformDevice>)
@@ -104,10 +108,6 @@ impl Serial8250Manager {
                 return e;
             })?;
 
-        // 把驱动注册到platform总线
-        platform_driver_manager()
-            .register(serial8250_isa_driver.clone() as Arc<dyn PlatformDriver>)?;
-
         unsafe {
             INITIALIZED = true;
         }

+ 3 - 0
kernel/src/driver/virtio/mmio.rs

@@ -0,0 +1,3 @@
+pub(super) fn virtio_probe_mmio() {
+    // todo: implement virtio_probe_mmio
+}

+ 29 - 5
kernel/src/driver/virtio/mod.rs

@@ -1,20 +1,44 @@
-use core::any::Any;
-
-use alloc::sync::Arc;
+use alloc::{string::String, sync::Arc};
 use system_error::SystemError;
 
 use crate::exception::{irqdesc::IrqReturn, IrqNumber};
 
-use super::base::device::DeviceId;
+use super::base::device::{driver::Driver, Device, DeviceId};
 
 pub(super) mod irq;
+pub mod mmio;
+pub mod sysfs;
+pub mod transport;
 pub mod transport_pci;
 #[allow(clippy::module_inception)]
 pub mod virtio;
 pub mod virtio_impl;
 
-pub trait VirtIODevice: Send + Sync + Any {
+/// virtio 设备厂商ID
+pub const VIRTIO_VENDOR_ID: u16 = 0x1af4;
+
+pub trait VirtIODevice: Device {
     fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError>;
 
     fn dev_id(&self) -> &Arc<DeviceId>;
+
+    fn set_device_name(&self, name: String);
+
+    fn device_name(&self) -> String;
+
+    fn set_virtio_device_index(&self, index: VirtIODeviceIndex);
+
+    fn virtio_device_index(&self) -> Option<VirtIODeviceIndex>;
+
+    /// virtio 设备类型
+    fn device_type_id(&self) -> u32;
+
+    /// virtio 设备厂商
+    fn vendor(&self) -> u32;
 }
+
+pub trait VirtIODriver: Driver {
+    fn probe(&self, device: &Arc<dyn VirtIODevice>) -> Result<(), SystemError>;
+}
+
+int_like!(VirtIODeviceIndex, usize);

+ 295 - 0
kernel/src/driver/virtio/sysfs.rs

@@ -0,0 +1,295 @@
+use alloc::{
+    string::{String, ToString},
+    sync::{Arc, Weak},
+};
+use ida::IdAllocator;
+use intertrait::cast::CastArc;
+use system_error::SystemError;
+use unified_init::macros::unified_init;
+
+use crate::{
+    driver::base::{
+        device::{
+            bus::{bus_manager, Bus},
+            device_manager,
+            driver::{driver_manager, Driver},
+            Device,
+        },
+        kobject::KObject,
+        subsys::SubSysPrivate,
+    },
+    filesystem::{
+        sysfs::{
+            file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport, SYSFS_ATTR_MODE_RO,
+        },
+        vfs::syscall::ModeType,
+    },
+    init::initcall::INITCALL_CORE,
+};
+
+use super::{VirtIODevice, VirtIODeviceIndex, VirtIODriver};
+
+static mut VIRTIO_BUS: Option<Arc<VirtIOBus>> = None;
+
+#[inline(always)]
+pub fn virtio_bus() -> Arc<VirtIOBus> {
+    unsafe { VIRTIO_BUS.as_ref().unwrap().clone() }
+}
+
+#[derive(Debug)]
+pub struct VirtIOBus {
+    private: SubSysPrivate,
+}
+
+impl VirtIOBus {
+    pub fn new() -> Arc<Self> {
+        let w: Weak<Self> = Weak::new();
+        let private = SubSysPrivate::new("virtio".to_string(), Some(w), None, &[]);
+        let bus = Arc::new(Self { private });
+        bus.subsystem()
+            .set_bus(Some(Arc::downgrade(&(bus.clone() as Arc<dyn Bus>))));
+
+        return bus;
+    }
+}
+
+impl Bus for VirtIOBus {
+    fn name(&self) -> String {
+        self.private.name()
+    }
+
+    fn dev_name(&self) -> String {
+        return self.name();
+    }
+
+    fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
+        // todo: VirtIODeviceAttrGroup
+        return &[];
+    }
+
+    fn subsystem(&self) -> &SubSysPrivate {
+        return &self.private;
+    }
+
+    fn probe(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> {
+        let drv = device.driver().ok_or(SystemError::EINVAL)?;
+        let virtio_drv = drv.cast::<dyn VirtIODriver>().map_err(|_| {
+            kerror!(
+                "VirtIOBus::probe() failed: device.driver() is not a VirtioDriver. Device: '{:?}'",
+                device.name()
+            );
+            SystemError::EINVAL
+        })?;
+
+        let virtio_dev = device.clone().cast::<dyn VirtIODevice>().map_err(|_| {
+            kerror!(
+                "VirtIOBus::probe() failed: device is not a VirtIODevice. Device: '{:?}'",
+                device.name()
+            );
+            SystemError::EINVAL
+        })?;
+
+        return virtio_drv.probe(&virtio_dev);
+    }
+
+    fn remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
+        todo!()
+    }
+
+    fn sync_state(&self, _device: &Arc<dyn Device>) {
+        todo!()
+    }
+
+    fn shutdown(&self, _device: &Arc<dyn Device>) {
+        todo!()
+    }
+
+    fn resume(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
+        todo!()
+    }
+
+    fn match_device(
+        &self,
+        _device: &Arc<dyn Device>,
+        _driver: &Arc<dyn Driver>,
+    ) -> Result<bool, SystemError> {
+        // todo: https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/virtio/virtio.c#85
+        todo!("VirtIOBus::match_device() is not implemented")
+    }
+}
+
+#[unified_init(INITCALL_CORE)]
+fn virtio_init() -> Result<(), SystemError> {
+    let bus = VirtIOBus::new();
+    unsafe {
+        VIRTIO_BUS = Some(bus.clone());
+    }
+    bus_manager()
+        .register(bus)
+        .expect("Failed to register virtio bus!");
+    Ok(())
+}
+
+#[inline(always)]
+pub fn virtio_driver_manager() -> &'static VirtIODriverManager {
+    &VirtIODriverManager
+}
+
+pub struct VirtIODriverManager;
+
+impl VirtIODriverManager {
+    pub fn register(&self, driver: Arc<dyn VirtIODriver>) -> Result<(), SystemError> {
+        driver.set_bus(Some(Arc::downgrade(&(virtio_bus() as Arc<dyn Bus>))));
+        return driver_manager().register(driver as Arc<dyn Driver>);
+    }
+
+    #[allow(dead_code)]
+    pub fn unregister(&self, driver: &Arc<dyn VirtIODriver>) {
+        driver_manager().unregister(&(driver.clone() as Arc<dyn Driver>));
+    }
+}
+
+#[inline(always)]
+pub fn virtio_device_manager() -> &'static VirtIODeviceManager {
+    &VirtIODeviceManager
+}
+
+pub struct VirtIODeviceManager;
+
+impl VirtIODeviceManager {
+    pub fn device_add(&self, dev: Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
+        dev.set_bus(Some(Arc::downgrade(&(virtio_bus() as Arc<dyn Bus>))));
+        device_manager().device_default_initialize(&(dev.clone() as Arc<dyn Device>));
+        let drv = dev.driver().ok_or(SystemError::EINVAL)?;
+
+        let virtio_drv = drv.cast::<dyn VirtIODriver>().map_err(|_| {
+            kerror!(
+                "VirtIODeviceManager::device_add() failed: device.driver() is not a VirtioDriver. Device: '{:?}'",
+                dev.name()
+            );
+            SystemError::EINVAL
+        })?;
+        let virtio_index = VIRTIO_DEVICE_INDEX_MANAGER.alloc();
+        dev.set_virtio_device_index(virtio_index);
+        dev.set_device_name(format!("virtio{}", virtio_index.data()));
+        virtio_drv.probe(&dev)?;
+
+        device_manager().add_device(dev.clone() as Arc<dyn Device>)?;
+        device_manager().add_groups(&(dev as Arc<dyn Device>), &[&VirtIODeviceAttrGroup])
+    }
+
+    #[allow(dead_code)]
+    pub fn device_remove(&self, dev: &Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
+        device_manager().remove(&(dev.clone() as Arc<dyn Device>));
+        return Ok(());
+    }
+}
+
+static VIRTIO_DEVICE_INDEX_MANAGER: VirtIODeviceIndexManager = VirtIODeviceIndexManager::new();
+
+/// VirtIO设备索引管理器
+///
+/// VirtIO设备索引管理器用于分配和管理VirtIO设备的唯一索引。
+pub struct VirtIODeviceIndexManager {
+    // ID分配器
+    ///
+    /// ID分配器用于分配唯一的索引给VirtIO设备。
+    ida: IdAllocator,
+}
+
+// VirtIO设备索引管理器的新建实例
+impl VirtIODeviceIndexManager {
+    /// 创建新的VirtIO设备索引管理器实例
+    ///
+    /// 创建一个新的VirtIO设备索引管理器实例,初始时分配器从0开始,直到最大usize值。
+    const fn new() -> Self {
+        Self {
+            ida: IdAllocator::new(0, usize::MAX),
+        }
+    }
+
+    /// 分配一个新的VirtIO设备索引
+    ///
+    /// 分配一个唯一的索引给VirtIO设备。
+    pub fn alloc(&self) -> VirtIODeviceIndex {
+        VirtIODeviceIndex(self.ida.alloc().unwrap())
+    }
+
+    // 释放一个VirtIO设备索引
+    ///
+    /// 释放之前分配的VirtIO设备索引,使其可以被重新使用。
+    #[allow(dead_code)]
+    pub fn free(&self, index: VirtIODeviceIndex) {
+        self.ida.free(index.0);
+    }
+}
+
+/// VirtIO设备属性组
+///
+/// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/virtio/virtio.c#64
+#[derive(Debug)]
+pub struct VirtIODeviceAttrGroup;
+
+impl AttributeGroup for VirtIODeviceAttrGroup {
+    fn name(&self) -> Option<&str> {
+        None
+    }
+
+    fn attrs(&self) -> &[&'static dyn Attribute] {
+        &[&AttrDevice, &AttrVendor]
+    }
+}
+
+#[derive(Debug)]
+struct AttrDevice;
+
+impl Attribute for AttrDevice {
+    fn name(&self) -> &str {
+        "device"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
+        let dev = kobj.cast::<dyn VirtIODevice>().map_err(|_| {
+            kerror!("AttrDevice::show() failed: kobj is not a VirtIODevice");
+            SystemError::EINVAL
+        })?;
+        let device_type_id = dev.device_type_id();
+
+        return sysfs_emit_str(buf, &format!("0x{:04x}\n", device_type_id));
+    }
+}
+
+#[derive(Debug)]
+struct AttrVendor;
+
+impl Attribute for AttrVendor {
+    fn name(&self) -> &str {
+        "vendor"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
+        let dev = kobj.cast::<dyn VirtIODevice>().map_err(|_| {
+            kerror!("AttrVendor::show() failed: kobj is not a VirtIODevice");
+            SystemError::EINVAL
+        })?;
+        let vendor = dev.vendor();
+
+        return sysfs_emit_str(buf, &format!("0x{:04x}\n", vendor));
+    }
+}

+ 131 - 0
kernel/src/driver/virtio/transport.rs

@@ -0,0 +1,131 @@
+use virtio_drivers::transport::Transport;
+
+use super::transport_pci::PciTransport;
+
+pub enum VirtIOTransport {
+    Pci(PciTransport),
+}
+
+impl core::fmt::Debug for VirtIOTransport {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        match self {
+            VirtIOTransport::Pci(_) => write!(f, "VirtIOTransport::Pci"),
+        }
+    }
+}
+
+impl Transport for VirtIOTransport {
+    #[inline(always)]
+    fn finish_init(&mut self) {
+        match self {
+            VirtIOTransport::Pci(transport) => transport.finish_init(),
+        }
+    }
+
+    #[inline(always)]
+    fn device_type(&self) -> virtio_drivers::transport::DeviceType {
+        match self {
+            VirtIOTransport::Pci(transport) => transport.device_type(),
+        }
+    }
+
+    #[inline(always)]
+    fn read_device_features(&mut self) -> u64 {
+        match self {
+            VirtIOTransport::Pci(transport) => transport.read_device_features(),
+        }
+    }
+
+    #[inline(always)]
+    fn write_driver_features(&mut self, driver_features: u64) {
+        match self {
+            VirtIOTransport::Pci(transport) => transport.write_driver_features(driver_features),
+        }
+    }
+
+    #[inline(always)]
+    fn max_queue_size(&mut self, queue: u16) -> u32 {
+        match self {
+            VirtIOTransport::Pci(transport) => transport.max_queue_size(queue),
+        }
+    }
+
+    #[inline(always)]
+    fn notify(&mut self, queue: u16) {
+        match self {
+            VirtIOTransport::Pci(transport) => transport.notify(queue),
+        }
+    }
+
+    #[inline(always)]
+    fn get_status(&self) -> virtio_drivers::transport::DeviceStatus {
+        match self {
+            VirtIOTransport::Pci(transport) => transport.get_status(),
+        }
+    }
+
+    #[inline(always)]
+    fn set_status(&mut self, status: virtio_drivers::transport::DeviceStatus) {
+        match self {
+            VirtIOTransport::Pci(transport) => transport.set_status(status),
+        }
+    }
+
+    #[inline(always)]
+    fn set_guest_page_size(&mut self, guest_page_size: u32) {
+        match self {
+            VirtIOTransport::Pci(transport) => transport.set_guest_page_size(guest_page_size),
+        }
+    }
+
+    #[inline(always)]
+    fn requires_legacy_layout(&self) -> bool {
+        match self {
+            VirtIOTransport::Pci(transport) => transport.requires_legacy_layout(),
+        }
+    }
+
+    #[inline(always)]
+    fn queue_set(
+        &mut self,
+        queue: u16,
+        size: u32,
+        descriptors: virtio_drivers::PhysAddr,
+        driver_area: virtio_drivers::PhysAddr,
+        device_area: virtio_drivers::PhysAddr,
+    ) {
+        match self {
+            VirtIOTransport::Pci(transport) => {
+                transport.queue_set(queue, size, descriptors, driver_area, device_area)
+            }
+        }
+    }
+
+    #[inline(always)]
+    fn queue_unset(&mut self, queue: u16) {
+        match self {
+            VirtIOTransport::Pci(transport) => transport.queue_unset(queue),
+        }
+    }
+
+    #[inline(always)]
+    fn queue_used(&mut self, queue: u16) -> bool {
+        match self {
+            VirtIOTransport::Pci(transport) => transport.queue_used(queue),
+        }
+    }
+
+    #[inline(always)]
+    fn ack_interrupt(&mut self) -> bool {
+        match self {
+            VirtIOTransport::Pci(transport) => transport.ack_interrupt(),
+        }
+    }
+
+    #[inline(always)]
+    fn config_space<T: 'static>(&self) -> virtio_drivers::Result<core::ptr::NonNull<T>> {
+        match self {
+            VirtIOTransport::Pci(transport) => transport.config_space(),
+        }
+    }
+}

+ 1 - 3
kernel/src/driver/virtio/transport_pci.rs

@@ -32,9 +32,7 @@ use virtio_drivers::{
     Error, Hal, PhysAddr,
 };
 
-/// The PCI vendor ID for VirtIO devices.
-/// PCI Virtio设备的vendor ID
-const VIRTIO_VENDOR_ID: u16 = 0x1af4;
+use super::VIRTIO_VENDOR_ID;
 
 /// The offset to add to a VirtIO device ID to get the corresponding PCI device ID.
 /// PCI Virtio设备的DEVICE_ID 的offset

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

@@ -1,53 +1,51 @@
+use super::mmio::virtio_probe_mmio;
 use super::transport_pci::PciTransport;
 use super::virtio_impl::HalImpl;
 use crate::driver::base::device::DeviceId;
 use crate::driver::net::virtio_net::virtio_net;
 use crate::driver::pci::pci::{
-    get_pci_device_structure_mut, PciDeviceStructure, PciDeviceStructureGeneralDevice,
-    PCI_DEVICE_LINKEDLIST,
+    get_pci_device_structures_mut_by_vendor_id, PciDeviceStructure,
+    PciDeviceStructureGeneralDevice, PCI_DEVICE_LINKEDLIST,
 };
+use crate::driver::virtio::transport::VirtIOTransport;
 use crate::libs::rwlock::RwLockWriteGuard;
 use crate::{kdebug, kerror, kwarn};
 use alloc::sync::Arc;
+use alloc::vec::Vec;
 use alloc::{boxed::Box, collections::LinkedList};
 use virtio_drivers::transport::{DeviceType, Transport};
-const NETWORK_CLASS: u8 = 0x2;
-const ETHERNET_SUBCLASS: u8 = 0x0;
-
-//Virtio设备寻找过程中出现的问题
-enum VirtioError {
-    VirtioNetNotFound,
-    NetDeviceNotFound,
-}
 
 ///@brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加)
 pub fn virtio_probe() {
+    virtio_probe_pci();
+    virtio_probe_mmio();
+}
+
+fn virtio_probe_pci() {
     let mut list = PCI_DEVICE_LINKEDLIST.write();
-    if let Ok(virtio_list) = virtio_device_search(&mut list) {
-        for virtio_device in virtio_list {
-            let dev_id = virtio_device.common_header.device_id;
-            let dev_id = DeviceId::new(None, Some(format!("virtio_{}", dev_id))).unwrap();
-            match PciTransport::new::<HalImpl>(virtio_device, dev_id.clone()) {
-                Ok(mut transport) => {
-                    kdebug!(
-                        "Detected virtio PCI device with device type {:?}, features {:#018x}",
-                        transport.device_type(),
-                        transport.read_device_features(),
-                    );
-                    virtio_device_init(transport, dev_id);
-                }
-                Err(err) => {
-                    kerror!("Pci transport create failed because of error: {}", err);
-                }
+    let virtio_list = virtio_device_search(&mut list);
+    for virtio_device in virtio_list {
+        let dev_id = virtio_device.common_header.device_id;
+        let dev_id = DeviceId::new(None, Some(format!("{dev_id}"))).unwrap();
+        match PciTransport::new::<HalImpl>(virtio_device, dev_id.clone()) {
+            Ok(mut transport) => {
+                kdebug!(
+                    "Detected virtio PCI device with device type {:?}, features {:#018x}",
+                    transport.device_type(),
+                    transport.read_device_features(),
+                );
+                let transport = VirtIOTransport::Pci(transport);
+                virtio_device_init(transport, dev_id);
+            }
+            Err(err) => {
+                kerror!("Pci transport create failed because of error: {}", err);
             }
         }
-    } else {
-        kerror!("Error occured when finding virtio device!");
     }
 }
 
 ///@brief 为virtio设备寻找对应的驱动进行初始化
-fn virtio_device_init(transport: impl Transport + 'static, dev_id: Arc<DeviceId>) {
+fn virtio_device_init(transport: VirtIOTransport, dev_id: Arc<DeviceId>) {
     match transport.device_type() {
         DeviceType::Block => {
             kwarn!("Not support virtio_block device for now");
@@ -65,39 +63,30 @@ fn virtio_device_init(transport: impl Transport + 'static, dev_id: Arc<DeviceId>
     }
 }
 
-/// @brief 寻找所有的virtio设备
-/// @param list 链表的写锁
-/// @return Result<LinkedList<&'a mut Pci_Device_Structure_General_Device>, VirtioError>  成功则返回包含所有virtio设备结构体的可变引用的链表,失败则返回err
-/// 该函数主要是为其他virtio设备预留支持
+/// # virtio_device_search - 在给定的PCI设备列表中搜索符合特定标准的virtio设备
+///
+/// 该函数搜索一个PCI设备列表,找到所有由特定厂商ID(0x1AF4)和设备ID范围(0x1000至0x103F)定义的virtio设备。
+///
+/// ## 参数
+///
+/// - list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>> - 一个可写的PCI设备结构列表的互斥锁。
+///
+/// ## 返回值
+///
+/// 返回一个包含所有找到的virtio设备的数组
 fn virtio_device_search<'a>(
     list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
-) -> Result<LinkedList<&'a mut PciDeviceStructureGeneralDevice>, VirtioError> {
-    let mut virtio_list: LinkedList<&mut PciDeviceStructureGeneralDevice> = LinkedList::new();
-    let virtio_net_device = get_virtio_net_device(list)?;
-    virtio_list.push_back(virtio_net_device);
-    Ok(virtio_list)
-}
+) -> Vec<&'a mut PciDeviceStructureGeneralDevice> {
+    let mut virtio_list = Vec::new();
+    let result = get_pci_device_structures_mut_by_vendor_id(list, 0x1AF4);
 
-/// @brief 寻找virtio-net设备
-/// @param list 链表的写锁
-/// @return Result<&'a mut Pci_Device_Structure_General_Device, VirtioError> 成功则返回virtio设备结构体的可变引用,失败则返回err
-fn get_virtio_net_device<'a>(
-    list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
-) -> Result<&'a mut PciDeviceStructureGeneralDevice, VirtioError> {
-    let result = get_pci_device_structure_mut(list, NETWORK_CLASS, ETHERNET_SUBCLASS);
-    if result.is_empty() {
-        return Err(VirtioError::NetDeviceNotFound);
-    }
     for device in result {
         let standard_device = device.as_standard_device_mut().unwrap();
         let header = &standard_device.common_header;
-        if header.vendor_id == 0x1AF4
-            && header.device_id >= 0x1000
-            && header.device_id <= 0x103F
-            && standard_device.subsystem_id == 1
-        {
-            return Ok(standard_device);
+        if header.device_id >= 0x1000 && header.device_id <= 0x103F {
+            virtio_list.push(standard_device);
         }
     }
-    Err(VirtioError::VirtioNetNotFound)
+
+    return virtio_list;
 }

+ 7 - 1
kernel/src/filesystem/sysfs/mod.rs

@@ -107,7 +107,13 @@ pub trait AttributeGroup: Debug + Send + Sync {
     ///
     /// 如果返回Some,则使用返回的权限。
     /// 如果要标识属性不可见,则返回Some(ModeType::empty())
-    fn is_visible(&self, kobj: Arc<dyn KObject>, attr: &'static dyn Attribute) -> Option<ModeType>;
+    fn is_visible(
+        &self,
+        _kobj: Arc<dyn KObject>,
+        attr: &'static dyn Attribute,
+    ) -> Option<ModeType> {
+        return Some(attr.mode());
+    }
 }
 
 /// sysfs只读属性文件的权限

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

@@ -5,7 +5,7 @@ use core::{
 
 use alloc::{collections::BTreeMap, sync::Arc};
 
-use crate::{driver::net::NetDriver, libs::rwlock::RwLock};
+use crate::{driver::net::NetDevice, libs::rwlock::RwLock};
 use smoltcp::wire::IpEndpoint;
 
 use self::socket::SocketInode;
@@ -18,7 +18,7 @@ pub mod syscall;
 lazy_static! {
     /// # 所有网络接口的列表
     /// 这个列表在中断上下文会使用到,因此需要irqsave
-    pub static ref NET_DRIVERS: RwLock<BTreeMap<usize, Arc<dyn NetDriver>>> = RwLock::new(BTreeMap::new());
+    pub static ref NET_DEVICES: RwLock<BTreeMap<usize, Arc<dyn NetDevice>>> = RwLock::new(BTreeMap::new());
 }
 
 /// 生成网络接口的id (全局自增)

+ 7 - 7
kernel/src/net/net_core.rs

@@ -3,10 +3,10 @@ use smoltcp::{socket::dhcpv4, wire};
 use system_error::SystemError;
 
 use crate::{
-    driver::net::NetDriver,
+    driver::net::NetDevice,
     kdebug, kinfo, kwarn,
     libs::rwlock::RwLockReadGuard,
-    net::{socket::SocketPollMethod, NET_DRIVERS},
+    net::{socket::SocketPollMethod, NET_DEVICES},
     time::timer::{next_n_ms_timer_jiffies, Timer, TimerFunction},
 };
 
@@ -41,7 +41,7 @@ pub fn net_init() -> Result<(), SystemError> {
 }
 
 fn dhcp_query() -> Result<(), SystemError> {
-    let binding = NET_DRIVERS.write_irqsave();
+    let binding = NET_DEVICES.write_irqsave();
 
     let net_face = binding.get(&0).ok_or(SystemError::ENODEV)?.clone();
 
@@ -119,7 +119,7 @@ fn dhcp_query() -> Result<(), SystemError> {
 }
 
 pub fn poll_ifaces() {
-    let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read_irqsave();
+    let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDevice>>> = NET_DEVICES.read_irqsave();
     if guard.len() == 0 {
         kwarn!("poll_ifaces: No net driver found!");
         return;
@@ -139,8 +139,8 @@ pub fn poll_ifaces() {
 pub fn poll_ifaces_try_lock(times: u16) -> Result<(), SystemError> {
     let mut i = 0;
     while i < times {
-        let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> =
-            NET_DRIVERS.read_irqsave();
+        let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDevice>>> =
+            NET_DEVICES.read_irqsave();
         if guard.len() == 0 {
             kwarn!("poll_ifaces: No net driver found!");
             // 没有网卡,返回错误
@@ -170,7 +170,7 @@ pub fn poll_ifaces_try_lock(times: u16) -> Result<(), SystemError> {
 /// @return 加锁超时,返回SystemError::EAGAIN_OR_EWOULDBLOCK
 /// @return 没有网卡,返回SystemError::ENODEV
 pub fn poll_ifaces_try_lock_onetime() -> Result<(), SystemError> {
-    let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read_irqsave();
+    let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDevice>>> = NET_DEVICES.read_irqsave();
     if guard.len() == 0 {
         kwarn!("poll_ifaces: No net driver found!");
         // 没有网卡,返回错误

+ 4 - 4
kernel/src/net/socket/inet.rs

@@ -7,12 +7,12 @@ use system_error::SystemError;
 
 use crate::{
     arch::rand::rand,
-    driver::net::NetDriver,
+    driver::net::NetDevice,
     kerror, kwarn,
     libs::rwlock::RwLock,
     net::{
         event_poll::EPollEventType, net_core::poll_ifaces, Endpoint, Protocol, ShutdownType,
-        NET_DRIVERS,
+        NET_DEVICES,
     },
 };
 
@@ -151,7 +151,7 @@ impl Socket for RawSocket {
                     socket_set_guard.get_mut::<raw::Socket>(self.handle.smoltcp_handle().unwrap());
 
                 // 暴力解决方案:只考虑0号网卡。 TODO:考虑多网卡的情况!!!
-                let iface = NET_DRIVERS.read_irqsave().get(&0).unwrap().clone();
+                let iface = NET_DEVICES.read_irqsave().get(&0).unwrap().clone();
 
                 // 构造IP头
                 let ipv4_src_addr: Option<wire::Ipv4Address> =
@@ -700,7 +700,7 @@ impl Socket for TcpSocket {
             PORT_MANAGER.bind_port(self.metadata.socket_type, temp_port, self.clone())?;
 
             // kdebug!("temp_port: {}", temp_port);
-            let iface: Arc<dyn NetDriver> = NET_DRIVERS.write_irqsave().get(&0).unwrap().clone();
+            let iface: Arc<dyn NetDevice> = NET_DEVICES.write_irqsave().get(&0).unwrap().clone();
             let mut inner_iface = iface.inner_iface().lock();
             // kdebug!("to connect: {ip:?}");
 

+ 6 - 1
tools/run-qemu.sh

@@ -76,6 +76,7 @@ QEMU_SERIAL="-serial file:../serial_opt.txt"
 QEMU_DRIVE="id=disk,file=${QEMU_DISK_IMAGE},if=none"
 QEMU_ACCELARATE=""
 QEMU_ARGUMENT=""
+QEMU_DEVICES=
 
 # 如果qemu_accel不为空
 if [ -n "${qemu_accel}" ]; then
@@ -86,8 +87,11 @@ if [ ${ARCH} == "i386" ] || [ ${ARCH} == "x86_64" ]; then
     QEMU_MACHINE=" -machine q35,memory-backend=${QEMU_MEMORY_BACKEND} "
     QEMU_CPU_FEATURES+="-cpu IvyBridge,apic,x2apic,+fpu,check,+vmx,${allflags}"
     QEMU_RTC_CLOCK+=" -rtc clock=host,base=localtime"
+    QEMU_DEVICES_DISK="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 "
 else
     QEMU_MACHINE=" -machine virt,memory-backend=${QEMU_MEMORY_BACKEND} -cpu sifive-u54 "
+    QEMU_DEVICES_DISK="-device virtio-blk-device,drive=disk "
+
 fi
 
 if [ ${ARCH} == "riscv64" ]; then
@@ -101,7 +105,8 @@ fi
 
 # 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 "
-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 " 
+QEMU_DEVICES+="${QEMU_DEVICES_DISK} "
+QEMU_DEVICES+=" -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 " 
 # 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 " 
 QEMU_ARGUMENT+="-d ${QEMU_DISK_IMAGE} -m ${QEMU_MEMORY} -smp ${QEMU_SMP} -boot order=d ${QEMU_MONITOR} -d ${qemu_trace_std} "