diff --git a/.gitignore b/.gitignore index c6561507..804cc9a3 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,6 @@ tools/redis-3.2.9 tools/sqlite-amalgamation-3410100 alien-* alien.bin -rust \ No newline at end of file +rust + +subsystems \ No newline at end of file diff --git a/apps/egui/src/main.rs b/apps/egui/src/main.rs index 43707663..74cba48f 100644 --- a/apps/egui/src/main.rs +++ b/apps/egui/src/main.rs @@ -23,7 +23,7 @@ impl GpuDevice { } } -impl GPUDevice for GpuDevice{ +impl GPUDevice for GpuDevice { fn flush(&self) { flush_frame_buffer(); } @@ -38,7 +38,6 @@ impl GPUDevice for GpuDevice{ } } - #[no_mangle] fn main() { println!("embedded graphics demo"); diff --git a/apps/ls/src/main.rs b/apps/ls/src/main.rs index 2b4b8e4a..1bcf9c86 100644 --- a/apps/ls/src/main.rs +++ b/apps/ls/src/main.rs @@ -20,7 +20,7 @@ fn main(_: usize, argv: Vec) -> isize { } 0 } -const BUF_SIZE:usize = 512; +const BUF_SIZE: usize = 512; fn parse_args(path: &str) { let fd = open(path, OpenFlags::O_RDONLY); assert!(fd >= 0, "open failed"); diff --git a/apps/memory-game/src/main.rs b/apps/memory-game/src/main.rs index 2aaea6a7..31efdf7b 100644 --- a/apps/memory-game/src/main.rs +++ b/apps/memory-game/src/main.rs @@ -13,8 +13,8 @@ use rand::prelude::{SliceRandom, SmallRng}; use rand::SeedableRng; use slint::platform::WindowEvent; use slint::{Model, VecModel}; -use virt2slint::Converter; use slint_helper::{MyPlatform, SwapBuffer}; +use virt2slint::Converter; use Mstd::io::{keyboard_or_mouse_event, VIRTGPU_XRES, VIRTGPU_YRES}; use Mstd::time::get_time_ms; @@ -86,7 +86,7 @@ fn main() { loop { // Let Slint run the timer hooks and update animations. slint::platform::update_timers_and_animations(); - let events = checkout_event(&mut converter,&mut x, &mut y); + let events = checkout_event(&mut converter, &mut x, &mut y); events.iter().for_each(|event| { window.dispatch_event(event.clone()); }); @@ -99,7 +99,7 @@ fn main() { }); } } -fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec { +fn checkout_event(converter: &mut Converter, x: &mut isize, y: &mut isize) -> Vec { let mut events = [0; 100]; let event_num = keyboard_or_mouse_event(&mut events); let mut res = Vec::new(); @@ -107,9 +107,9 @@ fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec let event = events[i]; // let window_event = input2event(event, x, y); let window_event = converter.convert(event, x, y); - window_event.map(|e|{ + window_event.map(|e| { res.push(e); }); } res -} \ No newline at end of file +} diff --git a/apps/printdemo/src/main.rs b/apps/printdemo/src/main.rs index 4f24bce1..663f7ee6 100644 --- a/apps/printdemo/src/main.rs +++ b/apps/printdemo/src/main.rs @@ -11,8 +11,8 @@ use alloc::vec::Vec; use slint::platform::WindowEvent; use slint::Model; -use virt2slint::Converter; use slint_helper::{MyPlatform, SwapBuffer}; +use virt2slint::Converter; use Mstd::io::{keyboard_or_mouse_event, VIRTGPU_XRES, VIRTGPU_YRES}; #[no_mangle] @@ -142,7 +142,7 @@ fn main() -> ! { loop { // Let Slint run the timer hooks and update animations. slint::platform::update_timers_and_animations(); - let events = checkout_event(&mut converter,&mut x, &mut y); + let events = checkout_event(&mut converter, &mut x, &mut y); events.iter().for_each(|event| { window.dispatch_event(event.clone()); }); @@ -156,7 +156,7 @@ fn main() -> ! { } } -fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec { +fn checkout_event(converter: &mut Converter, x: &mut isize, y: &mut isize) -> Vec { let mut events = [0; 100]; let event_num = keyboard_or_mouse_event(&mut events); let mut res = Vec::new(); @@ -164,9 +164,9 @@ fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec let event = events[i]; // let window_event = input2event(event, x, y); let window_event = converter.convert(event, x, y); - window_event.map(|e|{ + window_event.map(|e| { res.push(e); }); } res -} \ No newline at end of file +} diff --git a/apps/slint/src/main.rs b/apps/slint/src/main.rs index 0312d923..10f0d3e7 100644 --- a/apps/slint/src/main.rs +++ b/apps/slint/src/main.rs @@ -41,7 +41,7 @@ fn main() { loop { // Let Slint run the timer hooks and update animations. slint::platform::update_timers_and_animations(); - let events = checkout_event(&mut converter,&mut x, &mut y); + let events = checkout_event(&mut converter, &mut x, &mut y); events.iter().for_each(|event| { window.dispatch_event(event.clone()); }); @@ -55,7 +55,7 @@ fn main() { } } -fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec { +fn checkout_event(converter: &mut Converter, x: &mut isize, y: &mut isize) -> Vec { let mut events = [0; 100]; let event_num = keyboard_or_mouse_event(&mut events); let mut res = Vec::new(); @@ -63,7 +63,7 @@ fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec let event = events[i]; // let window_event = input2event(event, x, y); let window_event = converter.convert(event, x, y); - window_event.map(|e|{ + window_event.map(|e| { res.push(e); }); } diff --git a/apps/sysinfo/src/main.rs b/apps/sysinfo/src/main.rs index 00c2e9b3..f1b92563 100644 --- a/apps/sysinfo/src/main.rs +++ b/apps/sysinfo/src/main.rs @@ -11,8 +11,8 @@ use alloc::vec::Vec; use slint::platform::WindowEvent; use slint::SharedString; -use virt2slint::Converter; use slint_helper::{MyPlatform, SwapBuffer}; +use virt2slint::Converter; use Mstd::io::{keyboard_or_mouse_event, VIRTGPU_XRES, VIRTGPU_YRES}; slint::include_modules!(); @@ -62,7 +62,7 @@ fn main() { loop { // Let Slint run the timer hooks and update animations. slint::platform::update_timers_and_animations(); - let events = checkout_event(&mut converter,&mut x, &mut y); + let events = checkout_event(&mut converter, &mut x, &mut y); events.iter().for_each(|event| { window.dispatch_event(event.clone()); }); @@ -76,8 +76,7 @@ fn main() { } } - -fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec { +fn checkout_event(converter: &mut Converter, x: &mut isize, y: &mut isize) -> Vec { let mut events = [0; 100]; let event_num = keyboard_or_mouse_event(&mut events); let mut res = Vec::new(); @@ -85,9 +84,9 @@ fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec let event = events[i]; // let window_event = input2event(event, x, y); let window_event = converter.convert(event, x, y); - window_event.map(|e|{ + window_event.map(|e| { res.push(e); }); } res -} \ No newline at end of file +} diff --git a/apps/todo/src/main.rs b/apps/todo/src/main.rs index 31722e53..2cf3e9b6 100644 --- a/apps/todo/src/main.rs +++ b/apps/todo/src/main.rs @@ -12,8 +12,8 @@ use core::default::Default; use core::iter::Iterator; use slint::platform::WindowEvent; use slint::{FilterModel, Model, SortModel}; -use virt2slint::Converter; use slint_helper::{MyPlatform, SwapBuffer}; +use virt2slint::Converter; use Mstd::io::{keyboard_or_mouse_event, VIRTGPU_XRES, VIRTGPU_YRES}; slint::include_modules!(); @@ -147,7 +147,7 @@ fn main() { loop { // Let Slint run the timer hooks and update animations. slint::platform::update_timers_and_animations(); - let events = checkout_event(&mut converter,&mut x, &mut y); + let events = checkout_event(&mut converter, &mut x, &mut y); events.iter().for_each(|event| { window.dispatch_event(event.clone()); }); @@ -161,7 +161,7 @@ fn main() { } } -fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec { +fn checkout_event(converter: &mut Converter, x: &mut isize, y: &mut isize) -> Vec { let mut events = [0; 100]; let event_num = keyboard_or_mouse_event(&mut events); let mut res = Vec::new(); @@ -169,7 +169,7 @@ fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec let event = events[i]; // let window_event = input2event(event, x, y); let window_event = converter.convert(event, x, y); - window_event.map(|e|{ + window_event.map(|e| { res.push(e); }); } diff --git a/kernel/src/board/common.rs b/kernel/src/board/common.rs deleted file mode 100644 index 9b26c8d6..00000000 --- a/kernel/src/board/common.rs +++ /dev/null @@ -1,38 +0,0 @@ -use fdt::node::FdtNode; -use fdt::Fdt; - -#[allow(unused)] -pub fn get_device_info(fdt: &Fdt, device_name: &str) -> Option<(usize, usize)> { - let res = fdt - .all_nodes() - .find(|node| node.name.starts_with(device_name)); - let res = res.and_then(|node| { - if let Some(reg) = node.reg().and_then(|mut reg| reg.next()) { - let addr = reg.starting_address as usize; - if let Some(mut interrupts) = node.interrupts() { - let irq = interrupts.next().unwrap(); - return Some((addr, irq)); - } else { - None - } - } else { - None - } - }); - res -} - -#[allow(unused)] -pub fn get_device_info_from_node(node: &FdtNode) -> Option<(usize, usize)> { - if let Some(reg) = node.reg().and_then(|mut reg| reg.next()) { - let addr = reg.starting_address as usize; - if let Some(mut interrupts) = node.interrupts() { - let irq = interrupts.next().unwrap(); - Some((addr, irq)) - } else { - None - } - } else { - None - } -} diff --git a/kernel/src/board/cv1811.rs b/kernel/src/board/cv1811.rs deleted file mode 100644 index 664416d8..00000000 --- a/kernel/src/board/cv1811.rs +++ /dev/null @@ -1,49 +0,0 @@ -use fdt::Fdt; -use spin::Once; - -use crate::board::common::get_device_info; - -#[repr(align(4))] -struct _Wrapper(T); - -pub const FDT: &[u8] = &_Wrapper(*include_bytes!("../../../tools/cv1811h.dtb")).0; - -pub static DTB: Once = Once::new(); - -pub fn init_dtb(dtb: Option) { - let fdt = if dtb.is_some() { - unsafe { Fdt::from_ptr(dtb as *const u8).unwrap() } - } else { - unsafe { Fdt::from_ptr(FDT.as_ptr()).unwrap() } - }; - DTB.call_once(|| fdt); -} - -/// Get the base address and irq number of the uart device from the device tree. -pub fn probe_devices_from_dtb() { - if let Some(rtc) = probe_rtc() { - BOARD_DEVICES.lock().insert(DeviceType::Rtc, rtc); - } - if let Some(uart) = probe_uart() { - BOARD_DEVICES.lock().insert(DeviceType::Uart, uart); - } -} - -/// Get the base address and irq number of the uart device from the device tree. -pub fn probe_rtc() -> Option { - let fdt = DTB.get().unwrap(); - let res = get_device_info(fdt, "rtc"); - if res.is_none() { - return None; - } - let (base_addr, irq) = res.unwrap(); - Some(DeviceInfo::new(base_addr, irq)) -} - -pub fn probe_uart() -> Option { - let fdt = DTB.get().unwrap(); - if let Some((base_addr, irq)) = get_device_info(fdt, "serial0") { - return Some(DeviceInfo::new(base_addr, irq)); - } - None -} diff --git a/kernel/src/board/mod.rs b/kernel/src/board/mod.rs index 562684f8..4188d87b 100644 --- a/kernel/src/board/mod.rs +++ b/kernel/src/board/mod.rs @@ -1,71 +1,69 @@ +mod probe; + use alloc::collections::BTreeMap; use cfg_if::cfg_if; use crate::ksync::Mutex; -use crate::device::{DeviceInfo, DeviceType}; - -mod common; +use crate::device::DeviceType; pub static BOARD_DEVICES: Mutex> = Mutex::new(BTreeMap::new()); -pub fn get_rtc_info() -> Option<(usize, usize)> { - if let Some(rtc) = BOARD_DEVICES.lock().get(&DeviceType::Rtc) { - return Some((rtc.base_addr, rtc.irq)); - } - None +pub fn get_rtc_info() -> Option { + BOARD_DEVICES + .lock() + .get(&DeviceType::Rtc) + .map(|rtc| rtc.clone()) } -pub fn get_uart_info() -> Option<(usize, usize)> { - if let Some(uart) = BOARD_DEVICES.lock().get(&DeviceType::Uart) { - return Some((uart.base_addr, uart.irq)); - } - None +pub fn get_uart_info() -> Option { + BOARD_DEVICES + .lock() + .get(&DeviceType::Uart) + .map(|uart| uart.clone()) } -pub fn get_gpu_info() -> Option<(usize, usize)> { - if let Some(gpu) = BOARD_DEVICES.lock().get(&DeviceType::GPU) { - return Some((gpu.base_addr, gpu.irq)); - } - None +pub fn get_gpu_info() -> Option { + BOARD_DEVICES + .lock() + .get(&DeviceType::GPU) + .map(|gpu| gpu.clone()) } -pub fn get_keyboard_info() -> Option<(usize, usize)> { - if let Some(keyboard) = BOARD_DEVICES.lock().get(&DeviceType::KeyBoardInput) { - return Some((keyboard.base_addr, keyboard.irq)); - } - None +pub fn get_keyboard_info() -> Option { + BOARD_DEVICES + .lock() + .get(&DeviceType::KeyBoardInput) + .map(|keyboard| keyboard.clone()) } -pub fn get_mouse_info() -> Option<(usize, usize)> { - if let Some(mouse) = BOARD_DEVICES.lock().get(&DeviceType::MouseInput) { - return Some((mouse.base_addr, mouse.irq)); - } - None +pub fn get_mouse_info() -> Option { + BOARD_DEVICES + .lock() + .get(&DeviceType::MouseInput) + .map(|mouse| mouse.clone()) } -pub fn get_block_device_info() -> Option<(usize, usize)> { - if let Some(block) = BOARD_DEVICES.lock().get(&DeviceType::Block) { - return Some((block.base_addr, block.irq)); - } - None +pub fn get_block_device_info() -> Option { + BOARD_DEVICES + .lock() + .get(&DeviceType::Block) + .map(|block| block.clone()) } -pub fn get_net_device_info() -> Option<(usize, usize)> { - if let Some(net) = BOARD_DEVICES.lock().get(&DeviceType::Network) { - return Some((net.base_addr, net.irq)); - } - None +pub fn get_net_device_info() -> Option { + BOARD_DEVICES + .lock() + .get(&DeviceType::Network) + .map(|net| net.clone()) } +use crate::board::probe::DeviceInfo; cfg_if! { if #[cfg(feature="qemu")]{ mod qemu; pub use qemu::*; - }else if #[cfg(feature="cv1811")]{ - mod cv1811; - pub use cv1811::*; }else if #[cfg(feature="hifive")]{ mod unmatched; pub use unmatched::*; diff --git a/kernel/src/board/probe.rs b/kernel/src/board/probe.rs new file mode 100644 index 00000000..b7e25219 --- /dev/null +++ b/kernel/src/board/probe.rs @@ -0,0 +1,90 @@ +use alloc::string::{String, ToString}; + +use alloc::vec::Vec; +use core::ops::Range; +use fdt::standard_nodes::Compatible; +use fdt::Fdt; + +#[derive(Debug, Clone)] +pub struct DeviceInfo { + pub name: String, + pub base_addr: usize, + pub irq: usize, + pub compatible: String, +} + +impl DeviceInfo { + pub fn new(name: String, base_addr: usize, irq: usize, compatible: String) -> Self { + Self { + name, + base_addr, + irq, + compatible, + } + } +} + +pub trait Probe { + /// Get the base address and irq number of the uart device from the device tree. + fn probe_uart(&self) -> Option; + /// Get the base address and irq number of the rtc device from the device tree. + fn probe_rtc(&self) -> Option; + /// Get the base address and irq number of the virtio devices from the device tree. + fn probe_virtio(&self) -> Option>; + fn probe_common(&self, device_name: &str) -> Option; +} + +impl Probe for Fdt<'_> { + fn probe_uart(&self) -> Option { + match self.probe_common("uart") { + Some(device_info) => Some(device_info), + None => self.probe_common("serial"), + } + } + + fn probe_rtc(&self) -> Option { + self.probe_common("rtc") + } + + fn probe_virtio(&self) -> Option> { + let mut virtio_devices = Vec::new(); + for node in self.all_nodes() { + if node.name.starts_with("virtio_mmio") { + let reg = node.reg()?.next()?; + let paddr = reg.starting_address as usize; + let irq = node.property("interrupts")?.value; + let irq = u32::from_be_bytes(irq[0..4].try_into().ok()?); + + let compatible = node.compatible().map(Compatible::first).unwrap(); + + virtio_devices.push(DeviceInfo::new( + String::from("virtio_mmio"), + paddr, + irq as usize, + compatible.to_string(), + )); + } + } + Some(virtio_devices) + } + + fn probe_common(&self, device_name: &str) -> Option { + let node = self + .all_nodes() + .find(|node| node.name.starts_with(device_name))?; + let reg = node.reg()?.next()?; + let range = Range { + start: reg.starting_address as usize, + end: reg.starting_address as usize + reg.size.unwrap(), + }; + let irq = node.property("interrupts").unwrap().value; + let irq = u32::from_be_bytes(irq[0..4].try_into().unwrap()); + let compatible = node.compatible().map(Compatible::first).unwrap(); + Some(DeviceInfo::new( + device_name.to_string(), + range.start, + irq as usize, + compatible.to_string(), + )) + } +} diff --git a/kernel/src/board/qemu.rs b/kernel/src/board/qemu.rs index 3f31ec60..636de488 100644 --- a/kernel/src/board/qemu.rs +++ b/kernel/src/board/qemu.rs @@ -1,16 +1,11 @@ +use crate::board::probe::{DeviceInfo, Probe}; +use crate::board::BOARD_DEVICES; +use crate::device::DeviceType; use core::ptr::NonNull; - -use fdt::node::FdtNode; -use fdt::standard_nodes::Compatible; use fdt::Fdt; use spin::Once; use virtio_drivers::transport::mmio::{MmioTransport, VirtIOHeader}; -use virtio_drivers::transport::{DeviceType as VirtDeviceType, Transport}; - -use crate::board::common::get_device_info; -use crate::board::BOARD_DEVICES; -use crate::device::DeviceInfo; -use crate::device::DeviceType; +use virtio_drivers::transport::Transport; pub static DTB: Once = Once::new(); @@ -25,44 +20,25 @@ pub fn init_dtb(dtb: Option) { /// Get the base address and irq number of the uart device from the device tree. pub fn probe_devices_from_dtb() { - if let Some(rtc) = probe_rtc() { + let dtb = DTB.get().unwrap(); + if let Some(rtc) = dtb.probe_rtc() { BOARD_DEVICES.lock().insert(DeviceType::Rtc, rtc); } - if let Some(uart) = probe_uart() { + if let Some(uart) = dtb.probe_uart() { BOARD_DEVICES.lock().insert(DeviceType::Uart, uart); } - find_virtio_device(DTB.get().unwrap()); -} - -/// Get the base address and irq number of the uart device from the device tree. -pub fn probe_rtc() -> Option { - let fdt = DTB.get().unwrap(); - let res = get_device_info(fdt, "rtc"); - if res.is_none() { - return None; - } - let (base_addr, irq) = res.unwrap(); - Some(DeviceInfo::new(base_addr, irq)) -} - -/// Get the base address and irq number of the uart device from the device tree. -pub fn probe_uart() -> Option { - let fdt = DTB.get().unwrap(); - if let Some((base_addr, irq)) = get_device_info(fdt, "uart") { - return Some(DeviceInfo::new(base_addr, irq)); - } - None -} - -fn find_virtio_device(fdt: &Fdt) -> Option<(usize, usize)> { - for node in fdt.all_nodes() { - if node.name.starts_with("virtio_mmio") { - if let Some((device_type, info)) = virtio_probe(&node) { - BOARD_DEVICES.lock().insert(device_type, info); + if let Some(virtio_mmio) = dtb.probe_virtio() { + for virtio in virtio_mmio { + match virtio_mmio_type(&virtio) { + Some(ty) => { + BOARD_DEVICES.lock().insert(ty, virtio); + } + None => { + error!("Unknown virtio device type at {:#x}", virtio.base_addr); + } } } } - None } // keyboard @@ -70,64 +46,40 @@ const VIRTIO5: usize = 0x10005000; // mouse const VIRTIO6: usize = 0x10006000; -fn virtio_probe(node: &FdtNode) -> Option<(DeviceType, DeviceInfo)> { - if let Some(reg) = node.reg().and_then(|mut reg| reg.next()) { - let paddr = reg.starting_address as usize; - let size = reg.size.unwrap(); - let vaddr = paddr; - info!("walk dt addr={:#x}, size={:#x}", paddr, size); - info!( - "Device tree node {}: {:?}", - node.name, - node.compatible().map(Compatible::first), - ); - let irq = if let Some(mut interrupts) = node.interrupts() { - let irq = interrupts.next().unwrap(); - irq - } else { - 0 - }; - - let header = NonNull::new(vaddr as *mut VirtIOHeader).unwrap(); - match unsafe { MmioTransport::new(header) } { - Err(_) => {} - Ok(mut transport) => { - info!( +fn virtio_mmio_type(device_info: &DeviceInfo) -> Option { + let paddr = device_info.base_addr; + let header = NonNull::new(paddr as *mut VirtIOHeader).unwrap(); + info!("walk dt addr={:#x}", paddr); + info!( + "Device tree node {}: {:?}", + device_info.name, device_info.compatible + ); + match unsafe { MmioTransport::new(header) } { + Err(_) => None, + Ok(mut transport) => { + info!( "Detected virtio MMIO device with vendor id {:#X}, device type {:?}, version {:?}, features:{:?}", transport.vendor_id(), transport.device_type(), transport.version(), transport.read_device_features(), ); - info!("Probe virtio device: {:?}", transport.device_type()); - match transport.device_type() { - VirtDeviceType::Input => { - let device_info = DeviceInfo::new(paddr, irq); - let res = if paddr == VIRTIO5 { - Some((DeviceType::KeyBoardInput, device_info)) - } else if paddr == VIRTIO6 { - Some((DeviceType::MouseInput, device_info)) - } else { - None - }; - return res; - } - VirtDeviceType::Block => { - let device_info = DeviceInfo::new(paddr, irq); - return Some((DeviceType::Block, device_info)); - } - VirtDeviceType::GPU => { - let device_info = DeviceInfo::new(paddr, irq); - return Some((DeviceType::GPU, device_info)); - } - VirtDeviceType::Network => { - let device_info = DeviceInfo::new(paddr, irq); - return Some((DeviceType::Network, device_info)); + info!("Probe virtio device: {:?}", transport.device_type()); + match transport.device_type() { + virtio_drivers::transport::DeviceType::Input => { + if paddr == VIRTIO5 { + Some(DeviceType::KeyBoardInput) + } else if paddr == VIRTIO6 { + Some(DeviceType::MouseInput) + } else { + None } - _ => return None, } + virtio_drivers::transport::DeviceType::Block => Some(DeviceType::Block), + virtio_drivers::transport::DeviceType::GPU => Some(DeviceType::GPU), + virtio_drivers::transport::DeviceType::Network => Some(DeviceType::Network), + _ => None, } } } - None } diff --git a/kernel/src/board/unmatched.rs b/kernel/src/board/unmatched.rs index c387ccb6..f913a5a2 100644 --- a/kernel/src/board/unmatched.rs +++ b/kernel/src/board/unmatched.rs @@ -1,19 +1,20 @@ -use alloc::vec::Vec; +use crate::board::probe::Probe; +use crate::board::BOARD_DEVICES; +use crate::device::DeviceType; use fdt::Fdt; use spin::Once; -use crate::board::common::get_device_info; - #[repr(align(4))] -struct _Wrapper(T); +struct Wrapper(T); -pub const FDT: &[u8] = &_Wrapper(*include_bytes!("../../../tools/hifive-unmatched-a00.dtb")).0; +pub const FDT: &[u8] = &Wrapper(*include_bytes!("../../../tools/hifive-unmatched-a00.dtb")).0; pub static DTB: Once = Once::new(); pub fn init_dtb(dtb: Option) { let fdt = if dtb.is_some() { - unsafe { Fdt::from_ptr(dtb as *const u8).unwrap() } + assert_eq!(dtb.unwrap(), FDT.as_ptr() as usize); + unsafe { Fdt::from_ptr(dtb.unwrap() as *const u8).unwrap() } } else { unsafe { Fdt::from_ptr(FDT.as_ptr()).unwrap() } }; @@ -22,29 +23,11 @@ pub fn init_dtb(dtb: Option) { /// Get the base address and irq number of the uart device from the device tree. pub fn probe_devices_from_dtb() { - if let Some(rtc) = probe_rtc() { + let dtb = crate::board::DTB.get().unwrap(); + if let Some(rtc) = dtb.probe_rtc() { BOARD_DEVICES.lock().insert(DeviceType::Rtc, rtc); } - if let Some(uart) = probe_uart() { + if let Some(uart) = dtb.probe_uart() { BOARD_DEVICES.lock().insert(DeviceType::Uart, uart); } } - -/// Get the base address and irq number of the uart device from the device tree. -pub fn probe_rtc() -> Option { - let fdt = DTB.get().unwrap(); - let res = get_device_info(fdt, "rtc"); - if res.is_none() { - return None; - } - let (base_addr, irq) = res.unwrap(); - Some(DeviceInfo::new(base_addr, irq)) -} - -pub fn probe_uart() -> Option { - let fdt = DTB.get().unwrap(); - if let Some((base_addr, irq)) = get_device_info(fdt, "serial") { - return Some(DeviceInfo::new(base_addr, irq)); - } - None -} diff --git a/kernel/src/board/vf2.rs b/kernel/src/board/vf2.rs index 670334ce..397c26ee 100644 --- a/kernel/src/board/vf2.rs +++ b/kernel/src/board/vf2.rs @@ -1,15 +1,14 @@ -use core::ops::Range; - use fdt::Fdt; use spin::Once; +use crate::board::probe::Probe; use crate::board::BOARD_DEVICES; -use crate::device::{DeviceInfo, DeviceType}; +use crate::device::DeviceType; #[repr(align(4))] -struct _Wrapper(T); +struct Wrapper(T); -pub const FDT: &[u8] = &_Wrapper(*include_bytes!("../../../tools/jh7110-visionfive-v2.dtb")).0; +pub const FDT: &[u8] = &Wrapper(*include_bytes!("../../../tools/jh7110-visionfive-v2.dtb")).0; pub static DTB: Once = Once::new(); @@ -25,44 +24,11 @@ pub fn init_dtb(dtb: Option) { /// Get the base address and irq number of the uart device from the device tree. pub fn probe_devices_from_dtb() { - if let Some(rtc) = probe_rtc() { + let dtb = DTB.get().unwrap(); + if let Some(rtc) = dtb.probe_rtc() { BOARD_DEVICES.lock().insert(DeviceType::Rtc, rtc); } - if let Some(uart) = probe_uart() { + if let Some(uart) = dtb.probe_uart() { BOARD_DEVICES.lock().insert(DeviceType::Uart, uart); } } - -/// Get the base address and irq number of the uart device from the device tree. -pub fn probe_rtc() -> Option { - let fdt = DTB.get().unwrap(); - let node = fdt.all_nodes().find(|node| node.name.starts_with("rtc")); - assert!(node.is_some()); - let node = node.unwrap(); - let reg = node.reg().unwrap().next().unwrap(); - let range = Range { - start: reg.starting_address as usize, - end: reg.starting_address as usize + reg.size.unwrap(), - }; - // let irq = node.property("interrupts").unwrap().value; - // let irq = u32::from_be_bytes(irq.try_into().unwrap()); - let irq = 0xa; - Some(DeviceInfo::new(range.start, irq as usize)) -} - -/// Get the base address and irq number of the uart device from the device tree. -/// -/// Return: -/// (base addr, irq) -pub fn probe_uart() -> Option { - let fdt = DTB.get().unwrap(); - // get_device_info(fdt, "serial") - let node = fdt.all_nodes().find(|node| node.name.starts_with("serial")); - assert!(node.is_some()); - let node = node.unwrap(); - let mut reg = node.reg().unwrap(); - let irq = node.property("interrupts").unwrap().value; - let irq = u32::from_be_bytes(irq.try_into().unwrap()); - let base_addr = reg.next().unwrap().starting_address as usize; - Some(DeviceInfo::new(base_addr, irq as usize)) -} diff --git a/kernel/src/device/input.rs b/kernel/src/device/input.rs index 3da763a0..918097c7 100644 --- a/kernel/src/device/input.rs +++ b/kernel/src/device/input.rs @@ -42,7 +42,7 @@ impl INPUTDevice { impl VfsFile for INPUTDevice { fn read_at(&self, _offset: u64, buf: &mut [u8]) -> VfsResult { - if buf.len() != 8{ + if buf.len() != 8 { return Err(VfsError::Invalid); } let buf = unsafe { core::slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut u64, 1) }; @@ -85,12 +85,10 @@ impl VfsInode for INPUTDevice { pub static KEYBOARD_INPUT_DEVICE: Once> = Once::new(); pub static MOUSE_INPUT_DEVICE: Once> = Once::new(); - pub fn init_keyboard_input_device(input_device: Arc) { KEYBOARD_INPUT_DEVICE.call_once(|| input_device); } - pub fn init_mouse_input_device(input_device: Arc) { MOUSE_INPUT_DEVICE.call_once(|| input_device); } diff --git a/kernel/src/device/mod.rs b/kernel/src/device/mod.rs index 89738ebd..f1ec1d3b 100644 --- a/kernel/src/device/mod.rs +++ b/kernel/src/device/mod.rs @@ -9,11 +9,11 @@ use alloc::boxed::Box; use alloc::sync::Arc; pub use block::{BLKDevice, BlockDevice, BLOCK_DEVICE}; use core::sync::atomic::Ordering; -use smoltcp::wire::IpAddress; pub use gpu::{GPUDevice, GpuDevice, GPU_DEVICE}; pub use input::{ sys_event_get, INPUTDevice, InputDevice, KEYBOARD_INPUT_DEVICE, MOUSE_INPUT_DEVICE, }; +use smoltcp::wire::IpAddress; mod block; mod gpu; @@ -32,18 +32,6 @@ pub enum DeviceType { Uart, Rtc, } - -pub struct DeviceInfo { - pub base_addr: usize, - pub irq: usize, -} - -impl DeviceInfo { - pub fn new(base_addr: usize, irq: usize) -> Self { - Self { base_addr, irq } - } -} - pub fn init_device() { probe_devices_from_dtb(); init_uart(); @@ -62,12 +50,13 @@ fn init_rtc() { println!("There is no rtc device"); return; } - let (base_addr, irq) = res.unwrap(); + let info = res.unwrap(); + let (base_addr, irq) = (info.base_addr, info.irq); println!("Init rtc, base_addr:{:#x},irq:{}", base_addr, irq); #[cfg(feature = "qemu")] { use crate::driver::rtc::GoldFishRtc; - use ::rtc::{LowRtcDeviceExt}; + use ::rtc::LowRtcDeviceExt; let rtc = Arc::new(GoldFishRtc::new(base_addr)); let current_time = rtc.read_time_fmt(); rtc::init_rtc(rtc.clone()); @@ -87,7 +76,8 @@ fn init_uart() { println!("There is no uart device"); return; } - let (base_addr, irq) = res.unwrap(); + let info = res.unwrap(); + let (base_addr, irq) = (info.base_addr, info.irq); println!("Init uart, base_addr:{:#x},irq:{}", base_addr, irq); #[cfg(feature = "qemu")] { @@ -120,7 +110,8 @@ fn init_block_device() { println!("There is no block device"); return; } - let (base_addr, irq) = res.unwrap(); + let info = res.unwrap(); + let (base_addr, irq) = (info.base_addr, info.irq); println!("Init block device, base_addr:{:#x},irq:{}", base_addr, irq); let block_device = VirtIOBlkWrapper::new(base_addr); let block_device = GenericBlockDevice::new(Box::new(block_device)); @@ -150,14 +141,14 @@ fn init_fake_disk() { block::init_block_device(device.clone()); } - fn init_gpu() { let res = crate::board::get_gpu_info(); if res.is_none() { println!("There is no gpu device"); return; } - let (base_addr, irq) = res.unwrap(); + let info = res.unwrap(); + let (base_addr, irq) = (info.base_addr, info.irq); println!("Init gpu, base_addr:{:#x},irq:{}", base_addr, irq); #[cfg(feature = "qemu")] { @@ -176,7 +167,8 @@ fn init_keyboard_input_device() { println!("There is no keyboard device"); return; } - let (base_addr, irq) = res.unwrap(); + let info = res.unwrap(); + let (base_addr, irq) = (info.base_addr, info.irq); println!( "Init keyboard input device, base_addr:{:#x},irq:{}", base_addr, irq @@ -199,7 +191,8 @@ fn init_mouse_input_device() { println!("There is no mouse device"); return; } - let (base_addr, irq) = res.unwrap(); + let info = res.unwrap(); + let (base_addr, irq) = (info.base_addr, info.irq); println!( "Init mouse input device, base_addr:{:#x},irq:{}", base_addr, irq @@ -229,7 +222,8 @@ fn init_net() { println!("There is no net device"); return; } - let (base_addr, irq) = res.unwrap(); + let info = res.unwrap(); + let (base_addr, irq) = (info.base_addr, info.irq); println!("Init net device, base_addr:{:#x},irq:{}", base_addr, irq); #[cfg(feature = "qemu")] @@ -237,15 +231,15 @@ fn init_net() { use crate::device::net::NetNeedFunc; use crate::driver::net::make_virtio_net_device; let virtio_net = make_virtio_net_device(base_addr); - use core::str::FromStr; use crate::config::{QEMU_GATEWAY, QEMU_IP}; + use core::str::FromStr; let device = Box::new(virtio_net); netcore::init_net( device, Arc::new(NetNeedFunc), IpAddress::from_str(QEMU_IP).unwrap(), - IpAddress::from_str(QEMU_GATEWAY).unwrap(), - true + IpAddress::from_str(QEMU_GATEWAY).unwrap(), + true, ); println!("Init net device success"); #[cfg(feature = "net_test")] @@ -261,16 +255,9 @@ fn init_loop_device() { use crate::device::net::NetNeedFunc; use loopback::LoopbackDev; // use default ip and gateway for qemu - let ip = IpAddress::v4(127,0,0,1); - let gate_way = IpAddress::v4(127,0,0,1); + let ip = IpAddress::v4(127, 0, 0, 1); + let gate_way = IpAddress::v4(127, 0, 0, 1); let loopback = Box::new(LoopbackDev::new()); - netcore::init_net( - loopback, - Arc::new(NetNeedFunc), - ip, - gate_way, - false, - ); + netcore::init_net(loopback, Arc::new(NetNeedFunc), ip, gate_way, false); println!("Init net device success"); } - diff --git a/kernel/src/device/net.rs b/kernel/src/device/net.rs index befb6bdc..03076d7a 100644 --- a/kernel/src/device/net.rs +++ b/kernel/src/device/net.rs @@ -8,11 +8,11 @@ pub trait NetDevice: DeviceBase {} #[cfg(feature = "net_test")] pub mod nettest { + use crate::error::AlienResult; + use crate::net::port::neterror2alien; use alloc::vec::Vec; use core::net::{IpAddr, SocketAddr}; use netcore::tcp::TcpSocket; - use crate::error::{AlienResult}; - use crate::net::port::neterror2alien; /// A TCP stream between a local and a remote socket. pub struct TcpStream(TcpSocket); @@ -68,16 +68,12 @@ pub mod nettest { if n == 0 { return Ok(()); } - stream - .write_all(reverse(&buf[..n]).as_slice()).unwrap(); + stream.write_all(reverse(&buf[..n]).as_slice()).unwrap(); } } pub fn accept_loop() { - let local_addr = SocketAddr::new( - IpAddr::V4(LOCAL_IP.parse().unwrap()), - LOCAL_PORT, - ); + let local_addr = SocketAddr::new(IpAddr::V4(LOCAL_IP.parse().unwrap()), LOCAL_PORT); let listener = TcpListener::bind(local_addr).unwrap(); println!("listen on: {}", listener.local_addr().unwrap()); let mut i = 0; diff --git a/kernel/src/device/rtc.rs b/kernel/src/device/rtc.rs index 485be920..44502492 100644 --- a/kernel/src/device/rtc.rs +++ b/kernel/src/device/rtc.rs @@ -62,7 +62,7 @@ impl VfsFile for RTCDevice { match cmd { TeletypeCommand::RTC_RD_TIME => { let time = self.device.read_time_fmt(); - let c_rtc_time = pconst::io::RtcTime{ + let c_rtc_time = pconst::io::RtcTime { sec: time.second as u32, min: time.minute as u32, hour: time.hour as u32, diff --git a/kernel/src/driver/gpu.rs b/kernel/src/driver/gpu.rs index b678d98d..698410f1 100644 --- a/kernel/src/driver/gpu.rs +++ b/kernel/src/driver/gpu.rs @@ -35,7 +35,7 @@ impl VirtIOGpuWrapper { Self { gpu: Mutex::new(gpu), fb, - resolution + resolution, } } } diff --git a/kernel/src/driver/net.rs b/kernel/src/driver/net.rs index e10c93bd..a776a543 100644 --- a/kernel/src/driver/net.rs +++ b/kernel/src/driver/net.rs @@ -8,9 +8,11 @@ use crate::driver::hal::HalImpl; pub const NET_BUFFER_LEN: usize = 4096; pub const NET_QUEUE_SIZE: usize = 128; -pub fn make_virtio_net_device(addr:usize) -> VirtIONetDeviceWrapper { +pub fn make_virtio_net_device( + addr: usize, +) -> VirtIONetDeviceWrapper { let header = NonNull::new(addr as *mut VirtIOHeader).unwrap(); let transport = unsafe { MmioTransport::new(header) }.unwrap(); let device = VirtIONetDeviceWrapper::new(transport, NET_BUFFER_LEN); device -} \ No newline at end of file +} diff --git a/kernel/src/fs/dev/mod.rs b/kernel/src/fs/dev/mod.rs index 4a3b88af..47dd6724 100644 --- a/kernel/src/fs/dev/mod.rs +++ b/kernel/src/fs/dev/mod.rs @@ -186,7 +186,10 @@ pub fn init_devfs(devfs: Arc) -> Arc { fn scan_system_devices(root: Arc) { BLOCK_DEVICE.get().map(|blk| { - let block_device = Arc::new(BLKDevice::new(alloc_device_id(VfsNodeType::BlockDevice), blk.clone())); + let block_device = Arc::new(BLKDevice::new( + alloc_device_id(VfsNodeType::BlockDevice), + blk.clone(), + )); root.create( "sda", VfsNodeType::BlockDevice, @@ -197,7 +200,10 @@ fn scan_system_devices(root: Arc) { register_device(block_device); }); GPU_DEVICE.get().map(|gpu| { - let gpu_device = Arc::new(GPUDevice::new(alloc_device_id(VfsNodeType::CharDevice), gpu.clone())); + let gpu_device = Arc::new(GPUDevice::new( + alloc_device_id(VfsNodeType::CharDevice), + gpu.clone(), + )); root.create( "gpu", VfsNodeType::BlockDevice, @@ -238,7 +244,10 @@ fn scan_system_devices(root: Arc) { register_device(input_device); }); RTC_DEVICE.get().map(|rtc| { - let rtc_device = Arc::new(RTCDevice::new(alloc_device_id(VfsNodeType::CharDevice), rtc.clone())); + let rtc_device = Arc::new(RTCDevice::new( + alloc_device_id(VfsNodeType::CharDevice), + rtc.clone(), + )); root.create( "rtc", VfsNodeType::BlockDevice, @@ -249,7 +258,10 @@ fn scan_system_devices(root: Arc) { register_device(rtc_device); }); UART_DEVICE.get().map(|uart| { - let uart_device = Arc::new(UARTDevice::new(alloc_device_id(VfsNodeType::CharDevice), uart.clone())); + let uart_device = Arc::new(UARTDevice::new( + alloc_device_id(VfsNodeType::CharDevice), + uart.clone(), + )); root.create( "tty", VfsNodeType::BlockDevice, diff --git a/kernel/src/fs/file.rs b/kernel/src/fs/file.rs index 340ac3e7..ab0304a3 100644 --- a/kernel/src/fs/file.rs +++ b/kernel/src/fs/file.rs @@ -117,7 +117,7 @@ mod kernel_file { return Ok(0); } let open_flag = self.open_flag.lock(); - if !open_flag.contains(OpenFlags::O_RDONLY)&& !open_flag.contains(OpenFlags::O_RDWR) { + if !open_flag.contains(OpenFlags::O_RDONLY) && !open_flag.contains(OpenFlags::O_RDWR) { return Err(LinuxErrno::EPERM); } drop(open_flag); @@ -151,7 +151,7 @@ mod kernel_file { fn fsync(&self) -> AlienResult<()> { let open_flag = self.open_flag.lock(); - if !open_flag.contains(OpenFlags::O_WRONLY)&& !open_flag.contains(OpenFlags::O_RDWR) { + if !open_flag.contains(OpenFlags::O_WRONLY) && !open_flag.contains(OpenFlags::O_RDWR) { return Err(LinuxErrno::EPERM); } let inode = self.dentry.inode()?; @@ -213,7 +213,7 @@ mod kernel_file { if count + dirent64.len() <= buf.len() { let dirent_ptr = unsafe { &mut *(ptr as *mut Dirent64) }; *dirent_ptr = dirent64; - let name_ptr = dirent_ptr.name.as_mut_ptr(); + let name_ptr = dirent_ptr.name.as_mut_ptr(); unsafe { let mut name = d.name.clone(); name.push('\0'); @@ -236,9 +236,7 @@ mod kernel_file { } fn truncate(&self, len: u64) -> AlienResult<()> { let open_flag = self.open_flag.lock(); - if !open_flag - .contains(OpenFlags::O_WRONLY) & !open_flag.contains(OpenFlags::O_RDWR) - { + if !open_flag.contains(OpenFlags::O_WRONLY) & !open_flag.contains(OpenFlags::O_RDWR) { return Err(LinuxErrno::EINVAL); } let dt = self.dentry(); diff --git a/kernel/src/fs/link.rs b/kernel/src/fs/link.rs index 882c72bc..832f7534 100644 --- a/kernel/src/fs/link.rs +++ b/kernel/src/fs/link.rs @@ -85,9 +85,9 @@ pub fn sys_unlinkat(fd: isize, path: *const u8, flag: usize) -> AlienResult String { let mut res = String::new(); let fs = FS.lock(); - for (_,fs) in fs.iter() { + for (_, fs) in fs.iter() { let flag = fs.fs_flag(); if !flag.contains(FileSystemFlags::REQUIRES_DEV) { res.push_str("nodev ") @@ -36,7 +36,7 @@ impl SystemSupportFS { impl VfsFile for SystemSupportFS { fn read_at(&self, offset: u64, buf: &mut [u8]) -> VfsResult { let info = self.serialize(); - let min_len = min(buf.len(), info.as_bytes().len()-offset as usize); + let min_len = min(buf.len(), info.as_bytes().len() - offset as usize); buf[..min_len].copy_from_slice(&info.as_bytes()[..min_len]); Ok(min_len) } diff --git a/kernel/src/fs/proc/interrupt.rs b/kernel/src/fs/proc/interrupt.rs index 5d5ce8dc..83332a7a 100644 --- a/kernel/src/fs/proc/interrupt.rs +++ b/kernel/src/fs/proc/interrupt.rs @@ -13,7 +13,7 @@ pub struct InterruptRecord; impl VfsFile for InterruptRecord { fn read_at(&self, offset: u64, buf: &mut [u8]) -> VfsResult { let info = interrupts_info(); - let min_len = min(buf.len(), info.as_bytes().len()-offset as usize); + let min_len = min(buf.len(), info.as_bytes().len() - offset as usize); buf[..min_len].copy_from_slice(&info.as_bytes()[..min_len]); Ok(min_len) } diff --git a/kernel/src/fs/proc/mem.rs b/kernel/src/fs/proc/mem.rs index c66539e4..4a777ee6 100644 --- a/kernel/src/fs/proc/mem.rs +++ b/kernel/src/fs/proc/mem.rs @@ -12,7 +12,7 @@ pub struct MemInfo; impl VfsFile for MemInfo { fn read_at(&self, offset: u64, buf: &mut [u8]) -> VfsResult { - let min_len = min(buf.len(), MEMINFO.as_bytes().len()-offset as usize); + let min_len = min(buf.len(), MEMINFO.as_bytes().len() - offset as usize); buf[..min_len].copy_from_slice(&MEMINFO.as_bytes()[..min_len]); Ok(min_len) } diff --git a/kernel/src/fs/proc/mod.rs b/kernel/src/fs/proc/mod.rs index b14c16a9..fe6333c0 100644 --- a/kernel/src/fs/proc/mod.rs +++ b/kernel/src/fs/proc/mod.rs @@ -7,7 +7,7 @@ mod process; use crate::fs::proc::filesystem::SystemSupportFS; use crate::fs::proc::interrupt::InterruptRecord; use crate::fs::proc::mounts::MountInfo; -use crate::fs::{CommonFsProviderImpl}; +use crate::fs::CommonFsProviderImpl; use crate::ksync::Mutex; use alloc::sync::Arc; use dynfs::DynFsDirInode; diff --git a/kernel/src/fs/proc/mounts.rs b/kernel/src/fs/proc/mounts.rs index a266101e..ac0d76fe 100644 --- a/kernel/src/fs/proc/mounts.rs +++ b/kernel/src/fs/proc/mounts.rs @@ -1,47 +1,47 @@ -use alloc::sync::Arc; -use core::cmp::min; -use vfscore::error::VfsError; -use vfscore::file::VfsFile; -use vfscore::inode::{InodeAttr, VfsInode}; -use vfscore::superblock::VfsSuperBlock; -use vfscore::utils::{VfsFileStat, VfsNodePerm, VfsNodeType}; -use vfscore::VfsResult; - -// todo!(dynamic mount info) -const MOUNT_INFO: &str = r" - rootfs / rootfs rw 0 0 - devfs /dev devfs rw 0 0 - fat32 / fat rw 0 0 -"; -pub struct MountInfo; - -impl VfsFile for MountInfo { - fn read_at(&self, offset: u64, buf: &mut [u8]) -> VfsResult { - let min_len = min(buf.len(), MOUNT_INFO.as_bytes().len()-offset as usize); - buf[..min_len].copy_from_slice(&MOUNT_INFO.as_bytes()[..min_len]); - Ok(min_len) - } -} - -impl VfsInode for MountInfo { - fn get_super_block(&self) -> VfsResult> { - Err(VfsError::NoSys) - } - fn node_perm(&self) -> VfsNodePerm { - VfsNodePerm::empty() - } - fn set_attr(&self, _attr: InodeAttr) -> VfsResult<()> { - Ok(()) - } - - fn get_attr(&self) -> VfsResult { - Ok(VfsFileStat { - st_size: MOUNT_INFO.as_bytes().len() as u64, - ..Default::default() - }) - } - - fn inode_type(&self) -> VfsNodeType { - VfsNodeType::File - } -} +use alloc::sync::Arc; +use core::cmp::min; +use vfscore::error::VfsError; +use vfscore::file::VfsFile; +use vfscore::inode::{InodeAttr, VfsInode}; +use vfscore::superblock::VfsSuperBlock; +use vfscore::utils::{VfsFileStat, VfsNodePerm, VfsNodeType}; +use vfscore::VfsResult; + +// todo!(dynamic mount info) +const MOUNT_INFO: &str = r" + rootfs / rootfs rw 0 0 + devfs /dev devfs rw 0 0 + fat32 / fat rw 0 0 +"; +pub struct MountInfo; + +impl VfsFile for MountInfo { + fn read_at(&self, offset: u64, buf: &mut [u8]) -> VfsResult { + let min_len = min(buf.len(), MOUNT_INFO.as_bytes().len() - offset as usize); + buf[..min_len].copy_from_slice(&MOUNT_INFO.as_bytes()[..min_len]); + Ok(min_len) + } +} + +impl VfsInode for MountInfo { + fn get_super_block(&self) -> VfsResult> { + Err(VfsError::NoSys) + } + fn node_perm(&self) -> VfsNodePerm { + VfsNodePerm::empty() + } + fn set_attr(&self, _attr: InodeAttr) -> VfsResult<()> { + Ok(()) + } + + fn get_attr(&self) -> VfsResult { + Ok(VfsFileStat { + st_size: MOUNT_INFO.as_bytes().len() as u64, + ..Default::default() + }) + } + + fn inode_type(&self) -> VfsNodeType { + VfsNodeType::File + } +} diff --git a/kernel/src/fs/ram/mod.rs b/kernel/src/fs/ram/mod.rs index b466db95..b1b71834 100644 --- a/kernel/src/fs/ram/mod.rs +++ b/kernel/src/fs/ram/mod.rs @@ -73,7 +73,8 @@ pub fn init_ramfs(ramfs: Arc) -> Arc { .create("tmp", VfsNodeType::Dir, "rwxrwxrwx".into(), None) .unwrap(); - let _bashrc = root.create(".bashrc", VfsNodeType::File, "rwxrwxrwx".into(), None) + let _bashrc = root + .create(".bashrc", VfsNodeType::File, "rwxrwxrwx".into(), None) .unwrap(); println!("ramfs init success"); diff --git a/kernel/src/interrupt/record.rs b/kernel/src/interrupt/record.rs index 4f2e89b2..bdfdbfba 100644 --- a/kernel/src/interrupt/record.rs +++ b/kernel/src/interrupt/record.rs @@ -1,8 +1,8 @@ +use crate::ksync::Mutex; use alloc::collections::BTreeMap; use alloc::format; use alloc::string::String; -use spin::{Lazy}; -use crate::ksync::Mutex; +use spin::Lazy; /// Record the number of interrupts pub static INTERRUPT_RECORD: Lazy>> = Lazy::new(|| { diff --git a/kernel/src/ipc/pipe.rs b/kernel/src/ipc/pipe.rs index 54db94f8..3191f199 100644 --- a/kernel/src/ipc/pipe.rs +++ b/kernel/src/ipc/pipe.rs @@ -105,13 +105,13 @@ pub fn make_pipe_file() -> VfsResult<(Arc, Arc)> { impl File for PipeFile { fn read(&self, buf: &mut [u8]) -> AlienResult { if buf.len() == 0 { - return Ok(0) + return Ok(0); } self.dentry.inode()?.read_at(0, buf).map_err(|e| e.into()) } fn write(&self, buf: &[u8]) -> AlienResult { if buf.len() == 0 { - return Ok(0) + return Ok(0); } self.dentry.inode()?.write_at(0, buf).map_err(|e| e.into()) } diff --git a/kernel/src/ksync.rs b/kernel/src/ksync.rs index 8583dd43..b15cc9c4 100644 --- a/kernel/src/ksync.rs +++ b/kernel/src/ksync.rs @@ -1,84 +1,83 @@ -use kernel_sync::{LockAction, ticket::TicketMutexGuard}; -use core::cell::{RefCell, RefMut}; -use crate::arch::{hart_id, interrupt_disable, interrupt_enable, is_interrupt_enable}; -use crate::config::CPU_NUM; - - -pub type SpinMutex = kernel_sync::spin::SpinMutex; -pub type TicketMutex = kernel_sync::ticket::TicketMutex; -pub type RwLock = kernel_sync::RwLock; -pub type Mutex = TicketMutex; -pub type MutexGuard<'a, T> = TicketMutexGuard<'a, T, KernelLockAction>; - -#[derive(Debug, Default, Clone, Copy)] -#[repr(align(64))] -pub struct Cpu { - pub noff: i32, // Depth of push_off() nesting. - pub interrupt_enable: bool, // Were interrupts enabled before push_off()? -} - -impl Cpu { - const fn new() -> Self { - Self { - noff: 0, - interrupt_enable: false, - } - } -} - -pub struct SafeRefCell(RefCell); - -/// # Safety: Only the corresponding cpu will access it. -unsafe impl Sync for SafeRefCell {} - -impl SafeRefCell { - const fn new(t: T) -> Self { - Self(RefCell::new(t)) - } -} - -#[allow(clippy::declare_interior_mutable_const)] -const DEFAULT_CPU: SafeRefCell = SafeRefCell::new(Cpu::new()); - -static CPUS: [SafeRefCell; CPU_NUM] = [DEFAULT_CPU; CPU_NUM]; - -pub fn mycpu() -> RefMut<'static, Cpu> { - CPUS[hart_id()].0.borrow_mut() -} - -// push_off/pop_off are like intr_off()/intr_on() except that they are matched: -// it takes two pop_off()s to undo two push_off()s. Also, if interrupts -// are initially off, then push_off, pop_off leaves them off. -pub(crate) fn push_off() { - let old = is_interrupt_enable(); - interrupt_disable(); - let mut cpu = mycpu(); - if cpu.noff == 0 { - cpu.interrupt_enable = old; - } - cpu.noff += 1; -} - -pub(crate) fn pop_off() { - let mut cpu = mycpu(); - if is_interrupt_enable() || cpu.noff < 1 { - panic!("pop_off"); - } - cpu.noff -= 1; - let should_enable = cpu.noff == 0 && cpu.interrupt_enable; - drop(cpu); - // NOTICE: intr_on() may lead to an immediate inerrupt, so we *MUST* drop(cpu) in advance. - if should_enable { - interrupt_enable(); - } -} - -pub struct KernelLockAction; -impl LockAction for KernelLockAction { - fn before_lock() { - push_off(); - } - fn after_lock() { - pop_off(); - } -} +use crate::arch::{hart_id, interrupt_disable, interrupt_enable, is_interrupt_enable}; +use crate::config::CPU_NUM; +use core::cell::{RefCell, RefMut}; +use kernel_sync::{ticket::TicketMutexGuard, LockAction}; + +pub type SpinMutex = kernel_sync::spin::SpinMutex; +pub type TicketMutex = kernel_sync::ticket::TicketMutex; +pub type RwLock = kernel_sync::RwLock; +pub type Mutex = TicketMutex; +pub type MutexGuard<'a, T> = TicketMutexGuard<'a, T, KernelLockAction>; + +#[derive(Debug, Default, Clone, Copy)] +#[repr(align(64))] +pub struct Cpu { + pub noff: i32, // Depth of push_off() nesting. + pub interrupt_enable: bool, // Were interrupts enabled before push_off()? +} + +impl Cpu { + const fn new() -> Self { + Self { + noff: 0, + interrupt_enable: false, + } + } +} + +pub struct SafeRefCell(RefCell); + +/// # Safety: Only the corresponding cpu will access it. +unsafe impl Sync for SafeRefCell {} + +impl SafeRefCell { + const fn new(t: T) -> Self { + Self(RefCell::new(t)) + } +} + +#[allow(clippy::declare_interior_mutable_const)] +const DEFAULT_CPU: SafeRefCell = SafeRefCell::new(Cpu::new()); + +static CPUS: [SafeRefCell; CPU_NUM] = [DEFAULT_CPU; CPU_NUM]; + +pub fn mycpu() -> RefMut<'static, Cpu> { + CPUS[hart_id()].0.borrow_mut() +} + +// push_off/pop_off are like intr_off()/intr_on() except that they are matched: +// it takes two pop_off()s to undo two push_off()s. Also, if interrupts +// are initially off, then push_off, pop_off leaves them off. +pub(crate) fn push_off() { + let old = is_interrupt_enable(); + interrupt_disable(); + let mut cpu = mycpu(); + if cpu.noff == 0 { + cpu.interrupt_enable = old; + } + cpu.noff += 1; +} + +pub(crate) fn pop_off() { + let mut cpu = mycpu(); + if is_interrupt_enable() || cpu.noff < 1 { + panic!("pop_off"); + } + cpu.noff -= 1; + let should_enable = cpu.noff == 0 && cpu.interrupt_enable; + drop(cpu); + // NOTICE: intr_on() may lead to an immediate inerrupt, so we *MUST* drop(cpu) in advance. + if should_enable { + interrupt_enable(); + } +} + +pub struct KernelLockAction; +impl LockAction for KernelLockAction { + fn before_lock() { + push_off(); + } + fn after_lock() { + pop_off(); + } +} diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 116435c1..3dd9f0ac 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -13,7 +13,6 @@ extern crate alloc; #[macro_use] extern crate log; - use spin::Once; use basemachine::MachineInfo; diff --git a/kernel/src/memory/map.rs b/kernel/src/memory/map.rs index 05197109..e64f0d4b 100644 --- a/kernel/src/memory/map.rs +++ b/kernel/src/memory/map.rs @@ -183,7 +183,14 @@ pub fn do_munmap(start: usize, len: usize) -> isize { /// 函数成功执行后将返回所创建的内存映射区的首地址;否则返回错误类型。 /// Reference: [do_mmap](https://man7.org/linux/man-pages/man2/mmap.2.html) #[syscall_func(222)] -pub fn do_mmap(start: usize, len: usize, prot: u32, flags: u32, fd: usize, offset: usize) -> AlienResult { +pub fn do_mmap( + start: usize, + len: usize, + prot: u32, + flags: u32, + fd: usize, + offset: usize, +) -> AlienResult { let process = current_task().unwrap(); let mut process_inner = process.access_inner(); let prot = ProtFlags::from_bits_truncate(prot); @@ -192,7 +199,9 @@ pub fn do_mmap(start: usize, len: usize, prot: u32, flags: u32, fd: usize, offse "mmap: start: {:#x}, len: {:#x}, prot: {:?}, flags: {:?}, fd: {}, offset: {:#x}", start, len, prot, flags, fd, offset ); - process_inner.add_mmap(start, len, prot, flags, fd, offset).map(|addr| addr as isize) + process_inner + .add_mmap(start, len, prot, flags, fd, offset) + .map(|addr| addr as isize) } /// 一个系统调用,用于修改内存映射的保护位,从而修改对内存映射的访问权限。 diff --git a/kernel/src/memory/vmm.rs b/kernel/src/memory/vmm.rs index bb4c9b2b..c74bb90b 100644 --- a/kernel/src/memory/vmm.rs +++ b/kernel/src/memory/vmm.rs @@ -426,10 +426,14 @@ pub fn build_elf_address_space( }); // 地址向上取整对齐4 - let ceil_addr = align_up_4k(break_addr+FRAME_SIZE); + let ceil_addr = align_up_4k(break_addr + FRAME_SIZE); // 留出一个用户栈的位置+隔离页 let top = ceil_addr + USER_STACK_SIZE + FRAME_SIZE; - warn!("user stack: {:#x} - {:#x}", top - USER_STACK_SIZE - FRAME_SIZE, top-FRAME_SIZE); + warn!( + "user stack: {:#x} - {:#x}", + top - USER_STACK_SIZE - FRAME_SIZE, + top - FRAME_SIZE + ); // map user stack address_space .map_region_no_target( @@ -442,7 +446,7 @@ pub fn build_elf_address_space( .unwrap(); // 初始化一个有效页 address_space - .validate(VirtAddr::from(top - FRAME_SIZE * 2 ), "RWUVAD".into()) + .validate(VirtAddr::from(top - FRAME_SIZE * 2), "RWUVAD".into()) .unwrap(); let heap_bottom = top; // align to 4k diff --git a/kernel/src/net/port.rs b/kernel/src/net/port.rs index aeab125b..151c2f8f 100644 --- a/kernel/src/net/port.rs +++ b/kernel/src/net/port.rs @@ -1,8 +1,8 @@ //! 现为将网络异常类型 [`NetError`] 转为 系统异常类型 [`LinuxErrno`]的模块。原为定义端口全局变量和操作的模块。 use crate::error::AlienError; -use pconst::LinuxErrno; use netcore::common::NetError; +use pconst::LinuxErrno; /// 现为将网络异常类型 [`NetError`] 转为 系统异常类型 [`LinuxErrno`]。 pub fn neterror2alien(error: NetError) -> AlienError { diff --git a/kernel/src/net/socket.rs b/kernel/src/net/socket.rs index 74be92ce..9f2b785e 100644 --- a/kernel/src/net/socket.rs +++ b/kernel/src/net/socket.rs @@ -19,11 +19,11 @@ use alloc::boxed::Box; use alloc::sync::Arc; use core::fmt::{Debug, Formatter}; use core::net::SocketAddr; +use netcore::tcp::TcpSocket; +use netcore::udp::UdpSocket; use pconst::io::{OpenFlags, PollEvents, SeekFrom}; use pconst::net::{Domain, SocketType}; use pconst::LinuxErrno; -use netcore::tcp::TcpSocket; -use netcore::udp::UdpSocket; use vfscore::dentry::VfsDentry; use vfscore::inode::VfsInode; use vfscore::utils::VfsFileStat; @@ -69,8 +69,8 @@ impl SocketFileExt for SocketFile { impl File for SocketFile { fn read(&self, buf: &mut [u8]) -> AlienResult { - if buf.len()==0{ - return Ok(0) + if buf.len() == 0 { + return Ok(0); } netcore::poll_interfaces(); let socket = self.get_socketdata().unwrap(); @@ -83,8 +83,8 @@ impl File for SocketFile { } fn write(&self, buf: &[u8]) -> AlienResult { - if buf.len()==0{ - return Ok(0) + if buf.len() == 0 { + return Ok(0); } info!("socket_file_write: buf_len:{:?}", buf.len()); netcore::poll_interfaces(); diff --git a/kernel/src/panic.rs b/kernel/src/panic.rs index 3d6d2601..e2c2a26b 100644 --- a/kernel/src/panic.rs +++ b/kernel/src/panic.rs @@ -1,15 +1,15 @@ //! panic 处理 -use crate::sbi::{system_shutdown}; +use crate::sbi::system_shutdown; use crate::trace::find_symbol_with_addr; use core::panic::PanicInfo; use core::sync::atomic::AtomicBool; -use tracer::{Tracer, TracerProvider}; #[cfg(all(not(feature = "debug-eh-frame"), not(feature = "debug-frame-point")))] use tracer::CompilerTracer; -#[cfg(feature = "debug-frame-point")] -use tracer::FramePointTracer; #[cfg(feature = "debug-eh-frame")] use tracer::DwarfTracer; +#[cfg(feature = "debug-frame-point")] +use tracer::FramePointTracer; +use tracer::{Tracer, TracerProvider}; /// 递归标志 static RECURSION: AtomicBool = AtomicBool::new(false); @@ -45,7 +45,6 @@ impl TracerProvider for TracerProviderImpl { } } - #[cfg(feature = "debug-eh-frame")] extern "C" { fn kernel_eh_frame(); @@ -84,7 +83,7 @@ fn back_trace() { #[cfg(feature = "debug-frame-point")] let tracer = FramePointTracer::new(TracerProviderImpl); #[cfg(feature = "debug-eh-frame")] - let tracer = DwarfTracer::new(DwarfProviderImpl,TracerProviderImpl); + let tracer = DwarfTracer::new(DwarfProviderImpl, TracerProviderImpl); for x in tracer.trace() { println!("[{:#x}] (+{:0>4x}) {}", x.func_addr, x.bias, x.func_name); } diff --git a/kernel/src/print/console.rs b/kernel/src/print/console.rs index 1960beea..4162923b 100644 --- a/kernel/src/print/console.rs +++ b/kernel/src/print/console.rs @@ -77,7 +77,7 @@ impl Write for Stdout { } struct MStdout; -impl Write for MStdout{ +impl Write for MStdout { fn write_str(&mut self, s: &str) -> Result { s.as_bytes().iter().for_each(|x| { console_putchar(*x); @@ -107,7 +107,6 @@ macro_rules! mprintln { concat!($fmt, "\n"), $($arg)*)); } - /// 输出函数 /// 对参数进行输出 主要使用在输出相关的宏中 如println pub fn __print(args: Arguments) { diff --git a/kernel/src/task/cpu.rs b/kernel/src/task/cpu.rs index 8108e9ab..2628ab4d 100644 --- a/kernel/src/task/cpu.rs +++ b/kernel/src/task/cpu.rs @@ -2,7 +2,7 @@ use alloc::string::{String, ToString}; use alloc::sync::Arc; use alloc::vec::Vec; -use core::cell::{UnsafeCell}; +use core::cell::UnsafeCell; use smpscheduler::{FifoSmpScheduler, FifoTask, ScheduleHart}; use spin::Lazy; diff --git a/kernel/src/task/mod.rs b/kernel/src/task/mod.rs index 77e5e576..37b2f6c7 100644 --- a/kernel/src/task/mod.rs +++ b/kernel/src/task/mod.rs @@ -30,7 +30,7 @@ pub static INIT_PROCESS: Lazy> = Lazy::new(|| { let mut data = Vec::new(); read_all("/bin/init", &mut data); // let data = INIT; - assert!(data.len()>0); + assert!(data.len() > 0); let task = Task::from_elf("/bin/init", data.as_slice()).unwrap(); Arc::new(task) }); diff --git a/kernel/src/task/task.rs b/kernel/src/task/task.rs index 3bb53a91..ea46e10b 100644 --- a/kernel/src/task/task.rs +++ b/kernel/src/task/task.rs @@ -1085,7 +1085,10 @@ impl TaskInner { let fd = if flags.contains(MapFlags::MAP_ANONYMOUS) { None } else { - let file = self.fd_table.lock().get(fd) + let file = self + .fd_table + .lock() + .get(fd) .map_err(|_| LinuxErrno::EBADF)? .ok_or(LinuxErrno::EBADF)?; // EBADF Some(file) diff --git a/kernel/src/trap/exception.rs b/kernel/src/trap/exception.rs index 03d7448f..06cfb348 100644 --- a/kernel/src/trap/exception.rs +++ b/kernel/src/trap/exception.rs @@ -3,7 +3,7 @@ //! 目前包括系统调用异常处理 [`syscall_exception_handler`]、页错误异常处理 [`page_exception_handler`] (包括 //! 指令页错误异常处理 [`instruction_page_fault_exception_handler`]、 加载页错误异常处理[`load_page_fault_exception_handler`]、 //! 储存页错误异常处理 [`store_page_fault_exception_handler`]) 和 文件读入异常处理 [`trap_common_read_file`]。 -use crate::arch::{interrupt_enable}; +use crate::arch::interrupt_enable; use crate::error::{AlienError, AlienResult}; use crate::fs::file::File; use crate::task::{current_task, current_trap_frame}; diff --git a/kernel/src/trap/mod.rs b/kernel/src/trap/mod.rs index a4c27151..8ba41551 100644 --- a/kernel/src/trap/mod.rs +++ b/kernel/src/trap/mod.rs @@ -102,7 +102,7 @@ pub fn init_trap_subsystem() { pub trait TrapHandler { fn do_user_handle(&self); - fn do_kernel_handle(&self,sp:usize); + fn do_kernel_handle(&self, sp: usize); } impl TrapHandler for Trap { @@ -193,7 +193,7 @@ impl TrapHandler for Trap { } /// 内核态下的 trap 例程 - fn do_kernel_handle(&self,sp:usize) { + fn do_kernel_handle(&self, sp: usize) { let stval = stval::read(); let sepc = sepc::read(); match self { @@ -219,7 +219,7 @@ impl TrapHandler for Trap { Trap::Exception(_) => { panic!( "unhandled trap: {:?}, stval: {:#x?}, sepc: {:#x}, sp: {:#x}", - self, stval, sepc,sp + self, stval, sepc, sp ) } Trap::Interrupt(Interrupt::SupervisorExternal) => { @@ -305,7 +305,7 @@ pub fn check_task_timer_expired() { /// 只有在内核态下才能进入这个函数 /// 避免嵌套中断发生这里不会再开启中断 #[no_mangle] -pub fn kernel_trap_vector(sp:usize) { +pub fn kernel_trap_vector(sp: usize) { let sstatus = sstatus::read(); let spp = sstatus.spp(); if spp == SPP::User {