a touch of fiddling

This commit is contained in:
koniifer 2024-09-09 01:42:11 +01:00
parent 9b34e19005
commit fd155ea26a
24 changed files with 617 additions and 544 deletions

716
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,9 @@
[workspace] [workspace]
resolver = "2" resolver = "2"
members = [ "dev","kernel", "repbuild"] members = ["dev", "kernel", "repbuild"]
[profile.release]
strip = "symbols"
codegen-units = 1
lto = true
panic = "abort"

View file

@ -5,17 +5,17 @@ version = "0.2.0"
[dependencies] [dependencies]
embedded-graphics = "0.7" embedded-graphics = "0.8"
hbvm.git = "https://git.ablecorp.us/ableos/holey-bytes" hbvm.git = "https://git.ablecorp.us/ableos/holey-bytes"
log = "0.4" log = "0.4"
spin = "0.9" spin = "0.9"
uart_16550 = "0.2" uart_16550 = "0.3"
slab = { version = "0.4", default-features = false } slab = { version = "0.4", default-features = false }
xml.git = "https://git.ablecorp.us/ableos/ableos_userland" xml.git = "https://git.ablecorp.us/ableos/ableos_userland"
versioning.git = "https://git.ablecorp.us/ableos/ableos_userland" versioning.git = "https://git.ablecorp.us/ableos/ableos_userland"
able_graphics_library.git = "https://git.ablecorp.us/ableos/ableos_userland" # able_graphics_library.git = "https://git.ablecorp.us/ableos/ableos_userland"
hashbrown = "*" hashbrown = "0.14"
kiam = "0.1.1" kiam = "0.1"
[dependencies.limine] [dependencies.limine]
version = "0.1" version = "0.1"
@ -26,12 +26,12 @@ version = "0.3"
default-features = false default-features = false
features = ["alloc"] features = ["alloc"]
[dependencies.clparse] # [dependencies.clparse]
git = "https://git.ablecorp.us/ableos/ableos_userland" # git = "https://git.ablecorp.us/ableos/ableos_userland"
default-features = false # default-features = false
[dependencies.derive_more] [dependencies.derive_more]
version = "0.99" version = "1"
default-features = false default-features = false
features = [ features = [
"add", "add",
@ -48,9 +48,9 @@ features = [
[target.'cfg(target_arch = "x86_64")'.dependencies] [target.'cfg(target_arch = "x86_64")'.dependencies]
x86_64 = "0.14" x86_64 = "0.15"
x2apic = "0.4" x2apic = "0.4"
virtio-drivers = "0.4.0" virtio-drivers = "0.7"
# rdrand = "*" # rdrand = "*"
rdrand = { version = "0.8", default-features = false } rdrand = { version = "0.8", default-features = false }

View file

@ -39,7 +39,7 @@ static TSS: Lazy<TaskStateSegment> = Lazy::new(|| {
alloc::alloc::Layout::from_size_align(SIZE, 1).expect("stack pointer"), alloc::alloc::Layout::from_size_align(SIZE, 1).expect("stack pointer"),
) )
}; };
VirtAddr::from_ptr(stack) + SIZE VirtAddr::from_ptr(stack) + SIZE as u64
}; };
tss tss
}); });
@ -47,9 +47,9 @@ static TSS: Lazy<TaskStateSegment> = Lazy::new(|| {
static GDT: Lazy<(GlobalDescriptorTable, Selectors)> = Lazy::new(|| { static GDT: Lazy<(GlobalDescriptorTable, Selectors)> = Lazy::new(|| {
let mut gdt = GlobalDescriptorTable::new(); let mut gdt = GlobalDescriptorTable::new();
let sels = Selectors { let sels = Selectors {
kcode: gdt.add_entry(Descriptor::kernel_code_segment()), kcode: gdt.append(Descriptor::kernel_code_segment()),
kdata: gdt.add_entry(Descriptor::kernel_data_segment()), kdata: gdt.append(Descriptor::kernel_data_segment()),
tss: gdt.add_entry(Descriptor::tss_segment(&TSS)), tss: gdt.append(Descriptor::tss_segment(&TSS)),
}; };
(gdt, sels) (gdt, sels)
}); });

View file

@ -45,9 +45,9 @@ static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| {
} }
idt.page_fault.set_handler_fn(page_fault); idt.page_fault.set_handler_fn(page_fault);
idt[Interrupt::ApicErr as usize].set_handler_fn(apic_err); idt[Interrupt::ApicErr as u8].set_handler_fn(apic_err);
idt[Interrupt::Spurious as usize].set_handler_fn(spurious); idt[Interrupt::Spurious as u8].set_handler_fn(spurious);
idt[Interrupt::Timer as usize].set_handler_fn(timer); idt[Interrupt::Timer as u8].set_handler_fn(timer);
idt idt
}); });

View file

@ -1,11 +1,6 @@
//! Logging (as in terms of console / serial output) //! Logging (as in terms of console / serial output)
#![allow(deprecated)] #![allow(deprecated)]
use { use {core::fmt::Write, spin::Mutex, uart_16550::SerialPort};
core::fmt::Write,
limine::{TerminalRequest, TerminalResponse},
spin::{Lazy, Mutex},
uart_16550::SerialPort,
};
pub static SERIAL_CONSOLE: Mutex<SerialPort> = Mutex::new(unsafe { SerialPort::new(0x3F8) }); pub static SERIAL_CONSOLE: Mutex<SerialPort> = Mutex::new(unsafe { SerialPort::new(0x3F8) });

View file

@ -1,7 +1,4 @@
use { use {crate::bootmodules::BootModule, core::arch::asm, log::warn, rdrand::RdSeed};
crate::bootmodules::BootModule, core::arch::asm, embedded_graphics::pixelcolor::Rgb888,
log::warn, rdrand::RdSeed,
};
pub mod memory; pub mod memory;
mod cpuid; mod cpuid;
@ -208,7 +205,7 @@ pub fn hardware_random_u64() -> u64 {
trace!("Random {}", ret); trace!("Random {}", ret);
return ret; return ret;
} }
Err(err) => { Err(_) => {
warn!("RDRand not supported."); warn!("RDRand not supported.");
// Try rdseed // Try rdseed
let gen = RdSeed::new(); let gen = RdSeed::new();
@ -218,7 +215,7 @@ pub fn hardware_random_u64() -> u64 {
trace!("Random {}", ret); trace!("Random {}", ret);
return ret; return ret;
} }
Err(err) => { Err(_) => {
panic!("Neither RDRand or RDSeed are supported") panic!("Neither RDRand or RDSeed are supported")
} }
} }
@ -235,7 +232,7 @@ pub fn hardware_random_u32() -> u32 {
trace!("Random {}", ret); trace!("Random {}", ret);
return ret; return ret;
} }
Err(err) => { Err(_) => {
warn!("RDRand not supported."); warn!("RDRand not supported.");
// Try rdseed // Try rdseed
let gen = RdSeed::new(); let gen = RdSeed::new();
@ -245,7 +242,7 @@ pub fn hardware_random_u32() -> u32 {
trace!("Random {}", ret); trace!("Random {}", ret);
return ret; return ret;
} }
Err(err) => { Err(_) => {
panic!("Neither RDRand or RDSeed are supported") panic!("Neither RDRand or RDSeed are supported")
} }
} }
@ -255,6 +252,7 @@ pub fn hardware_random_u32() -> u32 {
pub fn get_edid() {} pub fn get_edid() {}
#[allow(unused)]
pub fn register_dump() { pub fn register_dump() {
let rax: u64; let rax: u64;
let rbx: u64 = 0; let rbx: u64 = 0;

View file

@ -1,10 +1,10 @@
use { use {
crate::alloc::string::ToString, // crate::alloc::string::ToString,
alloc::{string::String, vec::Vec}, alloc::{string::String, vec::Vec},
clparse::Arguments, // clparse::Arguments,
core::fmt::{Debug, Display}, // core::fmt::{Debug, Display},
log::trace, // log::trace,
xml::XMLElement, // xml::XMLElement,
}; };
pub type BootModules = Vec<BootModule>; pub type BootModules = Vec<BootModule>;
@ -19,18 +19,18 @@ impl BootModule {
} }
} }
pub fn build_cmd<T: Display + Debug>(name: T, cmdline: T) -> XMLElement { // pub fn build_cmd<T: Display + Debug>(name: T, cmdline: T) -> XMLElement {
let mut cmdline = cmdline.to_string(); // let mut cmdline = cmdline.to_string();
cmdline.pop(); // cmdline.pop();
cmdline.remove(0); // cmdline.remove(0);
let cmd = Arguments::parse(cmdline.to_string()).unwrap(); // let cmd = Arguments::parse(cmdline.to_string()).unwrap();
trace!("Cmdline: {cmd:?}"); // trace!("Cmdline: {cmd:?}");
let mut clo = XMLElement::new(name); // let mut clo = XMLElement::new(name);
for (key, value) in cmd.arguments { // for (key, value) in cmd.arguments {
clo.set_attribute(key, value); // clo.set_attribute(key, value);
} // }
trace!("command line object: {:?}", clo); // trace!("command line object: {:?}", clo);
clo // clo
} // }

View file

@ -1,18 +1,10 @@
//! Environment call handling routines //! Environment call handling routines
use core::borrow::Borrow; use crate::holeybytes::kernel_services::{block_read, service_definition_service::sds_msg_handler};
use crate::{
allocator,
holeybytes::kernel_services::{
block_read,
service_definition_service::{sds_msg_handler, SERVICES},
},
};
use { use {
super::{mem::Memory, Vm}, super::Vm,
crate::{arch, holeybytes::mem, ipc::buffer::IpcBuffer, kmain::IPC_BUFFERS}, crate::{arch, ipc::buffer::IpcBuffer, kmain::IPC_BUFFERS},
alloc::string::String, alloc::string::String,
log::{debug, error, info, trace, warn}, log::{debug, error, info, trace, warn},
}; };
@ -78,7 +70,7 @@ pub fn handler(vm: &mut Vm) {
}, },
1 => match log_msg_handler(vm, mem_addr, length) { 1 => match log_msg_handler(vm, mem_addr, length) {
Ok(()) => {} Ok(()) => {}
Err(err) => log::error!("Improper log format"), Err(_) => log::error!("Improper log format"),
}, },
2 => { 2 => {
use crate::holeybytes::kernel_services::mem_serve::memory_msg_handler; use crate::holeybytes::kernel_services::mem_serve::memory_msg_handler;
@ -107,7 +99,7 @@ pub fn handler(vm: &mut Vm) {
x86_64::instructions::port::Port::new(address).write(value); x86_64::instructions::port::Port::new(address).write(value);
} }
let mut msg_vec = block_read(mem_addr, length); let msg_vec = block_read(mem_addr, length);
let msg_type = msg_vec[0]; let msg_type = msg_vec[0];
match msg_type { match msg_type {
0 => 'wow: { 0 => 'wow: {
@ -203,7 +195,7 @@ pub fn handler(vm: &mut Vm) {
let max_length = vm.registers[5].cast::<u64>(); let max_length = vm.registers[5].cast::<u64>();
let mut buffs = IPC_BUFFERS.lock(); let mut buffs = IPC_BUFFERS.lock();
let mut buff: &mut IpcBuffer; let buff: &mut IpcBuffer;
if buffs.get_mut(&buffer_id).is_some() { if buffs.get_mut(&buffer_id).is_some() {
buff = buffs.get_mut(&buffer_id).unwrap(); buff = buffs.get_mut(&buffer_id).unwrap();
@ -252,7 +244,7 @@ pub fn handler(vm: &mut Vm) {
} }
} }
fn log_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> { fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
// let message_length = 8 + 8 + 8; // let message_length = 8 + 8 + 8;
// log::info!("Mem Addr 0x{:x?} length {}", mem_addr, length); // log::info!("Mem Addr 0x{:x?} length {}", mem_addr, length);
let mut msg_vec = block_read(mem_addr, length); let mut msg_vec = block_read(mem_addr, length);
@ -261,7 +253,7 @@ fn log_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogE
match String::from_utf8(msg_vec) { match String::from_utf8(msg_vec) {
Ok(strr) => { Ok(strr) => {
// use LogLevel::*; // use LogLevel::*;
let ll = match log_level { let _ll = match log_level {
0 | 48 => error!("{}", strr), 0 | 48 => error!("{}", strr),
1 | 49 => warn!("{}", strr), 1 | 49 => warn!("{}", strr),
2 | 50 => info!("{}", strr), 2 | 50 => info!("{}", strr),
@ -285,8 +277,8 @@ pub enum LogError {
NoMessages, NoMessages,
InvalidLogFormat, InvalidLogFormat,
} }
use {alloc::vec, log::Record};
// use {alloc::vec, log::Record};
// fn memory_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> { // fn memory_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
// let mut val = alloc::vec::Vec::new(); // let mut val = alloc::vec::Vec::new();
// for _ in 0..4096 { // for _ in 0..4096 {

View file

@ -1,19 +1,10 @@
use { use {
crate::holeybytes::{ crate::holeybytes::{kernel_services::block_read, Vm},
ecah::LogError, alloc::alloc::{alloc_zeroed, dealloc},
kernel_services::{block_read, mem_serve},
Vm,
},
alloc::{
alloc::{alloc_zeroed, dealloc},
vec::Vec,
},
core::alloc::Layout, core::alloc::Layout,
log::{debug, info}, log::{debug, info},
}; };
use alloc::vec;
pub enum MemoryServiceError { pub enum MemoryServiceError {
InvalidMemoryFormat, InvalidMemoryFormat,
} }
@ -25,7 +16,7 @@ pub enum MemoryQuotaType {
KillQuota = 3, KillQuota = 3,
} }
fn alloc_page(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), MemoryServiceError> { fn alloc_page(vm: &mut Vm, _mem_addr: u64, _length: usize) -> Result<(), MemoryServiceError> {
let ptr = unsafe { alloc_zeroed(Layout::new::<[u8; 4096]>()) }; let ptr = unsafe { alloc_zeroed(Layout::new::<[u8; 4096]>()) };
info!("Block address: {:?}", ptr); info!("Block address: {:?}", ptr);
vm.registers[1] = hbvm::value::Value(ptr as u64); vm.registers[1] = hbvm::value::Value(ptr as u64);
@ -38,7 +29,7 @@ pub fn memory_msg_handler(
mem_addr: u64, mem_addr: u64,
length: usize, length: usize,
) -> Result<(), MemoryServiceError> { ) -> Result<(), MemoryServiceError> {
let mut msg_vec = block_read(mem_addr, length); let msg_vec = block_read(mem_addr, length);
let msg_type = msg_vec[0]; let msg_type = msg_vec[0];
match msg_type { match msg_type {
0 => { 0 => {
@ -84,7 +75,7 @@ pub fn memory_msg_handler(
let hid_raw: [u8; 8] = msg_vec[2..10].try_into().unwrap(); let hid_raw: [u8; 8] = msg_vec[2..10].try_into().unwrap();
let hid: u64 = u64::from_le_bytes(hid_raw); let hid: u64 = u64::from_le_bytes(hid_raw);
let pid_raw: [u8; 8] = msg_vec[10..18].try_into().unwrap(); let pid_raw: [u8; 8] = msg_vec[10..18].try_into().unwrap();
let pid: u64 = u64::from_le_bytes(hid_raw); let pid: u64 = u64::from_le_bytes(pid_raw);
debug!( debug!(
"Setting HID-{:x}:PID-{:x}'s quota type to {:?}", "Setting HID-{:x}:PID-{:x}'s quota type to {:?}",
hid, pid, quota_type hid, pid, quota_type

View file

@ -1,4 +1,4 @@
use alloc::{vec, vec::Vec}; use alloc::vec::Vec;
pub mod mem_serve; pub mod mem_serve;
pub mod service_definition_service; pub mod service_definition_service;

View file

@ -1,12 +1,8 @@
use { use {
crate::{ crate::{
alloc::string::ToString,
arch::hardware_random_u64, arch::hardware_random_u64,
holeybytes::{ecah::LogError, kernel_services::block_read, Vm}, holeybytes::{ecah::LogError, kernel_services::block_read, Vm},
ipc::{ ipc::{buffer::IpcBuffer, protocol::Protocol},
buffer::IpcBuffer,
protocol::{self, Protocol},
},
kmain::IPC_BUFFERS, kmain::IPC_BUFFERS,
}, },
alloc::string::String, alloc::string::String,
@ -100,7 +96,7 @@ fn sds_create_service(protocol: String) -> u64 {
} }
fn sds_search_service(protocol: String) -> u64 { fn sds_search_service(protocol: String) -> u64 {
let mut services = SERVICES.lock(); let services = SERVICES.lock();
let compare = Protocol::from(protocol.clone()); let compare = Protocol::from(protocol.clone());
for (bid, protocol_canidate) in &services.0 { for (bid, protocol_canidate) in &services.0 {
trace!("BID-{bid} protocol_canidate {:?}", protocol_canidate); trace!("BID-{bid} protocol_canidate {:?}", protocol_canidate);

View file

@ -7,7 +7,7 @@
use hbvm::mem::Address; use hbvm::mem::Address;
fn calc_start_of_page(ptr: u64) -> u64 { fn calc_start_of_page(ptr: u64) -> u64 {
let mut page_aligned = false; let _page_aligned = false;
if ptr % 4096 == 0 { if ptr % 4096 == 0 {
// page_aligned = true; // page_aligned = true;
return ptr / 4096; return ptr / 4096;
@ -21,11 +21,11 @@ pub struct Memory {
impl Memory { impl Memory {
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn read_device(addr: Address) { fn read_device(_addr: Address) {
unsafe { //unsafe {
// //
// x86_64::instructions::port::Port::new(addr.get()).read() // x86_64::instructions::port::Port::new(addr.get()).read()
} //}
} }
} }
@ -37,7 +37,6 @@ impl hbvm::mem::Memory for Memory {
target: *mut u8, target: *mut u8,
count: usize, count: usize,
) -> Result<(), hbvm::mem::LoadError> { ) -> Result<(), hbvm::mem::LoadError> {
use log::{error, info};
if addr.get() % 4096 == 0 {} if addr.get() % 4096 == 0 {}
core::ptr::copy(addr.get() as *const u8, target, count); core::ptr::copy(addr.get() as *const u8, target, count);
Ok(()) Ok(())

View file

@ -3,30 +3,33 @@ mod kernel_services;
mod mem; mod mem;
use { use {
crate::{arch, ipc::buffer::IpcBuffer, kmain::IPC_BUFFERS}, core::{
alloc::boxed::Box, alloc::Layout,
core::{default, future::Future, marker::PhantomData, ptr::NonNull, task::Poll}, future::Future,
marker::PhantomData,
pin::Pin,
ptr::NonNull,
task::{Context, Poll},
},
hbvm::{ hbvm::{
mem::{ mem::{softpaging::HandlePageFault, Address},
softpaging::{icache::ICache, HandlePageFault, SoftPagedMem},
Address, Memory,
},
VmRunError, VmRunOk, VmRunError, VmRunOk,
}, },
log::{debug, error, info, trace, warn}, log::error,
}; };
const STACK_SIZE: usize = 1024 * 1024; const STACK_SIZE: usize = 1024 * 1024;
const TIMER_QUOTIENT: usize = 100; const TIMER_QUOTIENT: usize = 1000;
type Vm = hbvm::Vm<mem::Memory, TIMER_QUOTIENT>; type Vm = hbvm::Vm<mem::Memory, TIMER_QUOTIENT>;
pub struct ExecThread<'p> { pub struct ExecThread<'p> {
vm: Vm, vm: Vm,
stack_bottom: *mut u8, stack_bottom: NonNull<u8>,
_phantom: PhantomData<&'p [u8]>, _phantom: PhantomData<&'p [u8]>,
} }
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) { pub fn set_arguments(&mut self, ptr: u64, length: u64) {
self.vm.registers[1] = hbvm::value::Value(ptr); self.vm.registers[1] = hbvm::value::Value(ptr);
@ -34,55 +37,60 @@ impl<'p> ExecThread<'p> {
} }
pub unsafe fn new(program: &'p [u8], entrypoint: Address) -> Self { pub unsafe fn new(program: &'p [u8], entrypoint: Address) -> Self {
let mut vm = unsafe { let mut vm = Vm::new(
Vm::new( mem::Memory {},
mem::Memory {}, Address::new(program.as_ptr() as u64 + entrypoint.get()),
Address::new(program.as_ptr() as u64 + entrypoint.get()), );
)
};
let stack_bottom = unsafe { allocate_stack().as_ptr() }; let stack_bottom = allocate_stack();
vm.write_reg(254, (stack_bottom as usize + STACK_SIZE - 1) as u64);
vm.write_reg(
254,
(stack_bottom.as_ptr() as usize + STACK_SIZE - 1) as u64,
);
ExecThread { ExecThread {
vm, vm,
stack_bottom, stack_bottom,
_phantom: Default::default(), _phantom: PhantomData,
} }
} }
} }
impl<'p> Drop for ExecThread<'p> { impl<'p> Drop for ExecThread<'p> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { alloc::alloc::dealloc(self.stack_bottom, stack_layout()) }; unsafe { alloc::alloc::dealloc(self.stack_bottom.as_ptr(), stack_layout()) };
} }
} }
impl<'p> Future for ExecThread<'p> { impl<'p> Future for ExecThread<'p> {
type Output = Result<(), VmRunError>; type Output = Result<(), VmRunError>;
fn poll( fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
mut self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
) -> Poll<Self::Output> {
match self.vm.run() { match self.vm.run() {
Err(err) => { Err(err) => {
log::error!("HBVM Error\r\nRegister dump: {:?}", self.vm.registers,); error!("HBVM Error\r\nRegister dump: {:?}", self.vm.registers);
return Poll::Ready(Err(err)); Poll::Ready(Err(err))
}
Ok(VmRunOk::End) => Poll::Ready(Ok(())),
Ok(VmRunOk::Ecall) => {
ecah::handler(&mut self.vm);
cx.waker().wake_by_ref();
Poll::Pending
}
Ok(VmRunOk::Timer) => {
cx.waker().wake_by_ref();
Poll::Pending
} }
Ok(VmRunOk::End) => return Poll::Ready(Ok(())),
Ok(VmRunOk::Ecall) => ecah::handler(&mut self.vm),
Ok(VmRunOk::Timer) => (),
Ok(VmRunOk::Breakpoint) => { Ok(VmRunOk::Breakpoint) => {
log::error!( error!(
"HBVM Debug breakpoint\r\nRegister dump: {:?}", "HBVM Debug breakpoint\r\nRegister dump: {:?}",
self.vm.registers, self.vm.registers
); );
cx.waker().wake_by_ref();
Poll::Pending
} }
} }
cx.waker().wake_by_ref();
Poll::Pending
} }
} }
@ -91,33 +99,23 @@ impl HandlePageFault for PageFaultHandler {
fn page_fault( fn page_fault(
&mut self, &mut self,
reason: hbvm::mem::MemoryAccessReason, reason: hbvm::mem::MemoryAccessReason,
pagetable: &mut hbvm::mem::softpaging::paging::PageTable, _pagetable: &mut hbvm::mem::softpaging::paging::PageTable,
vaddr: hbvm::mem::Address, vaddr: hbvm::mem::Address,
size: hbvm::mem::softpaging::PageSize, size: hbvm::mem::softpaging::PageSize,
dataptr: *mut u8, dataptr: *mut u8,
) -> bool ) -> bool {
where error!("REASON: {reason} vaddr: {vaddr} size: {size:?} Dataptr {dataptr:p}");
Self: Sized,
{
log::error!(
"REASON: {reason} \
vaddr: {vaddr} \
size: {size:?} \
Dataptr {dataptr:p}",
);
false false
} }
} }
const fn stack_layout() -> core::alloc::Layout { const fn stack_layout() -> Layout {
unsafe { alloc::alloc::Layout::from_size_align_unchecked(STACK_SIZE, 4096) } unsafe { Layout::from_size_align_unchecked(STACK_SIZE, 4096) }
} }
fn allocate_stack() -> NonNull<u8> { fn allocate_stack() -> NonNull<u8> {
let layout = stack_layout(); let layout = stack_layout();
match NonNull::new(unsafe { alloc::alloc::alloc_zeroed(layout) }) { NonNull::new(unsafe { alloc::alloc::alloc_zeroed(layout) })
Some(ptr) => ptr, .unwrap_or_else(|| alloc::alloc::handle_alloc_error(layout))
None => alloc::alloc::handle_alloc_error(layout),
}
} }

View file

@ -24,7 +24,7 @@ impl IpcBuffer {
length length
); );
match (bounded, length) { match (bounded, length) {
(false, a) => { (false, ..) => {
let buftype = BufferTypes::Unbound(SegQueue::new()); let buftype = BufferTypes::Unbound(SegQueue::new());
Self { Self {

View file

@ -1,7 +1,6 @@
use { use {
alloc::{string::String, vec::Vec}, alloc::{string::String, vec::Vec},
hashbrown::HashMap, hashbrown::HashMap,
log::info,
}; };
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct Type {} pub struct Type {}

View file

@ -2,27 +2,25 @@
use { use {
crate::{ crate::{
arch::{hardware_random_u64, logging::SERIAL_CONSOLE}, arch::hardware_random_u64,
bootmodules::{build_cmd, BootModules}, bootmodules::BootModules,
capabilities, //bootmodules::build_cmd,
device_tree::DeviceTree, device_tree::DeviceTree,
holeybytes::ExecThread, holeybytes::ExecThread,
ipc::buffer::{self, IpcBuffer}, ipc::buffer::IpcBuffer,
}, },
alloc::format,
hashbrown::HashMap, hashbrown::HashMap,
hbvm::mem::Address, hbvm::mem::Address,
limine::{Framebuffer, FramebufferRequest, NonNullPtr}, limine::{Framebuffer, FramebufferRequest, NonNullPtr},
log::{debug, info, trace}, log::{debug, info},
spin::{Lazy, Mutex}, spin::{Lazy, Mutex},
xml::XMLElement,
}; };
pub fn kmain(cmdline: &str, boot_modules: BootModules) -> ! { pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
debug!("Entered kmain"); debug!("Entered kmain");
let kcmd = build_cmd("Kernel Command Line", cmdline); // let kcmd = build_cmd("Kernel Command Line", cmdline);
trace!("Cmdline: {kcmd:?}"); // trace!("Cmdline: {kcmd:?}");
// for (i, bm) in boot_modules.iter().enumerate() { // for (i, bm) in boot_modules.iter().enumerate() {
// let name = format!("module-{}", i); // let name = format!("module-{}", i);
@ -108,7 +106,6 @@ pub static DEVICE_TREE: Lazy<Mutex<DeviceTree>> = Lazy::new(|| {
}); });
pub static FB_REQ: FramebufferRequest = FramebufferRequest::new(0); pub static FB_REQ: FramebufferRequest = FramebufferRequest::new(0);
use alloc::vec::Vec;
pub type IpcBuffers = HashMap<u64, IpcBuffer>; pub type IpcBuffers = HashMap<u64, IpcBuffer>;
pub static IPC_BUFFERS: Lazy<Mutex<IpcBuffers>> = Lazy::new(|| { pub static IPC_BUFFERS: Lazy<Mutex<IpcBuffers>> = Lazy::new(|| {
let mut bufs = HashMap::new(); let mut bufs = HashMap::new();

View file

@ -5,7 +5,6 @@
#![feature( #![feature(
abi_x86_interrupt, abi_x86_interrupt,
alloc_error_handler, alloc_error_handler,
panic_info_message,
ptr_sub_ptr, ptr_sub_ptr,
custom_test_frameworks, custom_test_frameworks,
naked_functions, naked_functions,
@ -40,6 +39,7 @@ pub const VERSION: Version = Version {
}; };
#[panic_handler] #[panic_handler]
#[cfg(target_os = "none")]
fn panic(info: &core::panic::PanicInfo) -> ! { fn panic(info: &core::panic::PanicInfo) -> ! {
arch::register_dump(); arch::register_dump();
@ -52,10 +52,8 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
)); ));
} }
if let Some(msg) = info.message() { let msg = info.message();
let _ = crate::arch::log(format_args!("{msg}\r\n")); let _ = crate::arch::log(format_args!("{msg}\r\n"));
}
loop {} loop {}
} }

View file

@ -1,3 +1,4 @@
#![allow(deprecated)]
// TODO: Add a logger api with logger levels and various outputs // TODO: Add a logger api with logger levels and various outputs
pub static TERMINAL_LOGGER: Lazy<Mutex<TermLogger>> = Lazy::new(|| Mutex::new(TermLogger::new())); pub static TERMINAL_LOGGER: Lazy<Mutex<TermLogger>> = Lazy::new(|| Mutex::new(TermLogger::new()));

View file

@ -1,7 +1,6 @@
//! The Memory Manager //! The Memory Manager
use alloc::collections::VecDeque; use {alloc::collections::VecDeque, derive_more::*};
use derive_more::*;
pub use crate::arch::PAGE_SIZE; pub use crate::arch::PAGE_SIZE;
pub const MAX_ORDER: usize = 10; pub const MAX_ORDER: usize = 10;
@ -44,7 +43,7 @@ pub const MAX_ORDER: usize = 10;
Sum, Sum,
UpperHex, UpperHex,
)] )]
#[display(fmt = "0x{:x}", _0)] #[display("0x{:x}", _0)]
#[from(forward)] #[from(forward)]
pub struct VirtualAddress(usize); pub struct VirtualAddress(usize);
@ -55,11 +54,11 @@ impl VirtualAddress {
pub fn vpns(&self) -> [usize; 3] { pub fn vpns(&self) -> [usize; 3] {
[ [
// [20:12] // [20:12]
(self.0 >> 12) & 0x1ff, (self.0 >> 12) & 0x1FF,
// [29:21] // [29:21]
(self.0 >> 21) & 0x1ff, (self.0 >> 21) & 0x1FF,
// [38:30] // [38:30]
(self.0 >> 30) & 0x1ff, (self.0 >> 30) & 0x1FF,
] ]
} }
@ -114,7 +113,7 @@ impl VirtualAddress {
Sum, Sum,
UpperHex, UpperHex,
)] )]
#[display(fmt = "0x{:x}", _0)] #[display("0x{:x}", _0)]
#[from(forward)] #[from(forward)]
pub struct PhysicalAddress(usize); pub struct PhysicalAddress(usize);
@ -125,11 +124,11 @@ impl PhysicalAddress {
pub fn ppns(&self) -> [usize; 3] { pub fn ppns(&self) -> [usize; 3] {
[ [
// [20:12] // [20:12]
(self.0 >> 12) & 0x1ff, (self.0 >> 12) & 0x1FF,
// [29:21] // [29:21]
(self.0 >> 21) & 0x1ff, (self.0 >> 21) & 0x1FF,
// [55:30] // [55:30]
(self.0 >> 30) & 0x3ffffff, (self.0 >> 30) & 0x3FFFFFF,
] ]
} }

View file

@ -1,26 +1,18 @@
#![allow(unused)] #![allow(unused)]
use { use {
alloc::{boxed::Box, collections::BTreeMap, sync::Arc, task::Wake}, alloc::{boxed::Box, sync::Arc, task::Wake},
core::{ core::{
future::Future, future::Future,
pin::Pin, pin::Pin,
task::{Context, Poll, Waker}, task::{Context, Poll, Waker},
}, },
crossbeam_queue::SegQueue, crossbeam_queue::SegQueue,
kiam::when, hashbrown::HashMap,
slab::Slab, slab::Slab,
spin::RwLock, spin::Mutex,
}; };
static SPAWN_QUEUE: RwLock<Option<SpawnQueue>> = RwLock::new(None);
pub fn spawn(future: impl Future<Output = ()> + Send + 'static) {
match &*SPAWN_QUEUE.read() {
Some(s) => s.push(Task::new(future)),
None => panic!("no task executor is running"),
}
}
pub fn yield_now() -> impl Future<Output = ()> { pub fn yield_now() -> impl Future<Output = ()> {
struct YieldNow(bool); struct YieldNow(bool);
impl Future for YieldNow { impl Future for YieldNow {
@ -42,61 +34,51 @@ pub fn yield_now() -> impl Future<Output = ()> {
#[derive(Default)] #[derive(Default)]
pub struct Executor { pub struct Executor {
tasks: Slab<Task>, tasks: Slab<Task>,
queue: TaskQueue, queue: Arc<SegQueue<TaskId>>,
to_spawn: SpawnQueue, wakers: HashMap<TaskId, Waker>, // Keeping HashMap as it is more performant for lookups.
wakers: BTreeMap<TaskId, Waker>,
} }
impl Executor { impl Executor {
pub fn new() -> Self {
Self {
tasks: Slab::new(),
queue: Arc::new(SegQueue::new()),
wakers: HashMap::new(),
}
}
pub fn spawn(&mut self, future: impl Future<Output = ()> + Send + 'static) { pub fn spawn(&mut self, future: impl Future<Output = ()> + Send + 'static) {
self.queue let task_id = TaskId(self.tasks.insert(Task::new(future)));
.push(TaskId(self.tasks.insert(Task::new(future)))); self.queue.push(task_id);
} }
pub fn run(&mut self) { pub fn run(&mut self) {
{
let mut global_spawner = SPAWN_QUEUE.write();
if global_spawner.is_some() {
panic!("Task executor is already running");
}
*global_spawner = Some(Arc::clone(&self.to_spawn));
}
loop { loop {
when! { while let Some(id) = self.queue.pop() {
let Some(id) = self if let Some(task) = self.tasks.get_mut(id.0) {
.to_spawn let waker = self.wakers.entry(id).or_insert_with(|| {
.pop()
.map(|t| TaskId(self.tasks.insert(t)))
.or_else(|| self.queue.pop())
=> {
let Some(task) = self.tasks.get_mut(id.0) else {
panic!("Attempted to get task from empty slot: {}", id.0);
};
let mut cx = Context::from_waker(self.wakers.entry(id).or_insert_with(|| {
Waker::from(Arc::new(TaskWaker { Waker::from(Arc::new(TaskWaker {
id, id,
queue: Arc::clone(&self.queue), queue: Arc::clone(&self.queue),
})) }))
})); });
match task.poll(&mut cx) { let mut cx = Context::from_waker(waker);
Poll::Ready(()) => {
self.tasks.remove(id.0); if let Poll::Ready(()) = task.poll(&mut cx) {
self.wakers.remove(&id); self.tasks.remove(id.0);
} self.wakers.remove(&id);
Poll::Pending => (),
} }
}, } else {
self.tasks.is_empty() => break, panic!("Attempted to get task from empty slot: {}", id.0);
_ => (), }
}
if self.tasks.is_empty() {
break;
} }
} }
*SPAWN_QUEUE.write() = None;
} }
} }
@ -117,21 +99,18 @@ impl Task {
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] #[derive(Hash, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
struct TaskId(usize); struct TaskId(usize);
type TaskQueue = Arc<SegQueue<TaskId>>;
type SpawnQueue = Arc<SegQueue<Task>>;
struct TaskWaker { struct TaskWaker {
id: TaskId, id: TaskId,
queue: TaskQueue, queue: Arc<SegQueue<TaskId>>,
} }
impl Wake for TaskWaker { impl Wake for TaskWaker {
fn wake(self: Arc<Self>) { fn wake(self: Arc<Self>) {
log::trace!("Woke Task-{:?}", self.id); log::trace!("Woke Task-{:?}", self.id);
self.wake_by_ref(); self.queue.push(self.id);
} }
fn wake_by_ref(self: &Arc<Self>) { fn wake_by_ref(self: &Arc<Self>) {

View file

@ -4,15 +4,15 @@ version = "0.2.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
str-reader = "0.1.2" str-reader = "0.1"
derive_more = "0.99" derive_more = { version = "1", features = ["full"] }
error-stack = "0.4" error-stack = "0.5"
fatfs = "0.3" fatfs = "0.3"
toml = "0.5.2" toml = "0.8"
# hbasm.git = "https://git.ablecorp.us/AbleOS/holey-bytes.git" # hbasm.git = "https://git.ablecorp.us/AbleOS/holey-bytes.git"
hblang.git = "https://git.ablecorp.us/AbleOS/holey-bytes.git" hblang.git = "https://git.ablecorp.us/AbleOS/holey-bytes.git"
[dependencies.reqwest] [dependencies.reqwest]
version = "0.11" version = "0.12"
default-features = false default-features = false
features = ["rustls-tls", "blocking"] features = ["rustls-tls", "blocking"]

View file

@ -1,4 +1,5 @@
#![allow(unused)] #![allow(unused)]
mod dev; mod dev;
use { use {
@ -7,7 +8,7 @@ use {
error_stack::{bail, report, Context, Report, Result, ResultExt}, error_stack::{bail, report, Context, Report, Result, ResultExt},
fatfs::{FileSystem, FormatVolumeOptions, FsOptions, ReadWriteSeek}, fatfs::{FileSystem, FormatVolumeOptions, FsOptions, ReadWriteSeek},
std::{ std::{
fmt::Display, // fmt::Display,
fs::{self, File}, fs::{self, File},
io::{self, Write}, io::{self, Write},
path::Path, path::Path,
@ -428,11 +429,11 @@ fn fetch_ovmf(target: Target) -> Result<String, OvmfFetchError> {
#[derive(Debug, Display)] #[derive(Debug, Display)]
enum OvmfFetchError { enum OvmfFetchError {
#[display(fmt = "Failed to fetch OVMF package")] #[display("Failed to fetch OVMF package")]
Fetch, Fetch,
#[display(fmt = "No OVMF package available")] #[display("No OVMF package available")]
Empty, Empty,
#[display(fmt = "IO Error")] #[display("IO Error")]
Io, Io,
} }
@ -447,19 +448,19 @@ enum Target {
#[derive(Debug, Display)] #[derive(Debug, Display)]
enum Error { enum Error {
#[display(fmt = "Failed to build the kernel")] #[display("Failed to build the kernel")]
Build, Build,
#[display(fmt = "Missing or invalid subcommand (available: build, run)")] #[display("Missing or invalid subcommand (available: build, run)")]
InvalidSubCom, InvalidSubCom,
#[display(fmt = "IO Error")] #[display("IO Error")]
Io, Io,
#[display(fmt = "Failed to spawn a process")] #[display("Failed to spawn a process")]
ProcessSpawn, ProcessSpawn,
#[display(fmt = "Failed to fetch UEFI firmware")] #[display("Failed to fetch UEFI firmware")]
OvmfFetch, OvmfFetch,
#[display(fmt = "Failed to assemble Holey Bytes code")] #[display("Failed to assemble Holey Bytes code")]
Assembler, Assembler,
#[display(fmt = "QEMU Error: {}", "fmt_qemu_err(*_0)")] #[display("QEMU Error: {}", "fmt_qemu_err(*_0)")]
Qemu(Option<i32>), Qemu(Option<i32>),
} }

View file

@ -1,3 +1,3 @@
[toolchain] [toolchain]
channel = "nightly-2024-05-17" channel = "nightly-2024-07-17"
components = ["rust-src", "llvm-tools"] components = ["rust-src", "llvm-tools"]