Arguments are actually passed into programs

pull/12/head
able 2023-11-13 23:51:30 -06:00
parent 3d0dcc78d6
commit c37d6d471d
9 changed files with 257 additions and 163 deletions

View File

@ -1,37 +1,46 @@
mod memory; mod memory;
use core::{arch::{asm, global_asm}, fmt::Write}; use {
use alloc::boxed::Box; alloc::boxed::Box,
use sbi::system_reset::{ResetType, ResetReason, system_reset}; core::{
use spin::{Mutex, Once}; arch::{asm, global_asm},
use uart_16550::MmioSerialPort; 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!("entry.s"));
global_asm!(include_str!("memory_regions.s")); global_asm!(include_str!("memory_regions.s"));
pub const PAGE_SIZE: usize = 4096; pub const PAGE_SIZE: usize = 4096;
extern { extern "C" {
static TEXT_START: PhysicalAddress; static TEXT_START: PhysicalAddress;
static TEXT_END: PhysicalAddress; static TEXT_END: PhysicalAddress;
static RODATA_START: PhysicalAddress; static RODATA_START: PhysicalAddress;
static RODATA_END: PhysicalAddress; static RODATA_END: PhysicalAddress;
static DATA_START: PhysicalAddress; static DATA_START: PhysicalAddress;
static DATA_END: PhysicalAddress; static DATA_END: PhysicalAddress;
static SDATA_START: PhysicalAddress; static SDATA_START: PhysicalAddress;
static SDATA_END: PhysicalAddress; static SDATA_END: PhysicalAddress;
static BSS_START: PhysicalAddress; static BSS_START: PhysicalAddress;
static BSS_END: PhysicalAddress; static BSS_END: PhysicalAddress;
static INITIAL_KERNEL_HEAP_START: PhysicalAddress; static INITIAL_KERNEL_HEAP_START: PhysicalAddress;
static INITIAL_KERNEL_HEAP_SIZE: usize; static INITIAL_KERNEL_HEAP_SIZE: usize;
static USABLE_MEMORY_START: PhysicalAddress; static USABLE_MEMORY_START: PhysicalAddress;
static USABLE_MEMORY_SIZE: usize; static USABLE_MEMORY_SIZE: usize;
} }
@ -39,12 +48,15 @@ extern {
static SERIAL_CONSOLE: Once<Mutex<MmioSerialPort>> = Once::new(); static SERIAL_CONSOLE: Once<Mutex<MmioSerialPort>> = Once::new();
#[no_mangle] #[no_mangle]
unsafe extern fn _kernel_start() -> ! { unsafe extern "C" fn _kernel_start() -> ! {
SERIAL_CONSOLE.call_once(|| Mutex::new(unsafe { MmioSerialPort::new(0x1000_0000) })); SERIAL_CONSOLE.call_once(|| Mutex::new(unsafe { MmioSerialPort::new(0x1000_0000) }));
crate::logger::init().expect("failed to set logger"); crate::logger::init().expect("failed to set logger");
log::info!("Initialising AKern {}", crate::VERSION); log::info!("Initialising AKern {}", crate::VERSION);
allocator::init(INITIAL_KERNEL_HEAP_START.as_mut_ptr::<u8>(), INITIAL_KERNEL_HEAP_SIZE); allocator::init(
INITIAL_KERNEL_HEAP_START.as_mut_ptr::<u8>(),
INITIAL_KERNEL_HEAP_SIZE,
);
memory::init(USABLE_MEMORY_START.into(), USABLE_MEMORY_SIZE / PAGE_SIZE); memory::init(USABLE_MEMORY_START.into(), USABLE_MEMORY_SIZE / PAGE_SIZE);
let mut page_table_addr = PAGE_TABLE.get().unwrap().lock(); 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) // Map bss section (includes stack and initial kernel heap)
page_table.identity_map_range(BSS_START, BSS_END, PageEntryFlags::ReadWrite); page_table.identity_map_range(BSS_START, BSS_END, PageEntryFlags::ReadWrite);
// Map usable memory range (as rw so not executable) // 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 // 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 table_ppn = page_table_addr.as_addr() as usize >> 12;
let satp_value = 8 << 60 | table_ppn; let satp_value = 8 << 60 | table_ppn;

View File

@ -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<Mutex<Display>> = Lazy::new(|| {
static FB_REQ: FramebufferRequest = FramebufferRequest::new(0);
let fb1: &NonNullPtr<Framebuffer> = &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<u32> = 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<T: Transport>(transport: T) {
// let mut gpu = VirtIOGpu::<AbleosHal, T>::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");
// }

View File

@ -1,9 +1,6 @@
use { use {
crate::{arch::x86_64::graphics::DISPLAY, bootmodules::BootModule}, crate::bootmodules::BootModule, core::arch::asm, embedded_graphics::pixelcolor::Rgb888,
core::arch::asm, log::warn, rdrand::RdSeed,
embedded_graphics::pixelcolor::Rgb888,
log::warn,
rdrand::RdSeed,
}; };
pub mod memory; pub mod memory;
@ -83,51 +80,51 @@ unsafe extern "C" fn start() -> ! {
device_info_collector::collect_device_info(); device_info_collector::collect_device_info();
// Graphics test // Graphics test
{ // {
graphics::init(); // graphics::init();
let mut dis = DISPLAY.lock(); // let mut dis = DISPLAY.lock();
use embedded_graphics::prelude::RgbColor; // use embedded_graphics::prelude::RgbColor;
let _ = dis.set_color(Rgb888::YELLOW); // let _ = dis.set_color(Rgb888::YELLOW);
let thick = 6; // let thick = 6;
let p1 = (400, 30); // let p1 = (400, 30);
let p2 = (200, 150); // let p2 = (200, 150);
let p3 = (600, 150); // let p3 = (600, 150);
let p4 = (200, 350); // let p4 = (200, 350);
let p5 = (600, 350); // let p5 = (600, 350);
let p6 = (400, 470); // 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, p2.0, p2.1, thick);
let _ = dis.line(p1.0, p1.1, p3.0, p3.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(p2.0, p2.1, p4.0, p4.1, thick);
let _ = dis.line(p3.0, p3.1, p5.0, p5.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, p4.0, p4.1, thick);
let _ = dis.line(p6.0, p6.1, p5.0, p5.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, 150, 200, 350, thick);
let _ = dis.line(600, 350, 400, 250, thick); // let _ = dis.line(600, 350, 400, 250, thick);
} // }
{ // {
let _ = dis.set_color(Rgb888::WHITE); // let _ = dis.set_color(Rgb888::WHITE);
let hp1 = (350, 150); // let hp1 = (350, 150);
let hp2 = (350, 350); // let hp2 = (350, 350);
let hp3 = (450, 250); // let hp3 = (450, 250);
let hp4 = (350, 250); // let hp4 = (350, 250);
let hp5 = (450, 150); // let hp5 = (450, 150);
let hp6 = (450, 350); // let hp6 = (450, 350);
let _ = dis.line(hp1.0, hp1.1, hp2.0, hp2.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(hp3.0, hp3.1, hp4.0, hp4.1, thick);
let _ = dis.line(hp5.0, hp5.1, hp6.0, hp6.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 // TODO: Add in rdseed and rdrand as sources for randomness
let _rand = xml::XMLElement::new("Random"); let _rand = xml::XMLElement::new("Random");

View File

@ -25,6 +25,11 @@ pub struct ExecThread<'p> {
unsafe impl<'p> Send for ExecThread<'p> {} unsafe impl<'p> Send for ExecThread<'p> {}
impl<'p> 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 { pub unsafe fn new(program: &'p [u8], entrypoint: Address) -> Self {
ExecThread { ExecThread {
vm: unsafe { vm: unsafe {

View File

@ -1,19 +1,17 @@
//! AbleOS Kernel Entrypoint //! AbleOS Kernel Entrypoint
use {hashbrown::HashMap, hbvm::mem::Address};
use crate::{
capabilities,
holeybytes::ExecThread,
ipc::buffer::{self, IpcBuffer},
};
// use crate::arch::sloop;
use { use {
crate::{ crate::{
bootmodules::{build_cmd, BootModules}, bootmodules::{build_cmd, BootModules},
capabilities,
device_tree::DeviceTree, device_tree::DeviceTree,
holeybytes::ExecThread,
ipc::buffer::{self, IpcBuffer},
}, },
alloc::format, alloc::format,
hashbrown::HashMap,
hbvm::mem::Address,
limine::{Framebuffer, FramebufferRequest, NonNullPtr},
log::{debug, info, trace}, log::{debug, info, trace},
spin::{Lazy, Mutex}, spin::{Lazy, Mutex},
xml::XMLElement, xml::XMLElement,
@ -32,6 +30,7 @@ pub fn kmain(cmdline: &str, boot_modules: BootModules) -> ! {
// TODO: pass into the program // TODO: pass into the program
// Pass CMDLine into an IPCBuffer and put the ptr to the IPCBuffer in r200 // Pass CMDLine into an IPCBuffer and put the ptr to the IPCBuffer in r200
_bmcmd = build_cmd(name, bm.cmd.clone()); _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 VFS from initramfs
// TODO: schedule the init system from the initramfs // TODO: schedule the init system from the initramfs
drop(dt);
let fb1: &NonNullPtr<Framebuffer> = &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 mut executor = crate::task::Executor::default();
let bm_take = boot_modules.len(); let bm_take = boot_modules.len();
unsafe { unsafe {
for module in boot_modules.into_iter().take(bm_take) { 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 { 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:?}"); log::error!("{e:?}");
} }
}); });
@ -68,6 +102,7 @@ pub static DEVICE_TREE: Lazy<Mutex<DeviceTree>> = Lazy::new(|| {
let dt = DeviceTree::new(); let dt = DeviceTree::new();
Mutex::new(dt) Mutex::new(dt)
}); });
pub static FB_REQ: FramebufferRequest = FramebufferRequest::new(0);
use alloc::vec::Vec; use alloc::vec::Vec;
pub type IpcBuffers = HashMap<u64, IpcBuffer>; pub type IpcBuffers = HashMap<u64, IpcBuffer>;

View File

@ -1,3 +1,4 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
extern crate kernel; extern crate kernel;

View File

@ -139,9 +139,7 @@ fn get_fs() -> Result<FileSystem<impl ReadWriteSeek>, io::Error> {
io::copy( io::copy(
&mut File::open("limine/BOOTAA64.EFI") &mut File::open("limine/BOOTAA64.EFI")
.map_err(Report::from) .map_err(Report::from)
.attach_printable( .attach_printable("Copying Limine (ARM): have you pulled the submodule?")?,
"Copying Limine (ARM): have you pulled the submodule?",
)?,
&mut bootdir.create_file("bootaa64.efi")?, &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", "-drive", "file=target/disk.img,format=raw",
"-m", "4G", "-m", "4G",
"-smp", "cores=4", "-smp", "cores=4",
// "-enable-kvm",
"-cpu", "Broadwell-v4" "-cpu", "Broadwell-v4"
]); ]);
} }

View File

@ -31,4 +31,4 @@ TERM_BACKDROP=008080
MODULE_CMDLINE="" MODULE_CMDLINE=""
MODULE_PATH=boot:///limine_framebuffer_driver.hbf MODULE_PATH=boot:///limine_framebuffer_driver.hbf
MODULE_CMDLINE="" MODULE_CMDLINE="height=10 width=10 arch=${ARCH}"

View File

@ -4,26 +4,134 @@
// Use std abstractions if they exist like logging functionality // Use std abstractions if they exist like logging functionality
import "sysdata/test-programs/hblib/std" as std; 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. fn rect(reg_x, reg_y, w, h, color) {
tx(); 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(); 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();