diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 35003192..361204ee 100644 --- a/kernel/Cargo.toml +++ b/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 diff --git a/kernel/src/arch/x86_64/mod.rs b/kernel/src/arch/x86_64/mod.rs index 12aafea4..82a52147 100644 --- a/kernel/src/arch/x86_64/mod.rs +++ b/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; diff --git a/kernel/src/arch/x86_64/rand.rs b/kernel/src/arch/x86_64/rand.rs new file mode 100644 index 00000000..6916c64d --- /dev/null +++ b/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 }; +} diff --git a/kernel/src/driver/base/device/mod.rs b/kernel/src/driver/base/device/mod.rs index cac37bef..3951b38a 100644 --- a/kernel/src/driver/base/device/mod.rs +++ b/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: 该设备唯一标识 diff --git a/kernel/src/driver/base/platform/mod.rs b/kernel/src/driver/base/platform/mod.rs index 32cfdc87..61d2aa14 100644 --- a/kernel/src/driver/base/platform/mod.rs +++ b/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), } diff --git a/kernel/src/driver/mod.rs b/kernel/src/driver/mod.rs index 4b789242..9984bb3c 100644 --- a/kernel/src/driver/mod.rs +++ b/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; +} diff --git a/kernel/src/driver/net/mod.rs b/kernel/src/driver/net/mod.rs new file mode 100644 index 00000000..52638031 --- /dev/null +++ b/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; + // fn as_any_ref(&'static self) -> &'static dyn core::any::Any; +} diff --git a/kernel/src/driver/net/virtio_net.rs b/kernel/src/driver/net/virtio_net.rs new file mode 100644 index 00000000..fb89fc09 --- /dev/null +++ b/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 { + pub inner: Arc>>, +} + +impl Clone for VirtioNICDriver { + fn clone(&self) -> Self { + return VirtioNICDriver { + inner: self.inner.clone(), + }; + } +} + +/// @brief 网卡驱动的包裹器,这是为了获取网卡驱动的可变引用而设计的。 +/// 由于smoltcp的设计,导致需要在poll的时候获取网卡驱动的可变引用, +/// 同时需要在token的consume里面获取可变引用。为了避免双重加锁,所以需要这个包裹器。 +struct VirtioNICDriverWrapper(UnsafeCell>); +unsafe impl Send for VirtioNICDriverWrapper {} +unsafe impl Sync for VirtioNICDriverWrapper {} + +impl Deref for VirtioNICDriverWrapper { + type Target = VirtioNICDriver; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0.get() } + } +} +impl DerefMut for VirtioNICDriverWrapper { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { &mut *self.0.get() } + } +} + +impl VirtioNICDriverWrapper { + fn force_get_mut(&self) -> &mut VirtioNICDriver { + unsafe { &mut *self.0.get() } + } +} + +impl Debug for VirtioNICDriver { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("VirtioNICDriver").finish() + } +} + +pub struct VirtioInterface { + driver: VirtioNICDriverWrapper, + iface_id: usize, + iface: SpinLock, + name: String, +} + +impl 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) + .finish() + } +} + +impl VirtioInterface { + pub fn new(mut driver: VirtioNICDriver) -> Arc { + 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 = VirtioNICDriverWrapper(UnsafeCell::new(driver)); + let result = Arc::new(VirtioInterface { + driver, + iface_id, + iface: SpinLock::new(iface), + name: format!("eth{}", iface_id), + }); + + return result; + } +} + +impl VirtioNICDriver { + pub fn new(driver_net: VirtIONet) -> 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>> = Arc::new(SpinLock::new(driver_net)); + let result = VirtioNICDriver { inner }; + return result; + } +} + +pub struct VirtioNetToken { + driver: VirtioNICDriver, + rx_buffer: Option, +} + +impl<'a, T: Transport> VirtioNetToken { + pub fn new( + driver: VirtioNICDriver, + rx_buffer: Option, + ) -> Self { + return Self { driver, rx_buffer }; + } +} + +impl phy::Device for VirtioNICDriver { + type RxToken<'a> = VirtioNetToken where Self: 'a; + type TxToken<'a> = VirtioNetToken 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> { + // 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 phy::TxToken for VirtioNetToken { + fn consume(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 phy::RxToken for VirtioNetToken { + fn consume(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(transport: T) { + let driver_net: VirtIONet = + match VirtIONet::::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 = 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 Driver for VirtioInterface { + fn as_any_ref(&'static self) -> &'static dyn core::any::Any { + self + } +} + +impl NetDriver for VirtioInterface { + 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 { + 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 Sync for VirtioNICDriver {} +// unsafe impl Send for VirtioNICDriver {} diff --git a/kernel/src/driver/pci/pci.rs b/kernel/src/driver/pci/pci.rs index 02c433ee..45502545 100644 --- a/kernel/src/driver/pci/pci.rs +++ b/kernel/src/driver/pci/pci.rs @@ -44,16 +44,12 @@ impl PciDeviceLinkedList { } /// @brief 获取可读的linkedlist(读锁守卫) /// @return RwLockReadGuard>> 读锁守卫 - pub fn read( - &self, - ) -> RwLockReadGuard>> { + pub fn read(&self) -> RwLockReadGuard>> { self.list.read() } /// @brief 获取可写的linkedlist(写锁守卫) /// @return RwLockWriteGuard>> 写锁守卫 - pub fn write( - &self, - ) -> RwLockWriteGuard>> { + pub fn write(&self) -> RwLockWriteGuard>> { 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. diff --git a/kernel/src/driver/virtio/transport_pci.rs b/kernel/src/driver/virtio/transport_pci.rs index 676f8e8d..de4f8331 100644 --- a/kernel/src/driver/virtio/transport_pci.rs +++ b/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 = None; + let mut notify_cfg: Option = 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 for VirtioPciError { fn from(error: PciError) -> Self { Self::Pci(error) } } -///@brief 获取虚拟地址并将其转化为对应类型的指针 -///@param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息 -///@return Result, VirtioPciError> 成功则返回对应类型的指针,失败则返回Error +/// @brief 获取虚拟地址并将其转化为对应类型的指针 +/// @param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息 +/// @return Result, VirtioPciError> 成功则返回对应类型的指针,失败则返回Error fn get_bar_region( device_bar: &PciStandardDeviceBar, struct_info: &VirtioCapabilityInfo, @@ -486,9 +487,9 @@ fn get_bar_region( Ok(vaddr.cast()) } -///@brief 获取虚拟地址并将其转化为对应类型的 -///@param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息切片的指针 -///@return Result, VirtioPciError> 成功则返回对应类型的指针切片,失败则返回Error +/// @brief 获取虚拟地址并将其转化为对应类型的 +/// @param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息切片的指针 +/// @return Result, VirtioPciError> 成功则返回对应类型的指针切片,失败则返回Error fn get_bar_region_slice( device_bar: &PciStandardDeviceBar, struct_info: &VirtioCapabilityInfo, @@ -501,6 +502,7 @@ fn get_bar_region_slice( struct_info.length as usize / size_of::(), )) } + fn nonnull_slice_from_raw_parts(data: NonNull, len: usize) -> NonNull<[T]> { NonNull::new(ptr::slice_from_raw_parts_mut(data.as_ptr(), len)).unwrap() } diff --git a/kernel/src/driver/virtio/virtio.h b/kernel/src/driver/virtio/virtio.h index 2af1ad19..91d7b1fb 100644 --- a/kernel/src/driver/virtio/virtio.h +++ b/kernel/src/driver/virtio/virtio.h @@ -2,4 +2,4 @@ #include //寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备后续也可添加) -void c_virtio_probe(); +extern void rs_virtio_probe(); diff --git a/kernel/src/driver/virtio/virtio.rs b/kernel/src/driver/virtio/virtio.rs index 8843628b..3e6d89fc 100644 --- a/kernel/src/driver/virtio/virtio.rs +++ b/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(transport: T) { - let driver_net = match VirtIONet::::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, VirtioError> 成功则返回包含所有virtio设备结构体的可变引用的链表,失败则返回err diff --git a/kernel/src/driver/virtio/virtio_impl.rs b/kernel/src/driver/virtio/virtio_impl.rs index 99a1a293..1ad3f9dc 100644 --- a/kernel/src/driver/virtio/virtio_impl.rs +++ b/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, pages: usize) -> i32 { + unsafe fn dma_dealloc(paddr: PhysAddr, _vaddr: NonNull, 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 虚拟地址的指针 - fn mmio_phys_to_virt(_paddr: PhysAddr, _size: usize) -> NonNull { + unsafe fn mmio_phys_to_virt(_paddr: PhysAddr, _size: usize) -> NonNull { 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. } diff --git a/kernel/src/include/bindings/wrapper.h b/kernel/src/include/bindings/wrapper.h index c410a580..ce30d715 100644 --- a/kernel/src/include/bindings/wrapper.h +++ b/kernel/src/include/bindings/wrapper.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -44,4 +45,4 @@ #include #include #include -#include