From c37d6d471d572986ad2d46197114a58131677185 Mon Sep 17 00:00:00 2001 From: able Date: Mon, 13 Nov 2023 23:51:30 -0600 Subject: [PATCH] Arguments are actually passed into programs --- kernel/src/arch/riscv64/mod.rs | 50 ++++-- kernel/src/arch/x86_64/graphics.rs | 71 --------- kernel/src/arch/x86_64/mod.rs | 85 +++++----- kernel/src/holeybytes/mod.rs | 5 + kernel/src/kmain.rs | 53 +++++-- kernel/src/main.rs | 1 + repbuild/src/main.rs | 5 +- sysdata/limine.cfg | 2 +- .../limine_framebuffer_driver.rhai | 148 +++++++++++++++--- 9 files changed, 257 insertions(+), 163 deletions(-) diff --git a/kernel/src/arch/riscv64/mod.rs b/kernel/src/arch/riscv64/mod.rs index 0c7e966..2caa6c3 100644 --- a/kernel/src/arch/riscv64/mod.rs +++ b/kernel/src/arch/riscv64/mod.rs @@ -1,37 +1,46 @@ mod memory; -use core::{arch::{asm, global_asm}, fmt::Write}; -use alloc::boxed::Box; -use sbi::system_reset::{ResetType, ResetReason, system_reset}; -use spin::{Mutex, Once}; -use uart_16550::MmioSerialPort; +use { + alloc::boxed::Box, + core::{ + arch::{asm, global_asm}, + fmt::Write, + }, + sbi::system_reset::{system_reset, ResetReason, ResetType}, + spin::{Mutex, Once}, + uart_16550::MmioSerialPort, +}; -use crate::{allocator, memory::PhysicalAddress, arch::riscv64::memory::{PAGE_TABLE, PageEntryFlags, PageSize, PageTable}}; +use crate::{ + allocator, + arch::riscv64::memory::{PageEntryFlags, PageSize, PageTable, PAGE_TABLE}, + memory::PhysicalAddress, +}; global_asm!(include_str!("entry.s")); global_asm!(include_str!("memory_regions.s")); pub const PAGE_SIZE: usize = 4096; -extern { +extern "C" { static TEXT_START: PhysicalAddress; static TEXT_END: PhysicalAddress; static RODATA_START: PhysicalAddress; static RODATA_END: PhysicalAddress; - + static DATA_START: PhysicalAddress; static DATA_END: PhysicalAddress; static SDATA_START: PhysicalAddress; static SDATA_END: PhysicalAddress; - + static BSS_START: PhysicalAddress; static BSS_END: PhysicalAddress; - + static INITIAL_KERNEL_HEAP_START: PhysicalAddress; static INITIAL_KERNEL_HEAP_SIZE: usize; - + static USABLE_MEMORY_START: PhysicalAddress; static USABLE_MEMORY_SIZE: usize; } @@ -39,12 +48,15 @@ extern { static SERIAL_CONSOLE: Once> = Once::new(); #[no_mangle] -unsafe extern fn _kernel_start() -> ! { +unsafe extern "C" fn _kernel_start() -> ! { SERIAL_CONSOLE.call_once(|| Mutex::new(unsafe { MmioSerialPort::new(0x1000_0000) })); crate::logger::init().expect("failed to set logger"); log::info!("Initialising AKern {}", crate::VERSION); - allocator::init(INITIAL_KERNEL_HEAP_START.as_mut_ptr::(), INITIAL_KERNEL_HEAP_SIZE); + allocator::init( + INITIAL_KERNEL_HEAP_START.as_mut_ptr::(), + INITIAL_KERNEL_HEAP_SIZE, + ); memory::init(USABLE_MEMORY_START.into(), USABLE_MEMORY_SIZE / PAGE_SIZE); let mut page_table_addr = PAGE_TABLE.get().unwrap().lock(); @@ -61,9 +73,17 @@ unsafe extern fn _kernel_start() -> ! { // Map bss section (includes stack and initial kernel heap) page_table.identity_map_range(BSS_START, BSS_END, PageEntryFlags::ReadWrite); // Map usable memory range (as rw so not executable) - page_table.identity_map_range(USABLE_MEMORY_START, USABLE_MEMORY_START + USABLE_MEMORY_SIZE.into(), PageEntryFlags::ReadWrite); + page_table.identity_map_range( + USABLE_MEMORY_START, + USABLE_MEMORY_START + USABLE_MEMORY_SIZE.into(), + PageEntryFlags::ReadWrite, + ); // Map Uart so we can continue using serial - page_table.identity_map(0x1000_0000_usize.into(), PageEntryFlags::ReadWrite, PageSize::Size4KiB); + page_table.identity_map( + 0x1000_0000_usize.into(), + PageEntryFlags::ReadWrite, + PageSize::Size4KiB, + ); let table_ppn = page_table_addr.as_addr() as usize >> 12; let satp_value = 8 << 60 | table_ppn; diff --git a/kernel/src/arch/x86_64/graphics.rs b/kernel/src/arch/x86_64/graphics.rs index 2f36627..8b13789 100644 --- a/kernel/src/arch/x86_64/graphics.rs +++ b/kernel/src/arch/x86_64/graphics.rs @@ -1,72 +1 @@ -use { - crate::kmain::DEVICE_TREE, - able_graphics_library::raw_pixel::Display, - embedded_graphics::{pixelcolor::Rgb888, prelude::*}, - limine::{Framebuffer, FramebufferRequest, NonNullPtr}, - spin::{Lazy, Mutex}, -}; -pub static DISPLAY: Lazy> = Lazy::new(|| { - static FB_REQ: FramebufferRequest = FramebufferRequest::new(0); - let fb1: &NonNullPtr = &FB_REQ.get_response().get().unwrap().framebuffers()[0]; - - { - use crate::alloc::string::ToString; - let mut dt = DEVICE_TREE.lock(); - let mut disp = xml::XMLElement::new("display_0"); - - disp.set_attribute("width", fb1.width); - disp.set_attribute("height", fb1.height); - disp.set_attribute("bits per pixel", fb1.bpp); - disp.set_attribute("pitch", fb1.pitch); - // disp.set_attribute("fb ptr", fb1.address.as_ptr().unwrap()); - dt.devices.insert("Displays".to_string(), alloc::vec![disp]); - } - let _size: usize = (fb1.width * fb1.height).try_into().unwrap(); - let back_buffer: alloc::vec::Vec = alloc::vec![0; 800*600]; - - let m = Mutex::new(Display { - fb: fb1.address.as_ptr().unwrap().cast(), - bb: back_buffer.as_slice().as_ptr() as *mut u32, - size: Size::new(fb1.width as u32, fb1.height as u32), - color: Rgb888::WHITE, - }); - log::info!("Graphics initialised"); - log::info!( - "Graphics front ptr {:?}", - fb1.address.as_ptr().unwrap() as *const u8 - ); - m -}); - -pub fn init() { - Lazy::force(&DISPLAY); -} -// pub fn virtio_gpu(transport: T) { -// let mut gpu = VirtIOGpu::::new(transport).expect("failed to create gpu driver"); -// let (width, height) = gpu.resolution().expect("failed to get resolution"); -// let width = width as usize; -// let height = height as usize; -// log::info!("GPU resolution is {}x{}", width, height); -// let fb = gpu.setup_framebuffer().expect("failed to get fb"); -// for y in 0..height { -// for x in 0..width { -// let idx = (y * width + x) * 4; -// fb[idx] = x as u8; -// fb[idx + 1] = y as u8; -// fb[idx + 2] = (x + y) as u8; -// } -// } -// gpu.flush().expect("failed to flush"); -// //delay some time -// log::info!("virtio-gpu show graphics...."); -// for _ in 0..100000 { -// for _ in 0..100000 { -// unsafe { -// core::arch::asm!("nop"); -// } -// } -// } - -// log::info!("virtio-gpu test finished"); -// } diff --git a/kernel/src/arch/x86_64/mod.rs b/kernel/src/arch/x86_64/mod.rs index a8bae23..a67a7ed 100644 --- a/kernel/src/arch/x86_64/mod.rs +++ b/kernel/src/arch/x86_64/mod.rs @@ -1,9 +1,6 @@ use { - crate::{arch::x86_64::graphics::DISPLAY, bootmodules::BootModule}, - core::arch::asm, - embedded_graphics::pixelcolor::Rgb888, - log::warn, - rdrand::RdSeed, + crate::bootmodules::BootModule, core::arch::asm, embedded_graphics::pixelcolor::Rgb888, + log::warn, rdrand::RdSeed, }; pub mod memory; @@ -83,51 +80,51 @@ unsafe extern "C" fn start() -> ! { device_info_collector::collect_device_info(); // Graphics test - { - graphics::init(); - let mut dis = DISPLAY.lock(); - use embedded_graphics::prelude::RgbColor; + // { + // graphics::init(); + // let mut dis = DISPLAY.lock(); + // use embedded_graphics::prelude::RgbColor; - let _ = dis.set_color(Rgb888::YELLOW); - let thick = 6; - let p1 = (400, 30); - let p2 = (200, 150); - let p3 = (600, 150); - let p4 = (200, 350); - let p5 = (600, 350); - let p6 = (400, 470); + // let _ = dis.set_color(Rgb888::YELLOW); + // let thick = 6; + // let p1 = (400, 30); + // let p2 = (200, 150); + // let p3 = (600, 150); + // let p4 = (200, 350); + // let p5 = (600, 350); + // let p6 = (400, 470); - { - //HEXAGON + // { + // //HEXAGON - let _ = dis.line(p1.0, p1.1, p2.0, p2.1, thick); - let _ = dis.line(p1.0, p1.1, p3.0, p3.1, thick); - let _ = dis.line(p2.0, p2.1, p4.0, p4.1, thick); - let _ = dis.line(p3.0, p3.1, p5.0, p5.1, thick); - let _ = dis.line(p6.0, p6.1, p4.0, p4.1, thick); - let _ = dis.line(p6.0, p6.1, p5.0, p5.1, thick); - } - { - let _ = dis.line(600, 150, 200, 350, thick); - let _ = dis.line(600, 350, 400, 250, thick); - } + // let _ = dis.line(p1.0, p1.1, p2.0, p2.1, thick); + // let _ = dis.line(p1.0, p1.1, p3.0, p3.1, thick); + // let _ = dis.line(p2.0, p2.1, p4.0, p4.1, thick); + // let _ = dis.line(p3.0, p3.1, p5.0, p5.1, thick); + // let _ = dis.line(p6.0, p6.1, p4.0, p4.1, thick); + // let _ = dis.line(p6.0, p6.1, p5.0, p5.1, thick); + // } + // { + // let _ = dis.line(600, 150, 200, 350, thick); + // let _ = dis.line(600, 350, 400, 250, thick); + // } - { - let _ = dis.set_color(Rgb888::WHITE); - let hp1 = (350, 150); - let hp2 = (350, 350); - let hp3 = (450, 250); - let hp4 = (350, 250); - let hp5 = (450, 150); - let hp6 = (450, 350); + // { + // let _ = dis.set_color(Rgb888::WHITE); + // let hp1 = (350, 150); + // let hp2 = (350, 350); + // let hp3 = (450, 250); + // let hp4 = (350, 250); + // let hp5 = (450, 150); + // let hp6 = (450, 350); - let _ = dis.line(hp1.0, hp1.1, hp2.0, hp2.1, thick); - let _ = dis.line(hp3.0, hp3.1, hp4.0, hp4.1, thick); - let _ = dis.line(hp5.0, hp5.1, hp6.0, hp6.1, thick); - } + // let _ = dis.line(hp1.0, hp1.1, hp2.0, hp2.1, thick); + // let _ = dis.line(hp3.0, hp3.1, hp4.0, hp4.1, thick); + // let _ = dis.line(hp5.0, hp5.1, hp6.0, hp6.1, thick); + // } - dis.swap_buffers(); - }; + // dis.swap_buffers(); + // }; // TODO: Add in rdseed and rdrand as sources for randomness let _rand = xml::XMLElement::new("Random"); diff --git a/kernel/src/holeybytes/mod.rs b/kernel/src/holeybytes/mod.rs index 3b79f5e..7161648 100644 --- a/kernel/src/holeybytes/mod.rs +++ b/kernel/src/holeybytes/mod.rs @@ -25,6 +25,11 @@ pub struct ExecThread<'p> { unsafe impl<'p> Send for ExecThread<'p> {} impl<'p> ExecThread<'p> { + pub fn set_arguments(&mut self, ptr: u64, length: u64) { + self.vm.registers[1] = hbvm::value::Value(ptr); + self.vm.registers[2] = hbvm::value::Value(length); + } + pub unsafe fn new(program: &'p [u8], entrypoint: Address) -> Self { ExecThread { vm: unsafe { diff --git a/kernel/src/kmain.rs b/kernel/src/kmain.rs index 21de41f..4c9648c 100644 --- a/kernel/src/kmain.rs +++ b/kernel/src/kmain.rs @@ -1,19 +1,17 @@ //! AbleOS Kernel Entrypoint -use {hashbrown::HashMap, hbvm::mem::Address}; - -use crate::{ - capabilities, - holeybytes::ExecThread, - ipc::buffer::{self, IpcBuffer}, -}; -// use crate::arch::sloop; use { crate::{ bootmodules::{build_cmd, BootModules}, + capabilities, device_tree::DeviceTree, + holeybytes::ExecThread, + ipc::buffer::{self, IpcBuffer}, }, alloc::format, + hashbrown::HashMap, + hbvm::mem::Address, + limine::{Framebuffer, FramebufferRequest, NonNullPtr}, log::{debug, info, trace}, spin::{Lazy, Mutex}, xml::XMLElement, @@ -32,6 +30,7 @@ pub fn kmain(cmdline: &str, boot_modules: BootModules) -> ! { // TODO: pass into the program // Pass CMDLine into an IPCBuffer and put the ptr to the IPCBuffer in r200 _bmcmd = build_cmd(name, bm.cmd.clone()); + log::info!("{:?}", _bmcmd); } } @@ -47,12 +46,47 @@ pub fn kmain(cmdline: &str, boot_modules: BootModules) -> ! { // TODO: Schedule the VFS from initramfs // TODO: schedule the init system from the initramfs + drop(dt); + + let fb1: &NonNullPtr = &FB_REQ.get_response().get().unwrap().framebuffers()[0]; + + { + use crate::alloc::string::ToString; + let mut dt = DEVICE_TREE.lock(); + let mut disp = xml::XMLElement::new("display_0"); + + disp.set_attribute("width", fb1.width); + disp.set_attribute("height", fb1.height); + disp.set_attribute("bits per pixel", fb1.bpp); + disp.set_attribute("pitch", fb1.pitch); + dt.devices.insert("Displays".to_string(), alloc::vec![disp]); + } + log::info!("Graphics initialised"); + log::info!( + "Graphics front ptr {:?}", + fb1.address.as_ptr().unwrap() as *const u8 + ); + let mut executor = crate::task::Executor::default(); let bm_take = boot_modules.len(); unsafe { for module in boot_modules.into_iter().take(bm_take) { + let mut cmd = module.cmd; + { + // Remove the quotes + cmd.remove(0); + cmd.pop(); + } + let cmd_len = cmd.as_bytes().len() as u64; + + log::info!("Spawning {} with arguments \"{}\"", module.path, cmd); + executor.spawn(async move { - if let Err(e) = ExecThread::new(&module.bytes, Address::new(0)).await { + let mut thr = ExecThread::new(&module.bytes, Address::new(0)); + if cmd_len > 0 { + thr.set_arguments(cmd.as_bytes().as_ptr() as u64, cmd_len); + } + if let Err(e) = thr.await { log::error!("{e:?}"); } }); @@ -68,6 +102,7 @@ pub static DEVICE_TREE: Lazy> = Lazy::new(|| { let dt = DeviceTree::new(); Mutex::new(dt) }); +pub static FB_REQ: FramebufferRequest = FramebufferRequest::new(0); use alloc::vec::Vec; pub type IpcBuffers = HashMap; diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 308e166..973e301 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -1,3 +1,4 @@ #![no_std] #![no_main] + extern crate kernel; diff --git a/repbuild/src/main.rs b/repbuild/src/main.rs index a0e6caf..f9c0691 100644 --- a/repbuild/src/main.rs +++ b/repbuild/src/main.rs @@ -139,9 +139,7 @@ fn get_fs() -> Result, io::Error> { io::copy( &mut File::open("limine/BOOTAA64.EFI") .map_err(Report::from) - .attach_printable( - "Copying Limine (ARM): have you pulled the submodule?", - )?, + .attach_printable("Copying Limine (ARM): have you pulled the submodule?")?, &mut bootdir.create_file("bootaa64.efi")?, )?; @@ -233,6 +231,7 @@ fn run(release: bool, target: Target) -> Result<(), Error> { "-drive", "file=target/disk.img,format=raw", "-m", "4G", "-smp", "cores=4", + // "-enable-kvm", "-cpu", "Broadwell-v4" ]); } diff --git a/sysdata/limine.cfg b/sysdata/limine.cfg index e1acf4e..8e5699f 100644 --- a/sysdata/limine.cfg +++ b/sysdata/limine.cfg @@ -31,4 +31,4 @@ TERM_BACKDROP=008080 MODULE_CMDLINE="" MODULE_PATH=boot:///limine_framebuffer_driver.hbf - MODULE_CMDLINE="" \ No newline at end of file + MODULE_CMDLINE="height=10 width=10 arch=${ARCH}" \ No newline at end of file diff --git a/sysdata/test-programs/limine_framebuffer_driver.rhai b/sysdata/test-programs/limine_framebuffer_driver.rhai index 10e2214..d005cbc 100644 --- a/sysdata/test-programs/limine_framebuffer_driver.rhai +++ b/sysdata/test-programs/limine_framebuffer_driver.rhai @@ -4,26 +4,134 @@ // Use std abstractions if they exist like logging functionality import "sysdata/test-programs/hblib/std" as std; -// Define main -fn main(){ - std::Info("Starting the limine framebuffer driver."); - // Color - li64(r1, 0xffffffff); - // iterator - li32(r2, 0); - // count - li64(r3, 12); - // Label here - let start = label(); - // Write to the memory - st(r1, r2, 0xFFFF8000C0000000, 1); - // Increment - addi64(r2, r2, 1); - // std::Info("abc"); - jltu(r2, r3, start); - // Terminate execution. - tx(); +fn rect(reg_x, reg_y, w, h, color) { + li64(r3, 0); + li64(r4, 0); + li64(r5, w); + li64(r6, h); + + let start_y = label(); + + let start_x = label(); + + add64(r9, r3, reg_x); + add64(r10, r4, reg_y); + pixel(r9, r10, color); + + li64(r1, 1); + add64(r3, r3, r1); + + jltu(r3, r5, start_x); + + li64(r1, 1); + add64(r4, r4, r1); + + li64(r3, 0); + + jltu(r4, r6, start_y); } -main(); \ No newline at end of file +fn pixel(reg_x, reg_y, color) { + let BUFFER = 0xFFFF8000C0000000; + let WIDTH = 1024; + + // r1 = y * WIDTH + li64(r1, WIDTH); + mul64(r1, reg_y, r1); + + // r2 = x + r2 + add64(r2, reg_x, r1); + + // r2 = r2 * 4 + li64(r1, 4); + mul64(r2, r2, r1); + + // store pixel value + li64(r1, color); + st(r1, r2, BUFFER, 4); +} + +fn clear() { +// rect(r0, r0, 1024, 768, 0xff222222); + + let BUFFER = 0xFFFF8000C0000000; + // on arm the FB is at 0xFFFF8000BC430000 + // FIXME: get the framebuffer pointer from the starting arguments + + li64(r1, 0xff222222); + li64(r2, 0); + li64(r3, 1); + li64(r4, 1024 * 768); + li64(r5, 4); + let start = label(); + mul64(r6, r2, r5); + st(r1, r6, BUFFER, 4); + add64(r2, r2, r3); + jltu(r2, r4, start); +} + +// Define main +fn main(){ + std::Info("Starting the limine framebuffer driver."); + + li64(r100, 300); + li64(r101, 300); + li64(r102, 1); + li64(r103, 1); + li64(r104, 1024 - 20); + li64(r105, 768 - 20); + li64(r106, 0); + li64(r107, 0); + + clear(); + + let start = label(); + + rect(r100, r101, 20, 20, 0xff222222); + //clear(); + + add64(r100, r100, r102); + add64(r101, r101, r103); + + let after_x_right = declabel(); + jltu(r100, r104, after_x_right); + li64(r102, -1); + here(after_x_right); + + let after_x_left = declabel(); + jgtu(r100, r106, after_x_left); + li64(r102, 1); + li64(r100, 0); + here(after_x_left); + + let after_y_right = declabel(); + jltu(r101, r105, after_y_right); + li64(r103, -1); + here(after_y_right); + + let after_y_left = declabel(); + jgtu(r101, r107, after_y_left); + li64(r103, 1); + li64(r101, 0); + here(after_y_left); + + rect(r100, r101, 20, 20, 0xffffffff); + + li64(r200, 0); + li64(r201, 1); + li64(r202, 10000); + let wait = label(); + add64(r200, r200, r201); + jltu(r200, r202, wait); + + jeq(r0, r0, start); + //jmp(start); + + std::Info("done"); + + // Terminate execution. + tx(); +} + +main();