From 49c11978d51466ba43d201f740e5366f2ac7cc65 Mon Sep 17 00:00:00 2001 From: sawyer bristol Date: Tue, 18 Nov 2025 13:37:50 -0700 Subject: [PATCH] rename syscall table from abi --- README.md | 2 +- justfile | 6 ++- kernel/src/elf.rs | 40 +++++++++---------- kernel/src/main.rs | 4 +- kernel/src/{abi.rs => syscalls.rs} | 22 +++++------ userlib_sys/src/lib.rs | 62 +++++++++++++++--------------- 6 files changed, 69 insertions(+), 67 deletions(-) rename kernel/src/{abi.rs => syscalls.rs} (95%) diff --git a/README.md b/README.md index 23247a9..9e1f265 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # PicoCalc OS (Rust) A simple kernel and applications for the **Clockwork PicoCalc**, written in Rust. -This project provides a minimal kernel, ABI, and user-space applications to experiment with OS development on constrained hardware. +This project provides a minimal kernel, syscall table, and user-space applications to experiment with kernel development on constrained hardware. ## Status diff --git a/justfile b/justfile index 913f0b5..aeb2060 100644 --- a/justfile +++ b/justfile @@ -1,10 +1,12 @@ +target := "thumbv8m.main-none-eabihf" + kernel-dev board: cargo run --bin kernel --features {{board}} --features fps kernel-release-probe board: cargo run --bin kernel --profile release --features {{board}} --features fps kernel-release board: cargo build --bin kernel --release --no-default-features --features {{board}} - elf2uf2-rs -d target/thumbv8m.main-none-eabihf/release/kernel + elf2uf2-rs -d target/{{target}}/release/kernel binary-args := "RUSTFLAGS=\"-C link-arg=-pie -C relocation-model=pic\"" @@ -42,7 +44,7 @@ userapps: cbindgen just userapp wav_player copy-userapp app: - cp ./target/thumbv8m.main-none-eabihf/release-binary/{{app}} /run/media/$(whoami)/PICOCALC/{{app}}.bin + cp ./target/{{target}}/release-binary/{{app}} /run/media/$(whoami)/PICOCALC/{{app}}.bin copy-userapps: #!/bin/bash diff --git a/kernel/src/elf.rs b/kernel/src/elf.rs index 05aba55..2fbb7aa 100644 --- a/kernel/src/elf.rs +++ b/kernel/src/elf.rs @@ -1,8 +1,7 @@ use crate::{ - abi, storage::{File, SDCARD}, + syscalls, }; -use userlib_sys::{CallTable, EntryFn}; use alloc::{vec, vec::Vec}; use bumpalo::Bump; use core::ptr; @@ -17,6 +16,7 @@ use goblin::{ elf32::{header, reloc::Rel, section_header::SectionHeader, sym::Sym}, }; use strum::IntoEnumIterator; +use userlib_sys::{EntryFn, SyscallTable}; const ELF32_HDR_SIZE: usize = 52; @@ -70,7 +70,7 @@ pub async unsafe fn load_binary(name: &ShortFileName) -> Option<(EntryFn, Bump)> } } - patch_abi(&elf_header, base.as_mut_ptr(), min_vaddr, &mut file).unwrap(); + patch_syscalls(&elf_header, base.as_mut_ptr(), min_vaddr, &mut file).unwrap(); // entry pointer is base_ptr + (entry - min_vaddr) let entry_ptr: EntryFn = unsafe { @@ -150,7 +150,7 @@ fn apply_relocations( Ok(()) } -fn patch_abi( +fn patch_syscalls( elf_header: &Header, base: *mut u8, min_vaddr: u32, @@ -188,27 +188,27 @@ fn patch_abi( } let symbol_name = core::str::from_utf8(&name).unwrap(); - if symbol_name == "CALL_ABI_TABLE" { + if symbol_name == stringify!(SYS_CALL_TABLE) { let table_base = unsafe { base.add((sym.st_value as usize) - min_vaddr as usize) } as *mut usize; - for (idx, call) in CallTable::iter().enumerate() { + for (idx, call) in SyscallTable::iter().enumerate() { let ptr = match call { - CallTable::Alloc => abi::alloc as usize, - CallTable::Dealloc => abi::dealloc as usize, - CallTable::PrintString => abi::print as usize, - CallTable::SleepMs => abi::sleep as usize, - CallTable::GetMs => abi::get_ms as usize, - CallTable::DrawIter => abi::draw_iter as usize, - CallTable::GetKey => abi::get_key as usize, - CallTable::GenRand => abi::gen_rand as usize, - CallTable::ListDir => abi::list_dir as usize, - CallTable::ReadFile => abi::read_file as usize, - CallTable::WriteFile => abi::write_file as usize, - CallTable::FileLen => abi::file_len as usize, - CallTable::AudioBufferReady => abi::audio_buffer_ready as usize, - CallTable::SendAudioBuffer => abi::send_audio_buffer as usize, + SyscallTable::Alloc => syscalls::alloc as usize, + SyscallTable::Dealloc => syscalls::dealloc as usize, + SyscallTable::PrintString => syscalls::print as usize, + SyscallTable::SleepMs => syscalls::sleep as usize, + SyscallTable::GetMs => syscalls::get_ms as usize, + SyscallTable::DrawIter => syscalls::draw_iter as usize, + SyscallTable::GetKey => syscalls::get_key as usize, + SyscallTable::GenRand => syscalls::gen_rand as usize, + SyscallTable::ListDir => syscalls::list_dir as usize, + SyscallTable::ReadFile => syscalls::read_file as usize, + SyscallTable::WriteFile => syscalls::write_file as usize, + SyscallTable::FileLen => syscalls::file_len as usize, + SyscallTable::AudioBufferReady => syscalls::audio_buffer_ready as usize, + SyscallTable::SendAudioBuffer => syscalls::send_audio_buffer as usize, }; unsafe { table_base.add(idx as usize).write(ptr); diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 66570c7..81d7cc6 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -8,7 +8,6 @@ extern crate alloc; -mod abi; mod audio; mod display; mod elf; @@ -16,6 +15,7 @@ mod framebuffer; mod peripherals; mod scsi; mod storage; +mod syscalls; mod ui; mod usb; mod utils; @@ -31,12 +31,12 @@ mod psram; use crate::{heap::HEAP, heap::init_qmi_psram_heap, psram::init_psram, psram::init_psram_qmi}; use crate::{ - abi::{KEY_CACHE, MS_SINCE_LAUNCH}, audio::audio_handler, display::{FRAMEBUFFER, display_handler, init_display}, peripherals::{conf_peripherals, keyboard::read_keyboard_fifo}, scsi::MSC_SHUTDOWN, storage::{SDCARD, SdCard}, + syscalls::{KEY_CACHE, MS_SINCE_LAUNCH}, ui::{SELECTIONS, clear_selection, ui_handler}, }; use bumpalo::Bump; diff --git a/kernel/src/abi.rs b/kernel/src/syscalls.rs similarity index 95% rename from kernel/src/abi.rs rename to kernel/src/syscalls.rs index b5eec81..09b1840 100644 --- a/kernel/src/abi.rs +++ b/kernel/src/syscalls.rs @@ -1,14 +1,14 @@ use alloc::{string::ToString, vec::Vec}; use core::{ffi::c_char, ptr, sync::atomic::Ordering}; -use embassy_rp::clocks::{clk_sys_freq, RoscRng}; +use embassy_rp::clocks::{RoscRng, clk_sys_freq}; use embassy_time::Instant; use embedded_graphics::draw_target::DrawTarget; use embedded_sdmmc::LfnBuffer; use heapless::spsc::Queue; use userlib_sys::{ - keyboard::*, AllocAbi, AudioBufferReady, CLayout, CPixel, DeallocAbi, DrawIterAbi, FileLen, - GenRand, GetMsAbi, ListDir, PrintAbi, ReadFile, RngRequest, SendAudioBuffer, SleepMsAbi, - WriteFile, AUDIO_BUFFER_SAMPLES, + AUDIO_BUFFER_SAMPLES, Alloc, AudioBufferReady, CLayout, CPixel, Dealloc, DrawIter, FileLen, + GenRand, GetMs, ListDir, Print, ReadFile, RngRequest, SendAudioBuffer, SleepMs, WriteFile, + keyboard::*, }; #[cfg(feature = "psram")] @@ -24,7 +24,7 @@ use crate::{ storage::{Dir, File, SDCARD}, }; -const _: AllocAbi = alloc; +const _: Alloc = alloc; pub extern "C" fn alloc(layout: CLayout) -> *mut u8 { // SAFETY: caller guarantees layout is valid unsafe { @@ -40,7 +40,7 @@ pub extern "C" fn alloc(layout: CLayout) -> *mut u8 { } } -const _: DeallocAbi = dealloc; +const _: Dealloc = dealloc; pub extern "C" fn dealloc(ptr: *mut u8, layout: CLayout) { // SAFETY: caller guarantees ptr and layout are valid #[cfg(feature = "psram")] @@ -54,7 +54,7 @@ pub extern "C" fn dealloc(ptr: *mut u8, layout: CLayout) { } } -const _: PrintAbi = print; +const _: Print = print; pub extern "C" fn print(ptr: *const u8, len: usize) { // SAFETY: caller guarantees `ptr` is valid for `len` bytes let slice = unsafe { core::slice::from_raw_parts(ptr, len) }; @@ -68,7 +68,7 @@ pub extern "C" fn print(ptr: *const u8, len: usize) { } } -const _: SleepMsAbi = sleep; +const _: SleepMs = sleep; pub extern "C" fn sleep(ms: u64) { let cycles_per_ms = clk_sys_freq() / 1000; let total_cycles = ms * cycles_per_ms as u64; @@ -80,14 +80,14 @@ pub extern "C" fn sleep(ms: u64) { pub static mut MS_SINCE_LAUNCH: Option = None; -const _: GetMsAbi = get_ms; +const _: GetMs = get_ms; pub extern "C" fn get_ms() -> u64 { Instant::now() .duration_since(unsafe { MS_SINCE_LAUNCH.unwrap() }) .as_millis() } -const _: DrawIterAbi = draw_iter; +const _: DrawIter = draw_iter; pub extern "C" fn draw_iter(cpixels: *const CPixel, len: usize) { // SAFETY: caller guarantees `ptr` is valid for `len` bytes let cpixels = unsafe { core::slice::from_raw_parts(cpixels, len) }; @@ -101,7 +101,7 @@ pub extern "C" fn draw_iter(cpixels: *const CPixel, len: usize) { pub static mut KEY_CACHE: Queue = Queue::new(); -const _: GetKeyAbi = get_key; +const _: GetKey = get_key; pub extern "C" fn get_key() -> KeyEventC { if let Some(event) = unsafe { KEY_CACHE.dequeue() } { event.into() diff --git a/userlib_sys/src/lib.rs b/userlib_sys/src/lib.rs index 0b26e9f..1e275b3 100644 --- a/userlib_sys/src/lib.rs +++ b/userlib_sys/src/lib.rs @@ -12,12 +12,12 @@ use strum::{EnumCount, EnumIter}; pub type EntryFn = fn(); -pub const ABI_CALL_TABLE_COUNT: usize = 14; -const _: () = assert!(ABI_CALL_TABLE_COUNT == CallTable::COUNT); +pub const SYS_CALL_TABLE_COUNT: usize = 14; +const _: () = assert!(SYS_CALL_TABLE_COUNT == SyscallTable::COUNT); #[derive(Clone, Copy, EnumIter, EnumCount)] #[repr(u8)] -pub enum CallTable { +pub enum SyscallTable { Alloc = 0, Dealloc = 1, PrintString = 2, @@ -36,7 +36,7 @@ pub enum CallTable { #[unsafe(no_mangle)] #[unsafe(link_section = ".syscall_table")] -pub static mut CALL_ABI_TABLE: [usize; ABI_CALL_TABLE_COUNT] = [0; ABI_CALL_TABLE_COUNT]; +pub static mut SYS_CALL_TABLE: [usize; SYS_CALL_TABLE_COUNT] = [0; SYS_CALL_TABLE_COUNT]; #[cfg(feature = "alloc")] #[repr(C)] @@ -62,46 +62,46 @@ impl From for CLayout { } } -pub type AllocAbi = extern "C" fn(layout: CLayout) -> *mut u8; +pub type Alloc = extern "C" fn(layout: CLayout) -> *mut u8; #[unsafe(no_mangle)] pub extern "C" fn alloc(layout: CLayout) -> *mut u8 { - let f: AllocAbi = unsafe { core::mem::transmute(CALL_ABI_TABLE[CallTable::Alloc as usize]) }; + let f: Alloc = unsafe { core::mem::transmute(SYS_CALL_TABLE[SyscallTable::Alloc as usize]) }; f(layout) } -pub type DeallocAbi = extern "C" fn(ptr: *mut u8, layout: CLayout); +pub type Dealloc = extern "C" fn(ptr: *mut u8, layout: CLayout); #[unsafe(no_mangle)] pub extern "C" fn dealloc(ptr: *mut u8, layout: CLayout) { - let f: DeallocAbi = - unsafe { core::mem::transmute(CALL_ABI_TABLE[CallTable::Dealloc as usize]) }; + let f: Dealloc = + unsafe { core::mem::transmute(SYS_CALL_TABLE[SyscallTable::Dealloc as usize]) }; f(ptr, layout) } -pub type PrintAbi = extern "C" fn(ptr: *const u8, len: usize); +pub type Print = extern "C" fn(ptr: *const u8, len: usize); #[unsafe(no_mangle)] pub extern "C" fn print(ptr: *const u8, len: usize) { - let f: PrintAbi = - unsafe { core::mem::transmute(CALL_ABI_TABLE[CallTable::PrintString as usize]) }; + let f: Print = + unsafe { core::mem::transmute(SYS_CALL_TABLE[SyscallTable::PrintString as usize]) }; f(ptr, len); } -pub type SleepMsAbi = extern "C" fn(ms: u64); +pub type SleepMs = extern "C" fn(ms: u64); #[unsafe(no_mangle)] pub extern "C" fn sleep(ms: u64) { - let f: SleepMsAbi = - unsafe { core::mem::transmute(CALL_ABI_TABLE[CallTable::SleepMs as usize]) }; + let f: SleepMs = + unsafe { core::mem::transmute(SYS_CALL_TABLE[SyscallTable::SleepMs as usize]) }; f(ms); } -pub type GetMsAbi = extern "C" fn() -> u64; +pub type GetMs = extern "C" fn() -> u64; #[unsafe(no_mangle)] pub extern "C" fn get_ms() -> u64 { - let f: GetMsAbi = unsafe { core::mem::transmute(CALL_ABI_TABLE[CallTable::GetMs as usize]) }; + let f: GetMs = unsafe { core::mem::transmute(SYS_CALL_TABLE[SyscallTable::GetMs as usize]) }; f() } @@ -139,17 +139,17 @@ impl Into> for CPixel { } } -pub type DrawIterAbi = extern "C" fn(ptr: *const CPixel, len: usize); +pub type DrawIter = extern "C" fn(ptr: *const CPixel, len: usize); #[unsafe(no_mangle)] pub extern "C" fn draw_iter(ptr: *const CPixel, len: usize) { - let f: DrawIterAbi = - unsafe { core::mem::transmute(CALL_ABI_TABLE[CallTable::DrawIter as usize]) }; + let f: DrawIter = + unsafe { core::mem::transmute(SYS_CALL_TABLE[SyscallTable::DrawIter as usize]) }; f(ptr, len); } pub mod keyboard { - use crate::{CALL_ABI_TABLE, CallTable}; + use crate::{SYS_CALL_TABLE, SyscallTable}; bitflags::bitflags! { #[derive(Default, Debug, PartialEq, Eq, Clone, Copy)] @@ -367,12 +367,12 @@ pub mod keyboard { } } - pub type GetKeyAbi = extern "C" fn() -> KeyEventC; + pub type GetKey = extern "C" fn() -> KeyEventC; #[unsafe(no_mangle)] pub extern "C" fn get_key() -> KeyEventC { - let f: GetKeyAbi = - unsafe { core::mem::transmute(CALL_ABI_TABLE[CallTable::GetKey as usize]) }; + let f: GetKey = + unsafe { core::mem::transmute(SYS_CALL_TABLE[SyscallTable::GetKey as usize]) }; f() } } @@ -389,7 +389,7 @@ pub type GenRand = extern "C" fn(req: &mut RngRequest); #[unsafe(no_mangle)] pub extern "C" fn gen_rand(req: &mut RngRequest) { unsafe { - let ptr = CALL_ABI_TABLE[CallTable::GenRand as usize]; + let ptr = SYS_CALL_TABLE[SyscallTable::GenRand as usize]; let f: GenRand = core::mem::transmute(ptr); f(req) } @@ -412,7 +412,7 @@ pub extern "C" fn list_dir( max_entry_str_len: usize, ) -> usize { unsafe { - let ptr = CALL_ABI_TABLE[CallTable::ListDir as usize]; + let ptr = SYS_CALL_TABLE[SyscallTable::ListDir as usize]; let f: ListDir = core::mem::transmute(ptr); f(str, len, entries, entry_count, max_entry_str_len) } @@ -435,7 +435,7 @@ pub extern "C" fn read_file( buf_len: usize, ) -> usize { unsafe { - let ptr = CALL_ABI_TABLE[CallTable::ReadFile as usize]; + let ptr = SYS_CALL_TABLE[SyscallTable::ReadFile as usize]; let f: ReadFile = core::mem::transmute(ptr); f(str, len, read_from, buf, buf_len) } @@ -453,7 +453,7 @@ pub extern "C" fn write_file( buf_len: usize, ) { unsafe { - let ptr = CALL_ABI_TABLE[CallTable::WriteFile as usize]; + let ptr = SYS_CALL_TABLE[SyscallTable::WriteFile as usize]; let f: WriteFile = core::mem::transmute(ptr); f(str, len, write_from, buf, buf_len) } @@ -464,7 +464,7 @@ pub type FileLen = extern "C" fn(str: *const u8, len: usize) -> usize; #[unsafe(no_mangle)] pub extern "C" fn file_len(str: *const u8, len: usize) -> usize { unsafe { - let ptr = CALL_ABI_TABLE[CallTable::FileLen as usize]; + let ptr = SYS_CALL_TABLE[SyscallTable::FileLen as usize]; let f: FileLen = core::mem::transmute(ptr); f(str, len) } @@ -475,7 +475,7 @@ pub type AudioBufferReady = extern "C" fn() -> bool; #[allow(unused)] pub fn audio_buffer_ready() -> bool { unsafe { - let ptr = CALL_ABI_TABLE[CallTable::AudioBufferReady as usize]; + let ptr = SYS_CALL_TABLE[SyscallTable::AudioBufferReady as usize]; let f: AudioBufferReady = core::mem::transmute(ptr); f() } @@ -489,7 +489,7 @@ pub type SendAudioBuffer = extern "C" fn(ptr: *const u8, len: usize); #[allow(unused)] pub fn send_audio_buffer(buf: *const u8, len: usize) { unsafe { - let ptr = CALL_ABI_TABLE[CallTable::SendAudioBuffer as usize]; + let ptr = SYS_CALL_TABLE[SyscallTable::SendAudioBuffer as usize]; let f: SendAudioBuffer = core::mem::transmute(ptr); f(buf, len) }