Arguments are actually passed into programs

This commit is contained in:
able 2023-11-13 23:51:30 -06:00
parent f2e561e242
commit f074527e42
9 changed files with 257 additions and 163 deletions

View file

@ -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<Mutex<MmioSerialPort>> = 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::<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);
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;

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 {
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");

View file

@ -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 {

View file

@ -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<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 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<Mutex<DeviceTree>> = 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<u64, IpcBuffer>;

View file

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

View file

@ -139,9 +139,7 @@ fn get_fs() -> Result<FileSystem<impl ReadWriteSeek>, 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"
]);
}

View file

@ -31,4 +31,4 @@ TERM_BACKDROP=008080
MODULE_CMDLINE=""
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
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();
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();