From 897775f63aeb2964152b323a43b2500e8ab286ab Mon Sep 17 00:00:00 2001 From: Julien THILLARD Date: Sat, 21 Mar 2026 21:56:22 +0100 Subject: [PATCH] Cleans library directory --- .gdbinit | 8 +- ilm.ld | 4 +- justfile | 54 ++++++---- library/justfile | 8 +- library/std/.gitignore | 1 - library/std/patches/sys/stdio/mod.sed | 4 + library/std/src/sys/stdio/survos.rs | 148 ++++++++++++++++++++++++++ src/process.rs | 11 ++ src/virtual_fs.rs | 2 +- src/virtual_fs/null.rs | 6 +- user.ld | 35 ++++++ user/shell/Cargo.toml | 1 - user/shell/src/main.rs | 2 + user/test_pic/src/main.rs | 10 +- 14 files changed, 253 insertions(+), 41 deletions(-) create mode 100644 library/std/patches/sys/stdio/mod.sed create mode 100644 library/std/src/sys/stdio/survos.rs create mode 100644 user.ld diff --git a/.gdbinit b/.gdbinit index cef7d31..e3bc8f2 100644 --- a/.gdbinit +++ b/.gdbinit @@ -1,6 +1,6 @@ -file target/riscv64/debug/kernel-rust +# file target/riscv64/debug/kernel-rust target remote localhost:1234 -break machine_mode_entry -# break *0x800bf000 -# add-symbol-file target/riscv64/debug/test_pic 0x800bf000 +# break machine_mode_entry +break *0x800cfdd8 +add-symbol-file target/riscv64/debug/test_pic 0x800cfdd8 c diff --git a/ilm.ld b/ilm.ld index 5bf4e02..73d05cd 100644 --- a/ilm.ld +++ b/ilm.ld @@ -16,11 +16,11 @@ SECTIONS { *(.text .text.*) } > RAM - .rodata : { + .rodata : ALIGN(8) { *(.rodata .rodata.*) } > RAM - .data : { + .data : ALIGN(8) { *(.data .data.*) } > RAM diff --git a/justfile b/justfile index c2753dc..087eece 100644 --- a/justfile +++ b/justfile @@ -2,39 +2,39 @@ release := "" qemu_flags := "" cargo_flags := "" + if release != "" { "--release" } else { "" } bin_path := if release != "" { "target/riscv64/release" } else { "target/riscv64/debug" } +GDB := "gf2" default: run mount_filesystem: @# Add some permissions to be able to do next operations without sudo - mountpoint -q mnt || sudo mount -o umask=0022,gid=$(id -g $USER),uid=$(id -u $USER) disk.img mnt - -sync_filesystem: - sync + mountpoint -q mnt || sudo mount -o umask=0022,gid=$(id -g),uid=$(id -u) disk.img mnt update-std: - @cd library/std && just update-std + @cd library/std && {{ just_executable() }} update-std build-sysroot: - @cd library/std && just build-sysroot + @cd library/std && {{ just_executable() }} build-sysroot build_user_prog prog: - RUSTFLAGS="-C relocation-model=pic -C link-arg=-pie --sysroot {{ justfile_directory() / "sysroot" }}" cargo b {{ cargo_flags }} --package {{ prog }} - riscv64-elf-strip {{ bin_path / prog }} - cp {{ bin_path / prog }} {{ "mnt/usr/bin" / prog }} + RUSTFLAGS="-Clink-arg=-Tuser.ld -C relocation-model=pic -C link-arg=-pie --sysroot {{ justfile_directory() / "sysroot" }}" \ + cargo b {{ cargo_flags }} --package {{ prog }} + cp {{ bin_path / prog }} {{ bin_path / prog + "-stripped" }} + if command -v riscv64-elf-strip >/dev/null 2>&1; then \ + riscv64-elf-strip {{ bin_path / prog + "-stripped" }}; \ + fi + cp {{ bin_path / prog + "-stripped" }} {{ "mnt/usr/bin" / prog }} -build: mount_filesystem (map_dir "user" f"just release=\"{{release}}\" cargo_flags=\"{{cargo_flags}}\" build_user_prog") +build: mount_filesystem + @for file in `ls user`; do \ + {{ just_executable() }} release="{{ release }}" cargo_flags="{{ cargo_flags }}" build_user_prog $file ; \ + done RUSTFLAGS="-Clink-arg=-Tilm.ld --sysroot {{ justfile_directory() / "sysroot" }}" cargo b {{ cargo_flags }} - just sync_filesystem + sync run: build (runner f"{{bin_path / "kernel-rust"}}") -map_dir dir recipe: - @for file in `ls {{ dir }}`; do \ - {{ recipe }} $file ; \ - done - -qemu := f"qemu-system-riscv64 \ +QEMU := f"qemu-system-riscv64 \ -machine virt \ -serial mon:stdio \ -device bochs-display \ @@ -47,17 +47,25 @@ qemu := f"qemu-system-riscv64 \ # -d guest_errors,unimp,int" perf: build - {{ qemu }} -perfmap -kernel {{ bin_path / "kernel-rust" }}& + {{ QEMU }} -perfmap -kernel {{ bin_path / "kernel-rust" }}& perf record --output=/tmp/perf.data --call-graph=dwarf -F 999 -p $(pidof qemu-system-riscv64) -- sleep 20; exit 0 cd /tmp && hotspot perf.data -gdb: build - {{ qemu }} -s -S -kernel {{ bin_path / "kernel-rust" }}& - gf2 +dbg: build + {{ QEMU }} -s -S -kernel {{ bin_path / "kernel-rust" }}& + {{ GDB }} + +dbg-user prog addr: build + {{ QEMU }} -s -S -kernel {{ bin_path / "kernel-rust" }}& + {{ GDB }} -nx \ + -ex "target remote localhost:1234" \ + -ex "break *{{ addr }}" \ + -ex "add-symbol-file target/riscv64/debug/{{ prog }} {{ addr }}" \ + -ex "c" runner args: - {{ qemu }} -kernel {{ args }} + {{ QEMU }} -kernel {{ args }} clean: - cd library && just clean + cd library && {{ just_executable() }} clean cargo clean diff --git a/library/justfile b/library/justfile index 300ad76..b637f74 100644 --- a/library/justfile +++ b/library/justfile @@ -44,7 +44,7 @@ STD_FILES := "\ sys/thread_local/no_threads.rs sys/thread_local/os.rs sys/time/mod.rs \ sys/time/unsupported.rs sys/backtrace.rs sys/cmath.rs \ sys/configure_builtins.rs sys/env_consts.rs sys/exit.rs sys/mod.rs thread" -KEEP_FILES := "sys sys/pal sys/pal/survos.rs sys/alloc sys/alloc/survos.rs" +KEEP_FILES := "survos.rs" setup-std: @echo "🔗 Linking root directories..." @@ -74,8 +74,9 @@ patch-std: done build-sysroot: + cargo clean RUSTFLAGS="-Zforce-unstable-if-unmarked -C relocation-model=pic -C link-arg=-pie" \ - cargo build --package std --target ../riscv64.json --features compiler-builtins-mem + cargo build --package std --target ../riscv64.json --features compiler-builtins-mem mkdir -p ../sysroot/lib/rustlib/riscv64/lib rm -rf ../sysroot/lib/rustlib/riscv64/lib/* cp target/riscv64/debug/deps/*.rlib ../sysroot/lib/rustlib/riscv64/lib @@ -83,11 +84,10 @@ build-sysroot: clean: cargo clean rm -rf ../sysroot/lib/rustlib/riscv64/lib/* - @for item in $(find library/std/src); do \ + @for item in $(find std/src -type f); do \ basename_item=$(basename "$item"); \ keep=0; \ for protected in {{ KEEP_FILES }}; do \ - echo $basename_item = $protected; \ if [ "$basename_item" = "$protected" ]; then keep=1; break; fi; \ done; \ if [ "$keep" -eq 0 ]; then \ diff --git a/library/std/.gitignore b/library/std/.gitignore index 16ddd3e..b58ea62 100644 --- a/library/std/.gitignore +++ b/library/std/.gitignore @@ -91,7 +91,6 @@ src/sys/mod.rs src/sys/time src/sys/time/mod.rs src/sys/time/unsupported.rs -src/sys/stdio src/sys/stdio/mod.rs src/sys/stdio/unsupported.rs src/sys/cmath.rs diff --git a/library/std/patches/sys/stdio/mod.sed b/library/std/patches/sys/stdio/mod.sed new file mode 100644 index 0000000..aea4bce --- /dev/null +++ b/library/std/patches/sys/stdio/mod.sed @@ -0,0 +1,4 @@ +47a \ target_os = "survos" => { \ + mod survos; \ + pub use self::survos::*; \ + } diff --git a/library/std/src/sys/stdio/survos.rs b/library/std/src/sys/stdio/survos.rs new file mode 100644 index 0000000..7bfdf49 --- /dev/null +++ b/library/std/src/sys/stdio/survos.rs @@ -0,0 +1,148 @@ +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; + +#[path = "unsupported.rs"] +mod unsupported; +pub use self::unsupported::{STDIN_BUF_SIZE, Stderr, Stdin, is_ebadf, panic_output}; + +pub struct Stdout; +// pub struct Stdin; + +impl Stdout { + pub const fn new() -> Self { + Self + } +} +// impl Stdin { +// pub const fn new() -> Self { +// Self +// } +// } + +impl io::Write for Stdout { + fn write(&mut self, buf: &[u8]) -> io::Result { + unsafe { Ok(write(1, buf) as usize) } + } + + fn flush(&mut self) -> io::Result<()> { + // todo!() + Ok(()) + } +} + +// impl io::Read for Stdin { +// fn read(&mut self, buf: &mut [u8]) -> io::Result { +// Ok(0) +// // unsafe { Ok(read(0, buf) as usize) } +// } +// } + +#[repr(u64)] +pub enum SysCall { + Read = 0, + Write = 1, + Open = 2, + Close = 3, + Seek = 8, + Alloc = 40, + Dealloc = 41, + Spawn = 58, + ExecVE = 59, + Exit = 60, + NanoSleep = 101, + WriteIntTemp = 998, + WriteTemp = 999, + Unimplemented = 1 << 31, +} + +impl From for SysCall { + fn from(value: u64) -> Self { + match value { + 0 => SysCall::Read, + 1 => SysCall::Write, + 2 => SysCall::Open, + 3 => SysCall::Close, + 8 => SysCall::Seek, + 40 => SysCall::Alloc, + 41 => SysCall::Dealloc, + 58 => SysCall::Spawn, + 59 => SysCall::ExecVE, + 60 => SysCall::Exit, + 101 => SysCall::NanoSleep, + 998 => SysCall::WriteIntTemp, + 999 => SysCall::WriteTemp, + _ => SysCall::Unimplemented, + } + } +} + +#[allow(clippy::too_many_arguments)] +unsafe fn _syscall( + syscall: SysCall, + mut a1: u64, + mut a2: u64, + mut a3: u64, + mut a4: u64, + mut a5: u64, + mut a6: u64, + mut a7: u64, +) -> (u64, u64, u64, u64, u64, u64, u64, u64) { + let mut a0 = syscall as u64; + unsafe { + core::arch::asm!( + "ecall", + inlateout("a0") a0, + inlateout("a1") a1, + inlateout("a2") a2, + inlateout("a3") a3, + inlateout("a4") a4, + inlateout("a5") a5, + inlateout("a6") a6, + inlateout("a7") a7, + clobber_abi("system") + ); + } + (a0, a1, a2, a3, a4, a5, a6, a7) +} + +macro_rules! syscall { + ($syscall:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr, $a6:expr, $a7:expr) => { + _syscall($syscall, $a1, $a2, $a3, $a4, $a5, $a6, $a7) + }; + ($syscall:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr, $a6:expr) => { + syscall!($syscall, $a1, $a2, $a3, $a4, $a5, $a6, 0) + }; + ($syscall:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr) => { + syscall!($syscall, $a1, $a2, $a3, $a4, $a5, 0) + }; + ($syscall:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr) => { + syscall!($syscall, $a1, $a2, $a3, $a4, 0) + }; + ($syscall:expr, $a1:expr, $a2:expr, $a3:expr) => { + syscall!($syscall, $a1, $a2, $a3, 0) + }; + ($syscall:expr, $a1:expr, $a2:expr) => { + syscall!($syscall, $a1, $a2, 0) + }; + ($syscall:expr, $a1:expr) => { + syscall!($syscall, $a1, 0) + }; + ($syscall:expr) => { + syscall!($syscall, 0) + }; +} +pub fn write(file_descriptor: u64, buf: &[u8]) -> u64 { + unsafe { + let ptr = buf.as_ptr(); + let size = buf.len(); + let (len, ..) = syscall!(SysCall::Write, file_descriptor, ptr as u64, size as u64); + len + } +} +pub fn read(file_descriptor: u64, buf: &mut [u8]) -> u64 { + unsafe { + let ptr = buf.as_ptr(); + let size = buf.len(); + let (len, ..) = syscall!(SysCall::Read, file_descriptor, ptr as u64, size as u64); + len + } +} diff --git a/src/process.rs b/src/process.rs index 6d6b4e0..81acd80 100644 --- a/src/process.rs +++ b/src/process.rs @@ -197,6 +197,7 @@ impl Scheduler { if ph.p_type == goblin::elf::program_header::PT_LOAD { let dst = unsafe { base.add((ph.p_vaddr - min_vaddr) as usize) }; let src_off = ph.p_offset as usize; + println!("off{:x?}", dst); let copy_len = ph.p_filesz as usize; if copy_len > 0 { unsafe { @@ -228,6 +229,16 @@ impl Scheduler { let where_off = (rela.r_offset - min_vaddr) as usize; let where_ptr = unsafe { base.add(where_off) } as *mut u64; let val = (base as u64).wrapping_add(rela.r_addend.unwrap() as u64); + if rela.r_addend.unwrap() == 0x5bfb8 { + println!( + "Relocating GLOBAL_PANIC_COUNT: at {:p}, setting value to {:x}", + where_ptr, val + ); + assert!( + val % 8 == 0, + "DANGER: Address of GLOBAL_PANIC_COUNT is not 8-aligned!" + ); + } unsafe { core::ptr::write_unaligned(where_ptr, val) }; } _ => {} diff --git a/src/virtual_fs.rs b/src/virtual_fs.rs index 2ff5bd0..b052372 100644 --- a/src/virtual_fs.rs +++ b/src/virtual_fs.rs @@ -57,7 +57,7 @@ impl VirtualFileSystem for MainFileSystem { } pub static mut FILE_SYSTEM: LazyCell = LazyCell::new(|| MainFileSystem { - root: Box::new(Fat32FileSystem::new(Disk::new(1024 * 1024 * 16)).unwrap()), + root: Box::new(Fat32FileSystem::new(Disk::new(1024 * 1024 * 64)).unwrap()), mounts: HashMap::new(), }); diff --git a/src/virtual_fs/null.rs b/src/virtual_fs/null.rs index d5667d5..be2ff7f 100644 --- a/src/virtual_fs/null.rs +++ b/src/virtual_fs/null.rs @@ -39,12 +39,12 @@ impl Seek for NullNode { } impl Write for NullNode { - fn write(&mut self, _buf: &[u8]) -> Result { - todo!() + fn write(&mut self, buf: &[u8]) -> Result { + Ok(buf.len()) } fn flush(&mut self) -> Result<(), Self::Error> { - todo!() + Ok(()) } } diff --git a/user.ld b/user.ld new file mode 100644 index 0000000..82a86d9 --- /dev/null +++ b/user.ld @@ -0,0 +1,35 @@ +/* + * ld directives the for barmetal RISCV + */ +OUTPUT_ARCH(riscv) +ENTRY(_start) + +MEMORY { + RAM (wxa) : ORIGIN = 0x0, LENGTH = 512M +} + +SECTIONS { + . = 0x0; + .text : { + KEEP(*(.text._start)) + + *(.text .text.*) + } > RAM + + .rodata : ALIGN(8) { + *(.rodata .rodata.*) + } > RAM + + .data : ALIGN(8) { + *(.data .data.*) + } > RAM + + .bss : ALIGN(8) { + __bss_start = .; + *(.bss .bss.*) + __bss_end = .; + } > RAM + + _heap_start = ALIGN(8); + _heap_end = ORIGIN(RAM) + LENGTH(RAM); +} diff --git a/user/shell/Cargo.toml b/user/shell/Cargo.toml index 6b3a444..1fa277e 100644 --- a/user/shell/Cargo.toml +++ b/user/shell/Cargo.toml @@ -4,6 +4,5 @@ version = "0.1.0" edition = "2024" [dependencies] -# std = { path = "../../crates/std" } # shared = { path = "../../crates/shared", features = ["user"] } # core = { path = "../../crates/std/crates/core" } diff --git a/user/shell/src/main.rs b/user/shell/src/main.rs index f0784f1..9503e1b 100644 --- a/user/shell/src/main.rs +++ b/user/shell/src/main.rs @@ -1,3 +1,5 @@ +// use std::io::_print; + fn main() { let a = std::env::args(); for a in a { diff --git a/user/test_pic/src/main.rs b/user/test_pic/src/main.rs index e7f321c..c01ceec 100644 --- a/user/test_pic/src/main.rs +++ b/user/test_pic/src/main.rs @@ -1,8 +1,9 @@ #![allow(unused)] +#![feature(panic_internals, core_intrinsics)] -use io::{Read, Write}; -use std::io::{Stdin, stdin}; +use io::{Read as Readio, Write}; use shared::syscall; +use std::io::{Read, Stdin, stdin}; fn main() { let mut input = String::new(); @@ -13,10 +14,15 @@ fn main() { // syscall::sleep(Duration::from_secs_f64(2.0)); syscall::close(0); let mut tty = syscall::open("/dev/tty0"); + syscall::close(1); + let _ = syscall::open("/dev/tty0"); + println!("test from test_pic"); tty.write(input.as_bytes()).unwrap(); syscall::spawn("/usr/bin/shell"); + core::panicking::panic("explicit panic"); loop { let mut test = [0; 2]; + // let len = stdin().read(&mut test); let len = tty.read(&mut test).unwrap(); tty.write(str::from_utf8(&test[..len as usize]).unwrap().as_bytes()) .unwrap();