From c9b484089e7272f25841d46ef097dc25e1da37e3 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Sat, 17 Aug 2024 20:19:45 -0700 Subject: [PATCH] [Yellowstone] Wireframe for moving yellowstone to rust. --- rust/Cargo.lock | 30 +++++++++++++--- rust/Cargo.toml | 4 +-- rust/lib/denali/Cargo.toml | 12 +++++++ rust/lib/denali/build.rs | 14 ++++++++ rust/lib/denali/src/lib.rs | 5 +++ rust/lib/mammoth/src/elf.rs | 15 +++++--- rust/lib/mammoth/src/init.rs | 14 ++++++++ rust/lib/mammoth/src/lib.rs | 1 + rust/lib/mammoth/src/sync.rs | 19 ++++++++++ rust/lib/mammoth/src/syscall.rs | 30 ++++++++++++++++ rust/lib/victoriafalls/Cargo.toml | 2 +- rust/lib/victoriafalls/src/lib.rs | 4 +-- rust/lib/voyageurs/Cargo.toml | 2 +- rust/lib/voyageurs/src/listener.rs | 4 +-- rust/lib/yellowstone/Cargo.toml | 2 +- rust/sys/teton/Cargo.toml | 2 +- rust/sys/teton/src/framebuffer.rs | 2 +- rust/sys/teton/src/main.rs | 2 +- rust/sys/yellowstone/Cargo.toml | 12 +++++++ rust/sys/yellowstone/src/main.rs | 48 +++++++++++++++++++++++++ rust/sys/yellowstone/src/server.rs | 58 ++++++++++++++++++++++++++++++ rust/usr/testbed/Cargo.toml | 2 +- rust/usr/testbed/src/main.rs | 4 +-- scripts/build_image.sh | 2 +- 24 files changed, 265 insertions(+), 25 deletions(-) create mode 100644 rust/lib/denali/Cargo.toml create mode 100644 rust/lib/denali/build.rs create mode 100644 rust/lib/denali/src/lib.rs create mode 100644 rust/lib/mammoth/src/sync.rs create mode 100644 rust/sys/yellowstone/Cargo.toml create mode 100644 rust/sys/yellowstone/src/main.rs create mode 100644 rust/sys/yellowstone/src/server.rs diff --git a/rust/Cargo.lock b/rust/Cargo.lock index c1a17bd..2874dee 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -17,6 +17,16 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "denali" +version = "0.1.0" +dependencies = [ + "mammoth", + "yunq", + "yunq-derive", + "yunqc", +] + [[package]] name = "linked_list_allocator" version = "0.10.5" @@ -113,7 +123,7 @@ name = "testbed" version = "0.1.0" dependencies = [ "mammoth", - "yellowstone", + "yellowstone-yunq", "yunq", ] @@ -124,7 +134,7 @@ dependencies = [ "mammoth", "victoriafalls", "voyageurs", - "yellowstone", + "yellowstone-yunq", ] [[package]] @@ -144,7 +154,7 @@ name = "victoriafalls" version = "0.1.0" dependencies = [ "mammoth", - "yellowstone", + "yellowstone-yunq", "yunq", "yunq-derive", "yunqc", @@ -155,7 +165,7 @@ name = "voyageurs" version = "0.1.0" dependencies = [ "mammoth", - "yellowstone", + "yellowstone-yunq", "yunq", "yunq-derive", "yunqc", @@ -164,6 +174,18 @@ dependencies = [ [[package]] name = "yellowstone" version = "0.1.0" +dependencies = [ + "denali", + "mammoth", + "victoriafalls", + "voyageurs", + "yellowstone-yunq", + "yunq", +] + +[[package]] +name = "yellowstone-yunq" +version = "0.1.0" dependencies = [ "mammoth", "yunq", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 24f2adc..589f7ad 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,7 +1,7 @@ [workspace] -members = [ - "lib/mammoth", "lib/victoriafalls", "lib/voyageurs", "lib/yellowstone", "lib/yunq", "lib/yunq-derive", "sys/teton", "usr/testbed", +members = [ "lib/denali", + "lib/mammoth", "lib/victoriafalls", "lib/voyageurs", "lib/yellowstone", "lib/yunq", "lib/yunq-derive", "sys/teton", "sys/yellowstone", "usr/testbed", ] resolver = "2" diff --git a/rust/lib/denali/Cargo.toml b/rust/lib/denali/Cargo.toml new file mode 100644 index 0000000..e05782f --- /dev/null +++ b/rust/lib/denali/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "denali" +version = "0.1.0" +edition = "2021" + +[dependencies] +mammoth = { path = "../mammoth" } +yunq = {path = "../yunq"} +yunq-derive = {path = "../yunq-derive"} + +[build-dependencies] +yunqc = {path = "../../../yunq/rust"} diff --git a/rust/lib/denali/build.rs b/rust/lib/denali/build.rs new file mode 100644 index 0000000..d5ac830 --- /dev/null +++ b/rust/lib/denali/build.rs @@ -0,0 +1,14 @@ +use std::fs; + +fn main() { + let input_file = "../../../sys/denali/lib/denali/denali.yunq"; + + println!("cargo::rerun-if-changed={input_file}"); + + let input = fs::read_to_string(input_file).expect("Failed to read input file"); + + let code = yunqc::codegen(&input).expect("Failed to generate yunq code."); + + let out = std::env::var("OUT_DIR").unwrap() + "/yunq.rs"; + fs::write(out, code).expect("Failed to write generated code."); +} diff --git a/rust/lib/denali/src/lib.rs b/rust/lib/denali/src/lib.rs new file mode 100644 index 0000000..3cec9d6 --- /dev/null +++ b/rust/lib/denali/src/lib.rs @@ -0,0 +1,5 @@ +#![no_std] + +use core::include; + +include!(concat!(env!("OUT_DIR"), "/yunq.rs")); diff --git a/rust/lib/mammoth/src/elf.rs b/rust/lib/mammoth/src/elf.rs index 321063d..2b8638f 100644 --- a/rust/lib/mammoth/src/elf.rs +++ b/rust/lib/mammoth/src/elf.rs @@ -13,9 +13,7 @@ const ELF_IDENT_64BIT: u8 = 0x2; const ELF_ENDIAN_LITTLE: u8 = 0x1; const ELF_ENDIAN_BIG: u8 = 0x2; - const ELF_VERSION_CURRENT: u8 = 0x1; - const ELF_ABI_SYSV: u8 = 0x0; const ELF_ABI_LINUX: u8 = 0x3; @@ -312,7 +310,10 @@ fn load_elf_program(elf_file: &[u8], vmas: &Capability) -> Result { Ok(header.entry) } -pub fn spawn_process_from_elf(elf_file: &[u8]) -> Result { +pub fn spawn_process_from_elf_and_init( + elf_file: &[u8], + init_cap: Capability, +) -> Result { let self_cap = Capability::take_copy(unsafe { init::SELF_PROC_CAP })?; let port_cap = syscall::port_create()?; @@ -328,8 +329,7 @@ pub fn spawn_process_from_elf(elf_file: &[u8]) -> Result { new_proc_cap.duplicate(Capability::PERMS_ALL)?, )?; port.write_u64_and_cap(crate::init::Z_INIT_SELF_VMAS, new_as_cap)?; - let yellowstone = Capability::take_copy(unsafe { crate::init::INIT_ENDPOINT })?; - port.write_u64_and_cap(crate::init::Z_INIT_ENDPOINT, yellowstone)?; + port.write_u64_and_cap(crate::init::Z_INIT_ENDPOINT, init_cap)?; let thread_cap = syscall::thread_create(&new_proc_cap)?; @@ -337,3 +337,8 @@ pub fn spawn_process_from_elf(elf_file: &[u8]) -> Result { Ok(new_proc_cap) } + +pub fn spawn_process_from_elf(elf_file: &[u8]) -> Result { + let yellowstone = Capability::take_copy(unsafe { crate::init::INIT_ENDPOINT })?; + spawn_process_from_elf_and_init(elf_file, yellowstone) +} diff --git a/rust/lib/mammoth/src/init.rs b/rust/lib/mammoth/src/init.rs index a03eed7..556cf24 100644 --- a/rust/lib/mammoth/src/init.rs +++ b/rust/lib/mammoth/src/init.rs @@ -6,11 +6,21 @@ use crate::zion::z_cap_t; pub const Z_INIT_SELF_PROC: u64 = 0x4000_0000; pub const Z_INIT_SELF_VMAS: u64 = 0x4000_0001; pub const Z_INIT_ENDPOINT: u64 = 0x4100_0000; +const Z_BOOT_DENALI_VMMO: u64 = 0x4200_0000; +const Z_BOOT_VICTORIA_FALLS_VMMO: u64 = 0x4200_0001; +const Z_BOOT_PCI_VMMO: u64 = 0x4200_0002; +const Z_BOOT_FRAMEBUFFER_INFO_VMMO: u64 = 0x4200_0003; pub static mut SELF_PROC_CAP: z_cap_t = 0; pub static mut SELF_VMAS_CAP: z_cap_t = 0; pub static mut INIT_ENDPOINT: z_cap_t = 0; +// Boot capabilities, are generally only passed to yellowstone. +pub static mut BOOT_DENALI_VMMO: z_cap_t = 0; +pub static mut BOOT_VICTORIA_FALLS_VMMO: z_cap_t = 0; +pub static mut BOOT_PCI_VMMO: z_cap_t = 0; +pub static mut BOOT_FRAMEBUFFER_INFO_VMMO: z_cap_t = 0; + pub fn parse_init_port(port_cap: z_cap_t) { let init_port = Capability::take(port_cap); loop { @@ -29,6 +39,10 @@ pub fn parse_init_port(port_cap: z_cap_t) { Z_INIT_SELF_PROC => SELF_PROC_CAP = caps[0], Z_INIT_SELF_VMAS => SELF_VMAS_CAP = caps[0], Z_INIT_ENDPOINT => INIT_ENDPOINT = caps[0], + Z_BOOT_DENALI_VMMO => BOOT_DENALI_VMMO = caps[0], + Z_BOOT_VICTORIA_FALLS_VMMO => BOOT_VICTORIA_FALLS_VMMO = caps[0], + Z_BOOT_PCI_VMMO => BOOT_PCI_VMMO = caps[0], + Z_BOOT_FRAMEBUFFER_INFO_VMMO => BOOT_FRAMEBUFFER_INFO_VMMO = caps[0], _ => syscall::debug("Unknown Cap in Init"), } } diff --git a/rust/lib/mammoth/src/lib.rs b/rust/lib/mammoth/src/lib.rs index b0891a6..cf5d3f0 100644 --- a/rust/lib/mammoth/src/lib.rs +++ b/rust/lib/mammoth/src/lib.rs @@ -14,6 +14,7 @@ pub mod elf; pub mod init; pub mod mem; pub mod port; +pub mod sync; pub mod syscall; pub mod thread; pub mod zion; diff --git a/rust/lib/mammoth/src/sync.rs b/rust/lib/mammoth/src/sync.rs new file mode 100644 index 0000000..8d80f17 --- /dev/null +++ b/rust/lib/mammoth/src/sync.rs @@ -0,0 +1,19 @@ +use crate::{cap::Capability, syscall, zion::ZError}; + +pub struct Semaphore { + cap: Capability, +} + +impl Semaphore { + pub fn new() -> Result { + syscall::semaphore_create().map(|cap| Self { cap }) + } + + pub fn wait(&self) -> Result<(), ZError> { + syscall::semaphone_wait(&self.cap) + } + + pub fn signal(&self) -> Result<(), ZError> { + syscall::semaphone_signal(&self.cap) + } +} diff --git a/rust/lib/mammoth/src/syscall.rs b/rust/lib/mammoth/src/syscall.rs index 1c2d892..3d3635a 100644 --- a/rust/lib/mammoth/src/syscall.rs +++ b/rust/lib/mammoth/src/syscall.rs @@ -363,3 +363,33 @@ pub fn reply_port_recv( Ok((num_bytes, num_caps)) } + +pub fn semaphore_create() -> Result { + let mut sem_cap: z_cap_t = 0; + syscall( + zion::kZionSemaphoreCreate, + &zion::ZSemaphoreCreateReq { + semaphore_cap: &mut sem_cap, + }, + )?; + + Ok(Capability::take(sem_cap)) +} + +pub fn semaphone_signal(sem_cap: &Capability) -> Result<(), ZError> { + syscall( + zion::kZionSemaphoreSignal, + &zion::ZSemaphoreSignalReq { + semaphore_cap: sem_cap.raw(), + }, + ) +} + +pub fn semaphone_wait(sem_cap: &Capability) -> Result<(), ZError> { + syscall( + zion::kZionSemaphoreWait, + &zion::ZSemaphoreWaitReq { + semaphore_cap: sem_cap.raw(), + }, + ) +} diff --git a/rust/lib/victoriafalls/Cargo.toml b/rust/lib/victoriafalls/Cargo.toml index 7f3566b..aeb0bf1 100644 --- a/rust/lib/victoriafalls/Cargo.toml +++ b/rust/lib/victoriafalls/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] mammoth = { path = "../mammoth" } -yellowstone = { path = "../yellowstone" } +yellowstone-yunq = { path = "../yellowstone" } yunq = {path = "../yunq"} yunq-derive = {path = "../yunq-derive"} diff --git a/rust/lib/victoriafalls/src/lib.rs b/rust/lib/victoriafalls/src/lib.rs index 6248bc5..f6887c4 100644 --- a/rust/lib/victoriafalls/src/lib.rs +++ b/rust/lib/victoriafalls/src/lib.rs @@ -12,8 +12,8 @@ static mut VFS_CLIENT: Option = None; fn get_client() -> &'static mut VFSClient { unsafe { if let None = VFS_CLIENT { - let endpoint_cap = yellowstone::from_init_endpoint() - .get_endpoint(&yellowstone::GetEndpointRequest { + let endpoint_cap = yellowstone_yunq::from_init_endpoint() + .get_endpoint(&yellowstone_yunq::GetEndpointRequest { endpoint_name: "victoriafalls".to_string(), }) .expect("Failed to get VFS endpoint"); diff --git a/rust/lib/voyageurs/Cargo.toml b/rust/lib/voyageurs/Cargo.toml index a007692..b396220 100644 --- a/rust/lib/voyageurs/Cargo.toml +++ b/rust/lib/voyageurs/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] mammoth = { path = "../mammoth" } -yellowstone = { path = "../yellowstone" } +yellowstone-yunq = { path = "../yellowstone" } yunq = {path = "../yunq"} yunq-derive = {path = "../yunq-derive"} diff --git a/rust/lib/voyageurs/src/listener.rs b/rust/lib/voyageurs/src/listener.rs index b340ed3..78a4f4a 100644 --- a/rust/lib/voyageurs/src/listener.rs +++ b/rust/lib/voyageurs/src/listener.rs @@ -211,8 +211,8 @@ impl KeyboardListener { handler, }); - let voyageur_endpoint = yellowstone::from_init_endpoint() - .get_endpoint(&yellowstone::GetEndpointRequest { + let voyageur_endpoint = yellowstone_yunq::from_init_endpoint() + .get_endpoint(&yellowstone_yunq::GetEndpointRequest { endpoint_name: "voyageurs".to_string(), })? .endpoint; diff --git a/rust/lib/yellowstone/Cargo.toml b/rust/lib/yellowstone/Cargo.toml index 59ea732..c9a6299 100644 --- a/rust/lib/yellowstone/Cargo.toml +++ b/rust/lib/yellowstone/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "yellowstone" +name = "yellowstone-yunq" version = "0.1.0" edition = "2021" diff --git a/rust/sys/teton/Cargo.toml b/rust/sys/teton/Cargo.toml index a355119..1bcda15 100644 --- a/rust/sys/teton/Cargo.toml +++ b/rust/sys/teton/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" mammoth = { path = "../../lib/mammoth" } victoriafalls = { path = "../../lib/victoriafalls" } voyageurs = { path = "../../lib/voyageurs" } -yellowstone = { path = "../../lib/yellowstone" } +yellowstone-yunq = { path = "../../lib/yellowstone" } diff --git a/rust/sys/teton/src/framebuffer.rs b/rust/sys/teton/src/framebuffer.rs index 856b0c1..dad4099 100644 --- a/rust/sys/teton/src/framebuffer.rs +++ b/rust/sys/teton/src/framebuffer.rs @@ -1,5 +1,5 @@ use mammoth::{mem::MemoryRegion, zion::ZError}; -use yellowstone::FramebufferInfo; +use yellowstone_yunq::FramebufferInfo; pub struct Framebuffer { fb_info: FramebufferInfo, diff --git a/rust/sys/teton/src/main.rs b/rust/sys/teton/src/main.rs index b1866d2..5cec4fb 100644 --- a/rust/sys/teton/src/main.rs +++ b/rust/sys/teton/src/main.rs @@ -20,7 +20,7 @@ define_entry!(); extern "C" fn main() -> z_err_t { debug!("Teton Starting"); - let yellowstone = yellowstone::from_init_endpoint(); + let yellowstone = yellowstone_yunq::from_init_endpoint(); let framebuffer_info = yellowstone .get_framebuffer_info() .expect("Failed to get framebuffer info."); diff --git a/rust/sys/yellowstone/Cargo.toml b/rust/sys/yellowstone/Cargo.toml new file mode 100644 index 0000000..57e52b8 --- /dev/null +++ b/rust/sys/yellowstone/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "yellowstone" +version = "0.1.0" +edition = "2021" + +[dependencies] +mammoth = { path = "../../lib/mammoth" } +denali = { path = "../../lib/denali" } +victoriafalls = { path = "../../lib/victoriafalls" } +voyageurs = { path = "../../lib/voyageurs" } +yellowstone-yunq = { path = "../../lib/yellowstone" } +yunq = { path = "../../lib/yunq" } diff --git a/rust/sys/yellowstone/src/main.rs b/rust/sys/yellowstone/src/main.rs new file mode 100644 index 0000000..f416168 --- /dev/null +++ b/rust/sys/yellowstone/src/main.rs @@ -0,0 +1,48 @@ +#![no_std] +#![no_main] + +extern crate alloc; + +use mammoth::{ + cap::Capability, + define_entry, elf, + zion::{kZionPerm_Read, z_cap_t, z_err_t, ZError}, +}; +use yellowstone_yunq::YellowstoneServer; +use yunq::server::YunqServer; + +mod server; + +define_entry!(); + +fn spawn_from_vmmo(vmmo_cap: z_cap_t, server_cap: Capability) -> Result<(), ZError> { + let region = mammoth::mem::MemoryRegion::from_cap(Capability::take(vmmo_cap))?; + elf::spawn_process_from_elf_and_init(region.slice(), server_cap)?; + Ok(()) +} + +#[no_mangle] +extern "C" fn main() -> z_err_t { + let context = alloc::rc::Rc::new( + server::YellowstoneServerContext::new().expect("Failed to create yellowstone context"), + ); + let handler = server::YellowstoneServerImpl::new(context.clone()); + let server = YellowstoneServer::new(handler).expect("Couldn't create yellowstone server"); + + let server_thread = server.run_server().expect("Failed to run server"); + + spawn_from_vmmo( + unsafe { mammoth::init::BOOT_DENALI_VMMO }, + server + .create_client_cap() + .expect("Failed to create client cap for denali"), + ) + .expect("Failed to spawn denali"); + + context.wait_denali().expect("Failed to wait for denali"); + + mammoth::debug!("Denali registered."); + + server_thread.join().expect("Failed to join thread"); + 0 +} diff --git a/rust/sys/yellowstone/src/server.rs b/rust/sys/yellowstone/src/server.rs new file mode 100644 index 0000000..d3da021 --- /dev/null +++ b/rust/sys/yellowstone/src/server.rs @@ -0,0 +1,58 @@ +use alloc::rc::Rc; +use mammoth::zion::ZError; +use yellowstone_yunq::{ + AhciInfo, DenaliInfo, Endpoint, FramebufferInfo, GetEndpointRequest, RegisterEndpointRequest, + XhciInfo, YellowstoneServerHandler, +}; + +pub struct YellowstoneServerContext { + denali_semaphore: mammoth::sync::Semaphore, +} + +impl YellowstoneServerContext { + pub fn new() -> Result { + Ok(Self { + denali_semaphore: mammoth::sync::Semaphore::new()?, + }) + } + + pub fn wait_denali(&self) -> Result<(), ZError> { + self.denali_semaphore.wait() + } +} + +pub struct YellowstoneServerImpl { + context: Rc, +} + +impl YellowstoneServerImpl { + pub fn new(context: Rc) -> Self { + Self { context } + } +} + +impl YellowstoneServerHandler for YellowstoneServerImpl { + fn register_endpoint(&self, req: &RegisterEndpointRequest) -> Result<(), ZError> { + todo!() + } + + fn get_endpoint(&self, req: &GetEndpointRequest) -> Result { + todo!() + } + + fn get_ahci_info(&self) -> Result { + todo!() + } + + fn get_xhci_info(&self) -> Result { + todo!() + } + + fn get_framebuffer_info(&self) -> Result { + todo!() + } + + fn get_denali(&self) -> Result { + todo!() + } +} diff --git a/rust/usr/testbed/Cargo.toml b/rust/usr/testbed/Cargo.toml index 7934e6c..aff88d2 100644 --- a/rust/usr/testbed/Cargo.toml +++ b/rust/usr/testbed/Cargo.toml @@ -5,5 +5,5 @@ edition = "2021" [dependencies] mammoth = { path = "../../lib/mammoth" } -yellowstone = { path = "../../lib/yellowstone" } +yellowstone-yunq = { path = "../../lib/yellowstone" } yunq = { path = "../../lib/yunq" } diff --git a/rust/usr/testbed/src/main.rs b/rust/usr/testbed/src/main.rs index 9b6ad6b..a6a5ca0 100644 --- a/rust/usr/testbed/src/main.rs +++ b/rust/usr/testbed/src/main.rs @@ -8,7 +8,7 @@ use mammoth::debug; use mammoth::define_entry; use mammoth::thread; use mammoth::zion::z_err_t; -use yellowstone::GetEndpointRequest; +use yellowstone_yunq::GetEndpointRequest; define_entry!(); @@ -16,7 +16,7 @@ define_entry!(); pub extern "C" fn main() -> z_err_t { debug!("Testing!"); - let yellowstone = yellowstone::from_init_endpoint(); + let yellowstone = yellowstone_yunq::from_init_endpoint(); debug!("Get endpoint"); diff --git a/scripts/build_image.sh b/scripts/build_image.sh index e26074f..826bdd4 100644 --- a/scripts/build_image.sh +++ b/scripts/build_image.sh @@ -39,7 +39,7 @@ cp /usr/share/limine/limine-bios.sys efi/ cp ../zion/boot/limine.cfg efi/ cp zion/zion efi/ mkdir -p efi/sys -cp sys/yellowstone/yellowstone efi/sys/yellowstone +cp ../sysroot/bin/yellowstone efi/sys/yellowstone cp sys/denali/denali efi/sys/denali cp sys/victoriafalls/victoriafalls efi/sys/victoriafalls