diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1be6baa5..ebdba0fe 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -30,7 +30,7 @@ jobs: - uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly-2020-01-17 + toolchain: nightly-2020-03-23 components: rust-src, llvm-tools-preview - name: Cache QEMU diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 775ff6e2..09cd418a 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -107,9 +107,10 @@ dependencies = [ [[package]] name = "buddy_system_allocator" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -331,7 +332,7 @@ version = "0.1.2" dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "uefi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", "xmas-elf 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -348,7 +349,7 @@ dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "bitmap-allocator 0.1.0 (git+https://github.com/rcore-os/bitmap-allocator)", "bitvec 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", - "buddy_system_allocator 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "buddy_system_allocator 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", "compression 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "device_tree 1.0.3 (git+https://github.com/rcore-os/device_tree-rs)", @@ -362,11 +363,11 @@ dependencies = [ "raw-cpuid 7.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "rboot 0.1.2", "rcore-console 0.1.0 (git+https://github.com/rcore-os/rcore-console?rev=b7bacf9)", - "rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=e17b27b)", - "rcore-fs-devfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=e17b27b)", - "rcore-fs-mountfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=e17b27b)", - "rcore-fs-ramfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=e17b27b)", - "rcore-fs-sfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=e17b27b)", + "rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac)", + "rcore-fs-devfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac)", + "rcore-fs-mountfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac)", + "rcore-fs-ramfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac)", + "rcore-fs-sfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac)", "rcore-memory 0.1.0", "rcore-thread 0.1.0 (git+https://github.com/rcore-os/rcore-thread?rev=d727949b)", "riscv 0.5.0 (git+https://github.com/rcore-os/riscv)", @@ -392,7 +393,7 @@ dependencies = [ [[package]] name = "rcore-fs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs?rev=e17b27b#e17b27b3d257f23ed8ba43d902c909d23245a008" +source = "git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac#7f5eeac8b77f6bab11f6f2ce631a194bee658555" dependencies = [ "filetime 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -402,42 +403,42 @@ dependencies = [ [[package]] name = "rcore-fs-devfs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs?rev=e17b27b#e17b27b3d257f23ed8ba43d902c909d23245a008" +source = "git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac#7f5eeac8b77f6bab11f6f2ce631a194bee658555" dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=e17b27b)", + "rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rcore-fs-mountfs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs?rev=e17b27b#e17b27b3d257f23ed8ba43d902c909d23245a008" +source = "git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac#7f5eeac8b77f6bab11f6f2ce631a194bee658555" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=e17b27b)", + "rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rcore-fs-ramfs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs?rev=e17b27b#e17b27b3d257f23ed8ba43d902c909d23245a008" +source = "git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac#7f5eeac8b77f6bab11f6f2ce631a194bee658555" dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=e17b27b)", + "rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rcore-fs-sfs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs?rev=e17b27b#e17b27b3d257f23ed8ba43d902c909d23245a008" +source = "git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac#7f5eeac8b77f6bab11f6f2ce631a194bee658555" dependencies = [ "bitvec 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=e17b27b)", + "rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -496,6 +497,16 @@ dependencies = [ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustversion" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "semver" version = "0.9.0" @@ -681,6 +692,15 @@ dependencies = [ "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "x86_64" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "xmas-elf" version = "0.7.0" @@ -708,7 +728,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum bitmap-allocator 0.1.0 (git+https://github.com/rcore-os/bitmap-allocator)" = "" "checksum bitvec 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1fe4300c1d7a9ea6f3e3f39c10b39862bb79e1175c0572b6b49539a30e5562f5" -"checksum buddy_system_allocator 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "59da15ef556589ee78370281d75b67f2d69ed26465ec0e0f3961e2021502426f" +"checksum buddy_system_allocator 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "09072aa89a810228c822e132e4639ff17bab014ba5b2dce5270a6331ff1963ca" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" "checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" @@ -738,17 +758,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "30a9d219c32c9132f7be513c18be77c9881c7107d2ab5569d205a6a0f0e6dc7d" "checksum raw-cpuid 7.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4a349ca83373cfa5d6dbb66fd76e58b2cca08da71a5f6400de0a0a6a9bceeaf" "checksum rcore-console 0.1.0 (git+https://github.com/rcore-os/rcore-console?rev=b7bacf9)" = "" -"checksum rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=e17b27b)" = "" -"checksum rcore-fs-devfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=e17b27b)" = "" -"checksum rcore-fs-mountfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=e17b27b)" = "" -"checksum rcore-fs-ramfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=e17b27b)" = "" -"checksum rcore-fs-sfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=e17b27b)" = "" +"checksum rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac)" = "" +"checksum rcore-fs-devfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac)" = "" +"checksum rcore-fs-mountfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac)" = "" +"checksum rcore-fs-ramfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac)" = "" +"checksum rcore-fs-sfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?rev=7f5eeac)" = "" "checksum rcore-thread 0.1.0 (git+https://github.com/rcore-os/rcore-thread?rev=d727949b)" = "" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum register 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e10f31b6d2299e5620986ad9fcdd66463e125ad72af4f403f9aedf7592d5ccdb" "checksum riscv 0.5.0 (git+https://github.com/rcore-os/riscv)" = "" "checksum rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc874b127765f014d792f16763a81245ab80500e2ad921ed4ee9e82481ee08fe" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum smoltcp 0.5.0 (git+https://github.com/rcore-os/smoltcp?rev=5bd87c7c)" = "" @@ -774,5 +795,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum x86 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f21eecbd666e3a8edbf0b26d36f270f7a613d8986ca0eafb8205e324f7336dab" "checksum x86_64 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1f27d9168654aee1b0c1b73746caeb4aa33248f8b8c8f6e100e697fcc2a794b2" "checksum x86_64 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5d9e3e26fcb51976eafa310e8f2b7a5a83ae8c185443efe50cbc6534a4fffa0d" +"checksum x86_64 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4206b60c9f99766329b66962aa8ddc01df6c7edd02edc046b7a69d5df9fcdbcf" "checksum xmas-elf 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e74de9a366f6ab8c405fa6b371d9ac24943921fa14b3d64afcb202065c405f11" "checksum zero 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f1bc8a6b2005884962297587045002d8cfb8dcec9db332f4ca216ddc5de82c5" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 1f220f82..7163b8e1 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -66,11 +66,11 @@ bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator" } rcore-console = { git = "https://github.com/rcore-os/rcore-console", rev = "b7bacf9", default-features = false } rcore-memory = { path = "../crate/memory" } rcore-thread = { git = "https://github.com/rcore-os/rcore-thread", rev = "d727949b" } -rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "e17b27b" } -rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "e17b27b" } -rcore-fs-ramfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "e17b27b" } -rcore-fs-mountfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "e17b27b" } -rcore-fs-devfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "e17b27b" } +rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7f5eeac" } +rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7f5eeac" } +rcore-fs-ramfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7f5eeac" } +rcore-fs-mountfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7f5eeac" } +rcore-fs-devfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7f5eeac" } compression = { version = "0.1.4", default-features = false, features = ["gzip"] } diff --git a/kernel/src/drivers/console/mod.rs b/kernel/src/drivers/console/mod.rs index f2ccb5df..eb371e44 100644 --- a/kernel/src/drivers/console/mod.rs +++ b/kernel/src/drivers/console/mod.rs @@ -12,7 +12,7 @@ pub static CONSOLE: Mutex> = Mutex::new(None); /// Initialize console driver pub fn init() { if cfg!(feature = "consolegraphic") { - if let Some(fb) = FRAME_BUFFER.lock().take() { + if let Some(fb) = FRAME_BUFFER.write().take() { // FIXME: now take FrameBuffer out of global variable, then move into Console let console = Console::on_frame_buffer(fb.fb_info.xres, fb.fb_info.yres, fb); *CONSOLE.lock() = Some(console); diff --git a/kernel/src/drivers/gpu/fb.rs b/kernel/src/drivers/gpu/fb.rs index e9b43472..de3a300d 100644 --- a/kernel/src/drivers/gpu/fb.rs +++ b/kernel/src/drivers/gpu/fb.rs @@ -3,7 +3,7 @@ use alloc::string::String; use core::fmt; use log::*; -use spin::Mutex; +use spin::RwLock; /// Framebuffer information #[repr(C)] @@ -194,23 +194,48 @@ impl Framebuffer { } } - /// Copy buffer `[src_off .. src_off + size]` to `[dst_off .. dst_off + size]`. - /// `dst_off`, `src_off` and `size` must be aligned with `usize`. - pub fn copy(&mut self, dst_off: usize, src_off: usize, size: usize) { - const USIZE: usize = core::mem::size_of::(); - let mut dst = self.base_addr() + dst_off; - let mut src = self.base_addr() + src_off; - let src_end = src + size; - while src < src_end { - unsafe { *(dst as *mut usize) = *(src as *mut usize) } - dst += USIZE; - src += USIZE; + /// Read buffer data starts at `offset` to `buf`. + pub fn read_at(&self, offset: usize, buf: &mut [u8]) -> usize { + if offset >= self.fb_info.screen_size { + return 0; } + let count = buf.len().min(self.fb_info.screen_size - offset); + let data = unsafe { + core::slice::from_raw_parts((self.buf.base_addr + offset) as *const u8, count) + }; + buf[..count].copy_from_slice(&data); + count } - /// Fill buffer `[offset .. offset + size]` with `pixel`. - /// `offset` and `size` must be aligned with `usize`. - pub fn fill(&mut self, offset: usize, size: usize, pixel: u32) { + /// Write buffer data starts at `offset` to `buf`. + pub fn write_at(&mut self, offset: usize, buf: &[u8]) -> usize { + if offset > self.fb_info.screen_size { + return 0; + } + let count = buf.len().min(self.fb_info.screen_size - offset); + let data = unsafe { + core::slice::from_raw_parts_mut((self.buf.base_addr + offset) as *mut u8, count) + }; + data.copy_from_slice(&buf[..count]); + count + } + + /// Copy buffer `[src_off .. src_off + count]` to `[dst_off .. dst_off + count]`. + pub fn copy(&mut self, dst_off: usize, src_off: usize, count: usize) { + let size = self.fb_info.screen_size; + if src_off >= size || dst_off >= size { + return; + } + let count = count.min(size - src_off).min(size - dst_off); + unsafe { + let buf = core::slice::from_raw_parts_mut(self.buf.base_addr as *mut u8, size); + buf.copy_within(src_off..src_off + count, dst_off) + }; + } + + /// Fill buffer `[offset .. offset + count]` with `pixel`. + /// `offset` and `count` must be aligned with `usize`. + pub fn fill(&mut self, offset: usize, count: usize, pixel: u32) { const USIZE: usize = core::mem::size_of::(); let mut value: usize = 0; let depth = self.fb_info.depth as usize; @@ -221,8 +246,13 @@ impl Framebuffer { value += pixel as usize & mask; } + let offset = offset & !(USIZE - 1); + if offset >= self.fb_info.screen_size { + return; + } + let count = (count & !(USIZE - 1)).min(self.fb_info.screen_size - offset); let mut start = self.base_addr() + offset; - let end = start + size; + let end = start + count; while start < end { unsafe { *(start as *mut usize) = value } start += USIZE; @@ -279,7 +309,7 @@ impl ColorEncode for Rgb888 { } } -pub static FRAME_BUFFER: Mutex> = Mutex::new(None); +pub static FRAME_BUFFER: RwLock> = RwLock::new(None); /// Initialize framebuffer /// @@ -287,5 +317,5 @@ pub static FRAME_BUFFER: Mutex> = Mutex::new(None); pub fn init(info: FramebufferInfo) { let fb = Framebuffer::new(info); info!("framebuffer: init end\n{:#x?}", fb); - *FRAME_BUFFER.lock() = Some(fb); + *FRAME_BUFFER.write() = Some(fb); } diff --git a/kernel/src/fs/vga.rs b/kernel/src/fs/devfs/fbdev.rs similarity index 76% rename from kernel/src/fs/vga.rs rename to kernel/src/fs/devfs/fbdev.rs index 647b6c23..d761ccef 100755 --- a/kernel/src/fs/vga.rs +++ b/kernel/src/fs/devfs/fbdev.rs @@ -1,30 +1,43 @@ -use rcore_fs::vfs::*; +//! Implement INode for framebuffer use crate::drivers::gpu::fb::{ColorFormat, FramebufferInfo, FRAME_BUFFER}; +use crate::syscall::MmapProt; use core::any::Any; -#[derive(Default)] -pub struct Vga; +use rcore_fs::vfs::*; +use rcore_memory::memory_set::handler::Linear; -impl INode for Vga { - fn read_at(&self, _offset: usize, _buf: &mut [u8]) -> Result { - Err(FsError::NotSupported) - } - fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result { - info!("the _offset is {} {}", _offset, _buf[0]); - let lock = FRAME_BUFFER.lock(); - if let Some(ref frame_buffer) = *lock { - use core::slice; - let frame_buffer_data = unsafe { - slice::from_raw_parts_mut( - frame_buffer.base_addr() as *mut u8, - frame_buffer.framebuffer_size(), - ) - }; - frame_buffer_data.copy_from_slice(&_buf); - Ok(frame_buffer.framebuffer_size()) +#[derive(Default)] +pub struct Fbdev; + +impl INode for Fbdev { + fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result { + info!( + "fbdev read_at: offset={:#x} buf_len={:#x}", + offset, + buf.len() + ); + if let Some(fb) = FRAME_BUFFER.read().as_ref() { + Ok(fb.read_at(offset, buf)) } else { - Err(FsError::EntryNotFound) + Err(FsError::NoDevice) + } + } + fn write_at(&self, offset: usize, buf: &[u8]) -> Result { + info!( + "fbdev write_at: offset={:#x} buf_len={:#x}", + offset, + buf.len() + ); + if let Some(fb) = FRAME_BUFFER.write().as_mut() { + let count = fb.write_at(offset, buf); + if count == buf.len() { + Ok(count) + } else { + Err(FsError::NoDeviceSpace) + } + } else { + Err(FsError::NoDevice) } } fn poll(&self) -> Result { @@ -39,18 +52,18 @@ impl INode for Vga { Ok(Metadata { dev: 0, inode: 0, - size: 0x24000, + size: 0, blk_size: 0, blocks: 0, atime: Timespec { sec: 0, nsec: 0 }, mtime: Timespec { sec: 0, nsec: 0 }, ctime: Timespec { sec: 0, nsec: 0 }, - type_: FileType::SymLink, - mode: 0, - nlinks: 0, + type_: FileType::CharDevice, + mode: 0o660, + nlinks: 1, uid: 0, gid: 0, - rdev: 0, + rdev: make_rdev(29, 0), }) } fn io_control(&self, cmd: u32, data: usize) -> Result<()> { @@ -60,14 +73,14 @@ impl INode for Vga { match cmd { FBIOGET_FSCREENINFO => { let fb_fix_info = unsafe { &mut *(data as *mut FbFixScreeninfo) }; - if let Some(fb) = FRAME_BUFFER.lock().as_ref() { + if let Some(fb) = FRAME_BUFFER.read().as_ref() { fb_fix_info.fill_from(&fb.fb_info); } Ok(()) } FBIOGET_VSCREENINFO => { let fb_var_info = unsafe { &mut *(data as *mut FbVarScreeninfo) }; - if let Some(fb) = FRAME_BUFFER.lock().as_ref() { + if let Some(fb) = FRAME_BUFFER.read().as_ref() { fb_var_info.fill_from(&fb.fb_info); } Ok(()) @@ -78,6 +91,28 @@ impl INode for Vga { } } } + fn mmap(&self, area: MMapArea) -> Result<()> { + let attr = MmapProt::from_bits_truncate(area.prot).to_attr(); + #[cfg(target_arch = "aarch64")] + let attr = attr.mmio(crate::arch::paging::MMIOType::NormalNonCacheable as u8); + + if let Some(fb) = FRAME_BUFFER.read().as_ref() { + if area.offset + area.end_vaddr - area.start_vaddr > fb.framebuffer_size() { + return Err(FsError::NoDeviceSpace); + } + let thread = unsafe { crate::process::current_thread() }; + thread.vm.lock().push( + area.start_vaddr, + area.end_vaddr, + attr, + Linear::new((fb.paddr() + area.offset - area.start_vaddr) as isize), + "mmap_file", + ); + Ok(()) + } else { + Err(FsError::NoDevice) + } + } fn as_any_ref(&self) -> &dyn Any { self } diff --git a/kernel/src/fs/devfs/mod.rs b/kernel/src/fs/devfs/mod.rs new file mode 100644 index 00000000..38729d42 --- /dev/null +++ b/kernel/src/fs/devfs/mod.rs @@ -0,0 +1,9 @@ +//! Device file system mounted at /dev + +mod fbdev; +mod random; +mod stdio; + +pub use fbdev::*; +pub use random::*; +pub use stdio::*; diff --git a/kernel/src/fs/random.rs b/kernel/src/fs/devfs/random.rs similarity index 98% rename from kernel/src/fs/random.rs rename to kernel/src/fs/devfs/random.rs index 13c2345c..425774e0 100644 --- a/kernel/src/fs/random.rs +++ b/kernel/src/fs/devfs/random.rs @@ -7,7 +7,7 @@ use rcore_fs::vfs::*; use crate::sync::SpinNoIrqLock as Mutex; -pub struct RandomINodeData { +struct RandomINodeData { seed: u32, } diff --git a/kernel/src/fs/stdio.rs b/kernel/src/fs/devfs/stdio.rs similarity index 99% rename from kernel/src/fs/stdio.rs rename to kernel/src/fs/devfs/stdio.rs index 0c5d76d3..6014aba6 100644 --- a/kernel/src/fs/stdio.rs +++ b/kernel/src/fs/devfs/stdio.rs @@ -5,7 +5,7 @@ use core::any::Any; use rcore_fs::vfs::*; -use super::ioctl::*; +use crate::fs::ioctl::*; use crate::sync::Condvar; use crate::sync::SpinNoIrqLock as Mutex; diff --git a/kernel/src/fs/file.rs b/kernel/src/fs/file.rs index 888f350e..7c68f4a7 100644 --- a/kernel/src/fs/file.rs +++ b/kernel/src/fs/file.rs @@ -1,10 +1,14 @@ //! File handle for process +use crate::memory::GlobalFrameAlloc; +use crate::process::{current_thread, INodeForMap}; +use crate::syscall::MmapProt; use crate::thread; use alloc::{string::String, sync::Arc}; use core::fmt; -use rcore_fs::vfs::{FsError, INode, Metadata, PollStatus, Result}; +use rcore_fs::vfs::{FileType, FsError, INode, MMapArea, Metadata, PollStatus, Result}; +use rcore_memory::memory_set::handler::File; #[derive(Clone)] pub struct FileHandle { @@ -139,6 +143,32 @@ impl FileHandle { self.inode.io_control(cmd, arg) } + pub fn mmap(&mut self, area: MMapArea) -> Result<()> { + info!("mmap file path is {}", self.path); + match self.inode.metadata()?.type_ { + FileType::File => { + let prot = MmapProt::from_bits_truncate(area.prot); + let thread = unsafe { current_thread() }; + thread.vm.lock().push( + area.start_vaddr, + area.end_vaddr, + prot.to_attr(), + File { + file: INodeForMap(self.inode.clone()), + mem_start: area.start_vaddr, + file_start: area.offset, + file_end: area.offset + area.end_vaddr - area.start_vaddr, + allocator: GlobalFrameAlloc, + }, + "mmap_file", + ); + Ok(()) + } + FileType::CharDevice => self.inode.mmap(area), + _ => Err(FsError::NotSupported), + } + } + pub fn inode(&self) -> Arc { self.inode.clone() } diff --git a/kernel/src/fs/file_like.rs b/kernel/src/fs/file_like.rs index 0d91fc38..24844b24 100644 --- a/kernel/src/fs/file_like.rs +++ b/kernel/src/fs/file_like.rs @@ -6,7 +6,7 @@ use crate::fs::epoll::EpollInstance; use crate::net::Socket; use crate::syscall::{SysError, SysResult}; use alloc::boxed::Box; -use rcore_fs::vfs::PollStatus; +use rcore_fs::vfs::{MMapArea, PollStatus}; // TODO: merge FileLike to FileHandle ? // TODO: fix dup and remove Clone @@ -57,6 +57,13 @@ impl FileLike { } } } + pub fn mmap(&mut self, area: MMapArea) -> SysResult { + match self { + FileLike::File(file) => file.mmap(area)?, + _ => return Err(SysError::ENOSYS), + }; + Ok(0) + } pub fn poll(&self) -> Result { let status = match self { FileLike::File(file) => file.poll()?, @@ -70,7 +77,6 @@ impl FileLike { }; Ok(status) } - pub fn fcntl(&mut self, cmd: usize, arg: usize) -> SysResult { match self { FileLike::File(file) => file.fcntl(cmd, arg)?, diff --git a/kernel/src/fs/mod.rs b/kernel/src/fs/mod.rs index 4fed389e..f98706a0 100644 --- a/kernel/src/fs/mod.rs +++ b/kernel/src/fs/mod.rs @@ -1,19 +1,23 @@ use alloc::{sync::Arc, vec::Vec}; use rcore_fs::vfs::*; -use rcore_fs_devfs::{special::*, DevFS}; +use rcore_fs_devfs::{ + special::{NullINode, ZeroINode}, + DevFS, +}; use rcore_fs_mountfs::MountFS; use rcore_fs_ramfs::RamFS; use rcore_fs_sfs::SimpleFileSystem; +use self::devfs::{Fbdev, RandomINode}; + +pub use self::devfs::{STDIN, STDOUT}; pub use self::file::*; pub use self::file_like::*; pub use self::pipe::Pipe; pub use self::pseudo::*; -pub use self::random::*; -pub use self::stdio::{STDIN, STDOUT}; -pub use self::vga::*; +mod devfs; mod device; pub mod epoll; mod file; @@ -21,9 +25,6 @@ mod file_like; mod ioctl; mod pipe; mod pseudo; -mod random; -mod stdio; -pub mod vga; // Hard link user programs #[cfg(feature = "link_user")] @@ -83,8 +84,9 @@ lazy_static! { let devfs = DevFS::new(); devfs.add("null", Arc::new(NullINode::default())).expect("failed to mknod /dev/null"); devfs.add("zero", Arc::new(ZeroINode::default())).expect("failed to mknod /dev/zero"); - devfs.add("random", Arc::new(RandomINode::new(false))).expect("failed to mknod /dev/zero"); - devfs.add("urandom", Arc::new(RandomINode::new(true))).expect("failed to mknod /dev/zero"); + devfs.add("random", Arc::new(RandomINode::new(false))).expect("failed to mknod /dev/random"); + devfs.add("urandom", Arc::new(RandomINode::new(true))).expect("failed to mknod /dev/urandom"); + devfs.add("fb0", Arc::new(Fbdev::default())).expect("failed to mknod /dev/fb0"); // mount DevFS at /dev let dev = root.find(true, "dev").unwrap_or_else(|_| { diff --git a/kernel/src/fs/pseudo.rs b/kernel/src/fs/pseudo.rs index 44b8c6d6..8ae3b4ac 100644 --- a/kernel/src/fs/pseudo.rs +++ b/kernel/src/fs/pseudo.rs @@ -50,7 +50,7 @@ impl INode for Pseudo { ctime: Timespec { sec: 0, nsec: 0 }, type_: self.type_, mode: 0, - nlinks: 0, + nlinks: 1, uid: 0, gid: 0, rdev: 0, diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index 1c1a455b..f416feda 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -25,6 +25,7 @@ use crate::process::thread_manager; use core::mem::MaybeUninit; use rcore_fs::vfs::INode; +#[allow(dead_code)] pub struct Thread { context: Context, kstack: KernelStack, diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index c5381ec1..abf48f37 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -1144,10 +1144,6 @@ impl Process { "/proc/self/exe" => { return Ok(Arc::new(Pseudo::new(&self.exec_path, FileType::SymLink))); } - "/dev/fb0" => { - info!("/dev/fb0 will be opened"); - return Ok(Arc::new(Vga::default())); - } _ => {} } let (fd_dir_path, fd_name) = split_path(&path); @@ -1573,7 +1569,7 @@ impl From for Stat { nlink: info.nlinks as u32, uid: info.uid as u32, gid: info.gid as u32, - rdev: 0, + rdev: info.rdev as u64, size: info.size as u64, blksize: info.blk_size as u32, blocks: info.blocks as u64, @@ -1604,7 +1600,7 @@ impl From for Stat { nlink: info.nlinks as u32, uid: info.uid as u32, gid: info.gid as u32, - rdev: 0, + rdev: info.rdev as u64, size: info.size as u64, blksize: info.blk_size as u32, blocks: info.blocks as u64, diff --git a/kernel/src/syscall/mem.rs b/kernel/src/syscall/mem.rs index 415481d5..48115a53 100644 --- a/kernel/src/syscall/mem.rs +++ b/kernel/src/syscall/mem.rs @@ -1,15 +1,15 @@ -use rcore_memory::memory_set::handler::{Delay, File, Linear}; +use rcore_fs::vfs::MMapArea; +use rcore_memory::memory_set::handler::Delay; use rcore_memory::memory_set::MemoryAttr; use rcore_memory::PAGE_SIZE; -use crate::memory::GlobalFrameAlloc; - use super::*; +use crate::memory::GlobalFrameAlloc; impl Syscall<'_> { pub fn sys_mmap( &mut self, - mut addr: usize, + addr: usize, len: usize, prot: usize, flags: usize, @@ -24,6 +24,7 @@ impl Syscall<'_> { ); let mut proc = self.process(); + let mut addr = addr; if addr == 0 { // although NULL can be a valid address // but in C, NULL is regarded as allocation failure @@ -49,49 +50,18 @@ impl Syscall<'_> { Delay::new(GlobalFrameAlloc), "mmap_anon", ); - return Ok(addr); + Ok(addr) } else { - let file = proc.get_file(fd)?; - info!("mmap path is {} ", &*file.path); - match &*file.path { - "/dev/fb0" => { - use crate::drivers::gpu::fb::FRAME_BUFFER; - let attr = prot.to_attr(); - #[cfg(feature = "board_raspi3")] - let attr = attr.mmio(crate::arch::paging::MMIOType::NormalNonCacheable as u8); - - if let Some(fb) = FRAME_BUFFER.lock().as_ref() { - self.vm().push( - addr, - addr + len, - attr, - Linear::new((fb.paddr() - addr) as isize), - "mmap_file", - ); - info!("mmap for /dev/fb0"); - return Ok(addr); - } else { - return Err(SysError::ENOENT); - } - } - _ => { - let inode = file.inode(); - self.vm().push( - addr, - addr + len, - prot.to_attr(), - File { - file: INodeForMap(inode), - mem_start: addr, - file_start: offset, - file_end: offset + len, - allocator: GlobalFrameAlloc, - }, - "mmap_file", - ); - return Ok(addr); - } + let file_like = proc.get_file_like(fd)?; + let area = MMapArea { + start_vaddr: addr, + end_vaddr: addr + len, + prot: prot.bits(), + flags: flags.bits(), + offset, }; + file_like.mmap(area)?; + Ok(addr) } } @@ -121,6 +91,7 @@ impl Syscall<'_> { Ok(0) } } + bitflags! { pub struct MmapProt: usize { /// Data cannot be accessed @@ -163,7 +134,7 @@ bitflags! { } impl MmapProt { - fn to_attr(self) -> MemoryAttr { + pub fn to_attr(self) -> MemoryAttr { let mut attr = MemoryAttr::default().user(); if self.contains(MmapProt::EXEC) { attr = attr.execute(); diff --git a/rboot b/rboot index 88b882bd..33a2d215 160000 --- a/rboot +++ b/rboot @@ -1 +1 @@ -Subproject commit 88b882bd65eb7d7604a87634dafd63f96ae1bf2f +Subproject commit 33a2d215957b704a26dab52484d75d47dbb49bdb diff --git a/rust-toolchain b/rust-toolchain index 17841400..d6c11b15 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2020-01-17 +nightly-2020-03-23 diff --git a/user b/user index c5387635..1bdaf05b 160000 --- a/user +++ b/user @@ -1 +1 @@ -Subproject commit c53876357b500f34fb2d75bb1816e824366cce6e +Subproject commit 1bdaf05bb37bd8f38063c5bc935906bf640b07b7