From dc6c5d0ded38915991d54f5680cc5a368f88d2e4 Mon Sep 17 00:00:00 2001 From: Yukai Wu Date: Sat, 25 Jan 2025 15:49:23 +0800 Subject: [PATCH] fatfs on ramdisk --- Cargo.lock | 28 +++++--- kernel/Cargo.toml | 1 + kernel/src/blockdev/ahci.rs | 0 kernel/src/blockdev/mod.rs | 2 + kernel/src/blockdev/ramdisk.rs | 117 +++++++++++++++++++++++++++++++++ kernel/src/lib.rs | 2 + kernel/src/main.rs | 2 + 7 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 kernel/src/blockdev/ahci.rs create mode 100644 kernel/src/blockdev/mod.rs create mode 100644 kernel/src/blockdev/ramdisk.rs diff --git a/Cargo.lock b/Cargo.lock index 9811720..c6f32e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,6 +6,7 @@ version = 4 name = "DoglinkOS-2nd" version = "0.0.2-20250105" dependencies = [ + "fatfs 0.4.0", "good_memory_allocator", "limine", "noto-sans-mono-bitmap", @@ -118,7 +119,7 @@ dependencies = [ "DoglinkOS-2nd", "anyhow", "argh", - "fatfs", + "fatfs 0.3.6", "gpt", "ovmf-prebuilt", "tempfile", @@ -147,9 +148,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cpufeatures" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] @@ -248,6 +249,15 @@ dependencies = [ "log", ] +[[package]] +name = "fatfs" +version = "0.4.0" +source = "git+https://github.com/rafalh/rust-fatfs?rev=c4bb76929eb115f228720631b4110f827b998653#c4bb76929eb115f228720631b4110f827b998653" +dependencies = [ + "bitflags 2.8.0", + "log", +] + [[package]] name = "filetime" version = "0.2.25" @@ -659,9 +669,9 @@ checksum = "a157657054ffe556d8858504af8a672a054a6e0bd9e8ee531059100c0fa11bb2" [[package]] name = "rustix" -version = "0.38.43" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ "bitflags 2.8.0", "errno", @@ -849,9 +859,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "11cd88e12b17c6494200a9c1b683a04fcac9573ed74cd1b62aeb2727c5592243" [[package]] name = "unicode-width" @@ -912,9 +922,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744018581f9a3454a9e15beb8a33b017183f1e7c0cd170232a2d1453b23a51c4" +checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b" dependencies = [ "getrandom", ] diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 6dc7990..c9f956b 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -12,3 +12,4 @@ spin = "0.9.8" x2apic = "0.4.3" x86_64 = "0.15.2" os-terminal = "0.5.8" +fatfs = { git = "https://github.com/rafalh/rust-fatfs", rev = "c4bb76929eb115f228720631b4110f827b998653", default-features = false, features = ["alloc", "lfn"] } diff --git a/kernel/src/blockdev/ahci.rs b/kernel/src/blockdev/ahci.rs new file mode 100644 index 0000000..e69de29 diff --git a/kernel/src/blockdev/mod.rs b/kernel/src/blockdev/mod.rs new file mode 100644 index 0000000..8f7d7dd --- /dev/null +++ b/kernel/src/blockdev/mod.rs @@ -0,0 +1,2 @@ +pub mod ramdisk; +pub mod ahci; diff --git a/kernel/src/blockdev/ramdisk.rs b/kernel/src/blockdev/ramdisk.rs new file mode 100644 index 0000000..2367c17 --- /dev/null +++ b/kernel/src/blockdev/ramdisk.rs @@ -0,0 +1,117 @@ +use alloc::alloc::{alloc, dealloc, Layout}; +use crate::println; +use fatfs::{format_volume, FormatVolumeOptions, FileSystem, FsOptions, IoBase, Read, Write, Seek, Error, SeekFrom}; + +pub struct RamDisk { + size_in_blocks: usize, + layout: Layout, + ptr: *mut u8, + cur_pos: usize, +} + +impl RamDisk { + pub fn new(size_in_blocks: usize) -> Self { + unsafe { + let layout = Layout::from_size_align(size_in_blocks * 512, 4).unwrap(); + let allocated = alloc(layout); + Self { + size_in_blocks, + layout, + ptr: allocated, + cur_pos: 0, + } + } + } +} + +impl Drop for RamDisk { + fn drop(&mut self) { + unsafe { +// println!("{:#?} {:?}", self.layout, self.ptr); + dealloc(self.ptr, self.layout); + } + } +} + +impl IoBase for RamDisk { + type Error = Error<()>; +} + +impl Read for RamDisk { + fn read(&mut self, buf: &mut [u8]) -> Result { + let will_read = if buf.len() < 512 { buf.len() } else { 512 }; + if self.cur_pos + will_read < self.size_in_blocks * 512 { + unsafe { + core::ptr::copy(self.ptr.add(self.cur_pos), buf.as_mut_ptr(), will_read); + } + self.cur_pos += will_read; + Ok(will_read) + } else { + Err(Error::Io(())) + } + } +} + +impl Write for RamDisk { + fn write(&mut self, buf: &[u8]) -> Result { + let will_write = if buf.len() < 512 { buf.len() } else { 512 }; + if self.cur_pos <= self.size_in_blocks * 512 { + unsafe { + core::ptr::copy(buf.as_ptr(), self.ptr.add(self.cur_pos), will_write); + } + self.cur_pos += will_write; + Ok(will_write) + } else { + Err(Error::Io(())) + } + } + + fn flush(&mut self) -> Result<(), Self::Error> { + Ok(()) + } +} + +impl Seek for RamDisk { + fn seek(&mut self, frm: SeekFrom) -> Result { + let new_pos: i64; + match frm { + SeekFrom::Start(offset) => { + new_pos = offset as i64; + }, + SeekFrom::End(offset) => { + new_pos = (self.size_in_blocks * 512) as i64 + offset; + }, + SeekFrom::Current(offset) => { + new_pos = self.cur_pos as i64 + offset; + } + } + if new_pos < 0 || new_pos > (self.size_in_blocks * 512) as i64 { + Err(Error::Io(())) + } else { + self.cur_pos = new_pos as usize; + Ok(self.cur_pos as u64) + } + } +} + +pub fn test() { + let mut ramdisk = RamDisk::new(128); + format_volume(&mut ramdisk, FormatVolumeOptions::new()).expect("format volume failed"); + let fs = FileSystem::new(ramdisk, FsOptions::new()).expect("create fs failed"); + let root_dir = fs.root_dir(); + macro_rules! file_content { + ($name:expr, $content:expr) => { + { + let mut file = root_dir.create_file($name).expect("cre"); + file.write_all($content); + } + } + } + file_content!("zzjrabbit.txt", b"Hello, FAT!"); + file_content!("text.txt", b"ADG"); + for f in root_dir.iter() { + let e = f.unwrap(); + println!("Name: {}, Size: {}", e.file_name(), e.len()); + } +// println!("{:#?}", root_dir); +} diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 342fc8f..e9f51ef 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -1,6 +1,7 @@ #![no_std] #![feature(abi_x86_interrupt)] #![feature(slice_take)] +#![feature(array_ptr_get)] extern crate alloc; pub mod acpi; @@ -10,3 +11,4 @@ pub mod cpu; pub mod int; pub mod mm; pub mod pcie; +pub mod blockdev; diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 7d41cd2..84ba2d9 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -50,6 +50,8 @@ extern "C" fn kmain() -> ! { init_ioapic(parse_madt()); show_cpu_info(); doit(); + println!("\x1b[31mCOLOR\x1b[0m"); + DoglinkOS_2nd::blockdev::ramdisk::test(); hang(); }