1
0
Fork 0
forked from koniifer/ableos

Merge branch 'master' of ssh://git.ablecorp.us:20/able/ableos

This commit is contained in:
Able 2022-05-12 22:39:13 -05:00
commit 6f306b9ece
10 changed files with 231 additions and 287 deletions

1
Cargo.lock generated
View file

@ -429,6 +429,7 @@ dependencies = [
name = "kernel" name = "kernel"
version = "0.1.2" version = "0.1.2"
dependencies = [ dependencies = [
"linked_list_allocator",
"log", "log",
"versioning", "versioning",
] ]

View file

@ -1,6 +1,6 @@
use crate::allocator::{HEAP_SIZE, HEAP_START};
use alloc::alloc::{GlobalAlloc, Layout}; use alloc::alloc::{GlobalAlloc, Layout};
use core::ptr::null_mut; use core::ptr::null_mut;
use kernel::allocator::{HEAP_SIZE, HEAP_START};
use x86_64::{ use x86_64::{
structures::paging::{ structures::paging::{
mapper::MapToError, FrameAllocator, Mapper, Page, PageTableFlags, Size4KiB, mapper::MapToError, FrameAllocator, Mapper, Page, PageTableFlags, Size4KiB,
@ -39,7 +39,7 @@ pub fn init_heap(
} }
unsafe { unsafe {
crate::allocator::ALLOCATOR kernel::allocator::ALLOCATOR
.lock() .lock()
.init(HEAP_START, HEAP_SIZE); .init(HEAP_START, HEAP_SIZE);
} }

View file

@ -1,6 +1,7 @@
use super::systeminfo::SystemMemory; use super::systeminfo::SystemMemory;
use crate::{arch::drivers::sysinfo::master, ALLOCATOR}; use crate::arch::drivers::sysinfo::master;
use core::fmt::Display; use core::fmt::Display;
use kernel::allocator::ALLOCATOR;
use versioning::Version; use versioning::Version;
use x86_64::instructions::interrupts::{disable, enable}; use x86_64::instructions::interrupts::{disable, enable};

View file

@ -40,7 +40,6 @@ pub mod print;
#[macro_use] #[macro_use]
pub mod serial_print; pub mod serial_print;
pub mod allocator;
pub mod boot_conf; pub mod boot_conf;
pub mod devices; pub mod devices;
pub mod driver_traits; pub mod driver_traits;
@ -68,7 +67,6 @@ mod unicode_utils;
#[prelude_import] #[prelude_import]
pub use prelude::rust_2021::*; pub use prelude::rust_2021::*;
pub use allocator::*;
pub use driver_traits::*; pub use driver_traits::*;
pub use experiments::*; pub use experiments::*;
pub use graphics::*; pub use graphics::*;

View file

@ -2,13 +2,13 @@ use crate::arch::drivers::sysinfo::master;
use crate::filesystem::FILE_SYSTEM; use crate::filesystem::FILE_SYSTEM;
use crate::time::fetch_time; use crate::time::fetch_time;
use crate::wasm_jumploader::interp; use crate::wasm_jumploader::interp;
use crate::ALLOCATOR;
use crate::{ use crate::{
arch::{shutdown, sloop}, arch::{shutdown, sloop},
systeminfo::{KERNEL_VERSION, RELEASE_TYPE}, systeminfo::{KERNEL_VERSION, RELEASE_TYPE},
KERNEL_STATE, KERNEL_STATE,
}; };
use genfs::{Fs, OpenOptions}; use genfs::{Fs, OpenOptions};
use kernel::allocator::ALLOCATOR;
use rhai::Engine; use rhai::Engine;
use spin::Lazy; use spin::Lazy;
use x86_64::instructions::interrupts::{disable, enable}; use x86_64::instructions::interrupts::{disable, enable};

View file

@ -1,15 +1,51 @@
use core::alloc::Layout;
use crate::arch::generate_process_pass; use crate::arch::generate_process_pass;
use crate::arch::interrupts::{reset_pit_for_cpu, set_pit_2}; use crate::arch::interrupts::{reset_pit_for_cpu, set_pit_2};
use crate::devices::{self, pci, pci_inner}; use crate::devices::pci;
use crate::encoding::bin; use crate::filesystem::FILE_SYSTEM;
use crate::port_io::{read32, read8, write8};
use crate::rhai_shell::shell; use crate::rhai_shell::shell;
use crate::rhai_shell::KEYBUFF;
use crate::wasm_jumploader::run_program; use crate::wasm_jumploader::run_program;
use acpi::{AcpiTables, PlatformInfo}; use acpi::{AcpiTables, PlatformInfo};
use cpuio::inb;
use cpuio::outb; use cpuio::outb;
use genfs::Fs; use genfs::Fs;
use genfs::OpenOptions;
// TODO: move to a better place
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct AcpiStruct {}
impl acpi::AcpiHandler for AcpiStruct {
unsafe fn map_physical_region<T>(
&self,
physical_address: usize,
size: usize,
) -> acpi::PhysicalMapping<Self, T> {
info!("PHYS ADDR: {:?}", physical_address);
info!("Size: {:?}", size);
todo!("map_physical_region");
}
fn unmap_physical_region<T>(_region: &acpi::PhysicalMapping<Self, T>) {
todo!("unmap_physical_region");
}
}
pub struct Path {
pub path: Vec<String>,
}
impl Path {
pub fn new(path: String) -> Self {
let mut path_vec_string = vec![];
for part in path.split(&['\\', '/'][..]) {
path_vec_string.push(part.to_string());
}
Path {
path: path_vec_string,
}
}
}
/// Experimental scratchpad for testing. /// Experimental scratchpad for testing.
pub fn scratchpad() { pub fn scratchpad() {
@ -22,7 +58,7 @@ pub fn scratchpad() {
}"; }";
let axel = axel::parse(axel_raw.to_string()); let axel = axel::parse(axel_raw.to_string());
let xyz = devices::pci::brute_force_scan(); let xyz = pci::brute_force_scan();
for dev in xyz { for dev in xyz {
trace!("{:?}", dev); trace!("{:?}", dev);
dev.bars.iter().for_each(|bar| { dev.bars.iter().for_each(|bar| {
@ -59,7 +95,6 @@ pub fn scratchpad() {
real_shell(); real_shell();
} }
use crate::port_io::write16;
pub fn acpi() { pub fn acpi() {
let acpi_handler = AcpiStruct {}; let acpi_handler = AcpiStruct {};
@ -71,33 +106,13 @@ pub fn acpi() {
PlatformInfo { PlatformInfo {
power_profile, power_profile,
interrupt_model, interrupt_model,
processor_info, ..
pm_timer,
} => { } => {
info!("{:?}", power_profile); info!("{:?}", power_profile);
info!("{:?}", interrupt_model); info!("{:?}", interrupt_model);
// info!("{:?}", processor_info.unwrap()); // info!("{:?}", processor_info.unwrap());
// info!("{:?}", pm_timer.unwrap()); // info!("{:?}", pm_timer.unwrap());
} }
_ => todo!(),
}
}
// TODO: move to a better place
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct AcpiStruct {}
impl acpi::AcpiHandler for AcpiStruct {
unsafe fn map_physical_region<T>(
&self,
physical_address: usize,
size: usize,
) -> acpi::PhysicalMapping<Self, T> {
info!("PHYS ADDR: {:?}", physical_address);
info!("Size: {:?}", size);
todo!("map_physical_region");
}
fn unmap_physical_region<T>(_region: &acpi::PhysicalMapping<Self, T>) {
todo!("unmap_physical_region");
} }
} }
@ -139,7 +154,6 @@ pub fn real_shell() {
} }
} }
} }
use crate::rhai_shell::KEYBUFF;
pub fn command_parser(user: String, command: String) { pub fn command_parser(user: String, command: String) {
let fs = &*FILE_SYSTEM.lock(); let fs = &*FILE_SYSTEM.lock();
@ -210,9 +224,6 @@ pub fn command_parser(user: String, command: String) {
} }
} }
use crate::filesystem::FILE_SYSTEM;
use genfs::OpenOptions;
pub fn sound(n_frequency: u32) { pub fn sound(n_frequency: u32) {
let div: u32; let div: u32;
let tmp: u8; let tmp: u8;
@ -238,45 +249,3 @@ pub fn sound_off() {
}; };
reset_pit_for_cpu(); reset_pit_for_cpu();
} }
use cpuio::inb;
pub struct Path {
pub path: Vec<String>,
}
impl Path {
pub fn new(path: String) -> Self {
let mut path_vec_string = vec![];
for part in path.split(&['\\', '/'][..]) {
path_vec_string.push(part.to_string());
}
Path {
path: path_vec_string,
}
}
pub fn get_path(&self) -> String {
let mut path = String::new();
for part in &self.path {
path.push_str(part);
path.push('/');
}
path
}
}
#[derive(Debug, Copy, Clone)]
pub enum GpuFormats {
BGRA8Unorm = 1,
BGRX8Unorm = 2,
ARGB8Unorm = 3,
XRGB8Unorm = 4,
RGBA8Unorm = 67,
XBGR8Unorm = 68,
ABGR8Unorm = 121,
RGBX8Unorm = 134,
}

View file

@ -4,147 +4,134 @@ use wasmi::{
Signature, Trap, ValueType, Signature, Trap, ValueType,
}; };
const ADD_FUNC_INDEX: usize = 0; macro_rules! wasmi_type {
const GET_TIME_INDEX: usize = 2; (bool) => {
const GET_RANDOM_INDEX: usize = 3; ValueType::I32
const GET_INPUT_INDEX: usize = 4; };
const PRINT_CHAR: usize = 6; (u8) => {
const SEND_SIGNAL_INDEX: usize = 1; ValueType::I32
};
pub struct HostExternals; (u16) => {
impl HostExternals { ValueType::I32
fn check_signature(&self, index: usize, signature: &Signature) -> bool { };
match index { (u32) => {
ADD_FUNC_INDEX => { ValueType::I32
let (params, ret_ty): (&[ValueType], Option<ValueType>) = };
(&[ValueType::I32, ValueType::I32], Some(ValueType::I32)); (u64) => {
if params.len() != signature.params().len() { ValueType::I64
return false; };
} (i8) => {
if ret_ty != signature.return_type() { ValueType::I32
return false; };
} (i16) => {
for (ty, param) in params.iter().zip(signature.params()) { ValueType::I32
if *ty != *param { };
return false; (i32) => {
} ValueType::I32
} };
true (i64) => {
} ValueType::I64
};
SEND_SIGNAL_INDEX => { (f32) => {
let (params, ret_ty): (&[ValueType], Option<ValueType>) = ValueType::F32
(&[ValueType::I32, ValueType::I32], Some(ValueType::I32)); };
if params.len() != signature.params().len() { (f64) => {
return false; ValueType::F64
} };
if ret_ty != signature.return_type() {
return false;
}
for (ty, param) in params.iter().zip(signature.params()) {
if *ty != *param {
return false;
}
}
true
}
GET_TIME_INDEX => {
let (params, ret_ty): (&[ValueType], Option<ValueType>) =
(&[], Some(ValueType::I32));
if params.len() != signature.params().len() {
return false;
}
if ret_ty != signature.return_type() {
return false;
}
for (ty, param) in params.iter().zip(signature.params()) {
if *ty != *param {
return false;
}
}
true
}
GET_RANDOM_INDEX => {
let (params, ret_ty): (&[ValueType], Option<ValueType>) =
(&[], Some(ValueType::I32));
if params.len() != signature.params().len() {
return false;
}
if ret_ty != signature.return_type() {
return false;
}
for (ty, param) in params.iter().zip(signature.params()) {
if *ty != *param {
return false;
}
}
true
}
GET_INPUT_INDEX => {
let (params, ret_ty): (&[ValueType], Option<ValueType>) =
(&[], Some(ValueType::I32));
if params.len() != signature.params().len() {
return false;
}
if ret_ty != signature.return_type() {
return false;
}
for (ty, param) in params.iter().zip(signature.params()) {
if *ty != *param {
return false;
}
}
true
}
PRINT_CHAR => {
let (params, ret_ty): (&[ValueType], Option<ValueType>) = (&[ValueType::I32], None);
if params.len() != signature.params().len() {
return false;
}
if ret_ty != signature.return_type() {
return false;
}
for (ty, param) in params.iter().zip(signature.params()) {
if *ty != *param {
return false;
}
}
true
}
_ => false,
}
}
} }
impl Externals for HostExternals { macro_rules! wasmi_return_type {
() => {
None
};
($type: ident) => {
Some(wasmi_type!($type))
};
}
macro_rules! host_externals {
(
$($index: literal: $name: ident ($($arg_name: ident: $arg_type: ident),* $(,)?) $(-> $return_type: ident)? $block: block)*
) => {
pub struct HostExternals;
impl Externals for HostExternals {
fn invoke_index( fn invoke_index(
&mut self, &mut self,
index: usize, index: usize,
args: RuntimeArgs, args: RuntimeArgs
) -> Result<Option<RuntimeValue>, Trap> { ) -> Result<Option<RuntimeValue>, Trap> {
match index { match index {
ADD_FUNC_INDEX => { $(
let a: u32 = args.nth_checked(0)?; $index => match args.as_ref() {
let b: u32 = args.nth_checked(1)?; [$($arg_name),*] => {
$(
let $arg_name: $arg_type = (*$arg_name)
.try_into()
.ok_or(wasmi::TrapKind::UnexpectedSignature)?;
)*
$block
},
_ => return Err(wasmi::TrapKind::UnexpectedSignature.into()),
}
),*
_ => {
error!("Unimplemented function at {index}");
Err(Trap::new(wasmi::TrapKind::Unreachable))
}
}
}
}
impl ModuleImportResolver for HostExternals {
fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result<FuncRef, Error> {
let (index, param_types, return_type): (usize, &[ValueType], Option<ValueType>) =
match field_name {
$(
stringify!($name) => (
$index,
&[$(wasmi_type!($arg_type)),*],
wasmi_return_type!($($return_type)?),
),
)*
_ => {
return Err(Error::Instantiation(format!(
"Export {field_name} not found",
)));
},
};
if !(param_types.len() != signature.params().len() || return_type != signature.return_type())
&& param_types
.iter()
.zip(signature.params())
.find(|(ty, param)| ty != param)
.is_none()
{
trace!("Resolved export {field_name} at func {index}");
Ok(FuncInstance::alloc_host(signature.clone(), index))
} else {
Err(Error::Instantiation(format!(
"Export {field_name} has a bad signature {signature:?}",
)))
}
}
}
};
}
host_externals! {
0: add(a: u32, b: u32) -> u32 {
let result = a + b; let result = a + b;
trace!("SYSCALL: {} + {} = {}", a, b, result); trace!("SYSCALL: {} + {} = {}", a, b, result);
Ok(Some(RuntimeValue::I32(result as i32))) Ok(Some(result.into()))
} }
SEND_SIGNAL_INDEX => { 1: send_signal(pid: u32, signal: u32) -> i32 {
let pid: u32 = args.nth_checked(0)?;
let signal: u32 = args.nth_checked(1)?;
trace!("SYSCALL: send signal {} to pid {}", signal, pid); trace!("SYSCALL: send signal {} to pid {}", signal, pid);
let ret = RuntimeValue::I32(0); Ok(Some(0.into()))
Ok(Some(ret))
} }
GET_TIME_INDEX => { 2: get_time() -> u32 {
use core::sync::atomic::Ordering::*; use core::sync::atomic::Ordering::*;
trace!("SYSCALL: get time"); trace!("SYSCALL: get time");
@ -152,71 +139,30 @@ impl Externals for HostExternals {
let tick_time = kernel::TICK.load(Relaxed); let tick_time = kernel::TICK.load(Relaxed);
x86_64::instructions::interrupts::enable(); x86_64::instructions::interrupts::enable();
let ret = RuntimeValue::I32(tick_time.try_into().unwrap()); let ret: u32 = tick_time.try_into().unwrap();
Ok(Some(ret)) Ok(Some(ret.into()))
} }
GET_RANDOM_INDEX => { 3: get_random() -> i32 {
trace!("SYSCALL: get random"); trace!("SYSCALL: get random");
let rand = generate_process_pass(); let rand = generate_process_pass() as i32;
Ok(Some(rand.into()))
let ret = RuntimeValue::I32(rand as i32);
// let ret = RuntimeValue::I32(rand.try_into().unwrap());
Ok(Some(ret))
} }
GET_INPUT_INDEX => { 4: get_input() -> i32 {
let input = None; let input = None;
x86_64::instructions::interrupts::without_interrupts(|| KEYBUFF.lock().pop()); x86_64::instructions::interrupts::without_interrupts(|| KEYBUFF.lock().pop());
if let Some(chr) = input { if let Some(chr) = input {
trace!("SYSCALL: input: {}", chr); trace!("SYSCALL: input: {}", chr);
} }
let ret = RuntimeValue::I32(input.unwrap_or(0x00 as char) as i32); let ret = input.unwrap_or(0x00 as char) as i32;
Ok(Some(ret.into()))
Ok(Some(ret))
} }
PRINT_CHAR => { 5: print_char(chr: u8) {
let chr: u8 = args.nth_checked(0)?;
trace!("SYSCALL: print: {}", chr); trace!("SYSCALL: print: {}", chr);
print!("{}", char::from(chr)); print!("{}", char::from(chr));
Ok(None) Ok(None)
} }
_ => {
error!("Unimplemented function at {}", index);
Err(Trap::new(wasmi::TrapKind::Unreachable))
}
}
}
}
impl ModuleImportResolver for HostExternals {
fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result<FuncRef, Error> {
let index = match field_name {
"add" => ADD_FUNC_INDEX,
"send_signal" => SEND_SIGNAL_INDEX,
"get_time" => GET_TIME_INDEX,
"get_random" => GET_RANDOM_INDEX,
"get_input" => GET_INPUT_INDEX,
"print_char" => PRINT_CHAR,
_ => {
return Err(Error::Instantiation(format!(
"Export {} not found",
field_name
)))
}
};
if !self.check_signature(index, signature) {
return Err(Error::Instantiation(format!(
"Export {} has a bad signature {:?}",
field_name, signature
)));
}
trace!("Resolved export {} as func {}", field_name, index);
Ok(FuncInstance::alloc_host(signature.clone(), index))
}
} }

View file

@ -4,6 +4,7 @@ name = "kernel"
version = "0.1.2" version = "0.1.2"
[dependencies] [dependencies]
linked_list_allocator = "0.9"
log = "0.4.14" log = "0.4.14"
[dependencies.versioning] [dependencies.versioning]

24
kernel/src/allocator.rs Normal file
View file

@ -0,0 +1,24 @@
//! Memory allocator
use linked_list_allocator::LockedHeap;
///
pub const HEAP_START: usize = 0x_4444_4444_0000;
///
pub const HEAP_MULTIPLIER: usize = 100000;
///
pub const HEAP_BASE: usize = 100;
///
pub const HEAP_SIZE: usize = HEAP_BASE * HEAP_MULTIPLIER;
/// Global allocator
#[global_allocator]
pub static ALLOCATOR: LockedHeap = LockedHeap::empty();
#[alloc_error_handler]
fn alloc_error_handler(layout: alloc::alloc::Layout) -> ! {
panic!("allocation error: {:?}", layout)
}

View file

@ -1,10 +1,14 @@
//! The ableOS kernel. //! The ableOS kernel.
#![deny(missing_docs)] #![feature(alloc_error_handler)]
#![no_std]
#![feature(prelude_import)]
#![feature(arbitrary_enum_discriminant)] #![feature(arbitrary_enum_discriminant)]
#![feature(prelude_import)]
#![no_std]
#![deny(missing_docs)]
extern crate alloc;
pub mod allocator;
pub mod device_interface; pub mod device_interface;
pub mod messaging; pub mod messaging;
pub mod panic; pub mod panic;