character device impl, pci devices found

This commit is contained in:
Able 2022-02-09 07:08:40 -06:00
parent a78570b85f
commit 75cfb18c77
19 changed files with 396 additions and 105 deletions

69
ableos/Cargo.lock generated
View file

@ -39,6 +39,7 @@ dependencies = [
"linked_list_allocator", "linked_list_allocator",
"lliw", "lliw",
"log", "log",
"pc-beeper",
"pic8259", "pic8259",
"picorand", "picorand",
"pretty-hex", "pretty-hex",
@ -49,6 +50,7 @@ dependencies = [
"shadeable", "shadeable",
"smoltcp", "smoltcp",
"spin 0.5.2", "spin 0.5.2",
"tinypci",
"uart_16550", "uart_16550",
"unicode-width", "unicode-width",
"vga", "vga",
@ -83,9 +85,9 @@ dependencies = [
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.0.1" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]] [[package]]
name = "bit_field" name = "bit_field"
@ -183,7 +185,7 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
[[package]] [[package]]
name = "ext2" name = "ext2"
version = "0.1.1" version = "0.1.1"
source = "git+https://git.ablecorp.us/able/ext2-rs.git#220f66a156bfd5033eecac20372368860749c304" source = "git+https://git.ablecorp.us/able/ext2-rs.git#15bcf9f72e2523e7ebe2a8d09c1231ca9139f326"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"genfs", "genfs",
@ -264,15 +266,15 @@ dependencies = [
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.112" version = "0.2.117"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c"
[[package]] [[package]]
name = "libm" name = "libm"
version = "0.2.1" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db"
[[package]] [[package]]
name = "linked_list_allocator" name = "linked_list_allocator"
@ -291,9 +293,9 @@ checksum = "2d502c8bcc35a4f7ca9a7ffb7ac27b15ba30b1b92c2d69a1e4437e2635d73af7"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.5" version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b"
dependencies = [ dependencies = [
"scopeguard", "scopeguard",
] ]
@ -377,6 +379,14 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92"
[[package]]
name = "pc-beeper"
version = "0.1.0"
source = "git+https://github.com/AbleOS/pc-beeper#9b61a9d60552a9da4285f5ceb39ab2cccbb60b4b"
dependencies = [
"x86_64",
]
[[package]] [[package]]
name = "pic8259" name = "pic8259"
version = "0.10.2" version = "0.10.2"
@ -435,9 +445,9 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.14" version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -459,9 +469,9 @@ dependencies = [
[[package]] [[package]]
name = "rhai" name = "rhai"
version = "1.4.0" version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c7433068977c56619bf2b7831da26eb986d0645fe56f2ad9357eda7ae4c435e" checksum = "898b114d6cfa18af4593393fdc6c7437118e7e624d97f635fba8c75fd5c06f56"
dependencies = [ dependencies = [
"ahash", "ahash",
"core-error", "core-error",
@ -487,9 +497,9 @@ dependencies = [
[[package]] [[package]]
name = "rkyv" name = "rkyv"
version = "0.7.29" version = "0.7.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49a37de5dfc60bae2d94961dacd03c7b80e426b66a99fa1b17799570dbdd8f96" checksum = "439655b8d657bcb28264da8e5380d55549e34ffc4149bea9e3521890a122a7bd"
dependencies = [ dependencies = [
"hashbrown", "hashbrown",
"ptr_meta", "ptr_meta",
@ -499,9 +509,9 @@ dependencies = [
[[package]] [[package]]
name = "rkyv_derive" name = "rkyv_derive"
version = "0.7.29" version = "0.7.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719d447dd0e84b23cee6cb5b32d97e21efb112a3e3c636c8da36647b938475a1" checksum = "cded413ad606a80291ca84bedba137093807cf4f5b36be8c60f57a7e790d48f6"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -543,18 +553,18 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.133" version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.133" version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -563,9 +573,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.75" version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79" checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@ -641,9 +651,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.85" version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -659,6 +669,11 @@ dependencies = [
"crunchy", "crunchy",
] ]
[[package]]
name = "tinypci"
version = "0.1.0"
source = "git+https://github.com/trashbyte/tinypci.git#5e1bc4cf7ae4edb8d524a5e7e71a1ace9c4850fc"
[[package]] [[package]]
name = "ttf-parser" name = "ttf-parser"
version = "0.14.0" version = "0.14.0"
@ -751,9 +766,9 @@ dependencies = [
[[package]] [[package]]
name = "x86_64" name = "x86_64"
version = "0.14.7" version = "0.14.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb611915c917c6296d11e23f71ff1ecfe49c5766daba92cd3df52df6b58285b6" checksum = "958ab3202b01bc43ba2eb832102c4a487ed93151667a2289062e5f2b00058be2"
dependencies = [ dependencies = [
"bit_field", "bit_field",
"bitflags", "bitflags",

View file

@ -10,18 +10,15 @@ panic = "abort"
[package.metadata.bootimage] [package.metadata.bootimage]
run-args = [ run-args = [
"-cpu", "-cpu",
# "kvm64-v1", "Broadwell-v3",
# Support for rdrand
# "Broadwell",
"EPYC-v1",
"-serial", "-serial",
"stdio", "stdio",
"-smp", "-smp",
"cores=2", "cores=2",
"-vga",
"qxl",
# An example gpu used with ableOS # An example gpu used with ableOS
# "-device", # "-device",
# "virtio-gpu", # "virtio-gpu",
@ -52,12 +49,19 @@ lliw = "0.2.0"
spin = "0.5.2" spin = "0.5.2"
vga = "*" vga = "*"
log = "*" log = "*"
# tinypci = "0.1.0"
tinypci = { git = "https://github.com/trashbyte/tinypci.git", default-features = false }
pretty-hex = "0.2.1" pretty-hex = "0.2.1"
unicode-width = "0.1.7" unicode-width = "0.1.7"
picorand = "*" picorand = "*"
# watson = "0.4" # watson = "0.4"
genfs = "0.1.0" genfs = "0.1.0"
# pc-beeper = "0.1.0"
pc-beeper = {git = "https://github.com/AbleOS/pc-beeper"}
acpi = "4.1.0" acpi = "4.1.0"
@ -80,7 +84,7 @@ default-features = false
features = ["alloc"] features = ["alloc"]
[dependencies.hashbrown] [dependencies.hashbrown]
version = "*" version = "0.11.2"
default-features = false default-features = false
features = ["inline-more"] features = ["inline-more"]

View file

@ -0,0 +1,23 @@
use alloc::string::String;
use crate::character_device::CharacterDevice;
pub struct DevNull;
impl CharacterDevice for DevNull {
fn can_read(&self) -> bool {
true
}
fn can_write(&self) -> bool {
true
}
fn read_char(&mut self) -> Option<char> {
Some(0x00 as char)
}
fn write_char(&mut self, _: char) -> bool {
true
}
}

View file

@ -0,0 +1,38 @@
use crate::character_device::CharacterDevice;
pub struct DevUnicode {
pub next_write_char: char,
pub next_read_char: char,
}
impl CharacterDevice for DevUnicode {
fn can_read(&self) -> bool {
true
}
fn can_write(&self) -> bool {
true
}
fn read_char(&mut self) -> Option<char> {
let c = self.next_read_char;
self.next_read_char = add1_char(c);
Some(c)
}
fn write_char(&mut self, c: char) -> bool {
if self.next_write_char != c {
return false;
}
true
}
}
fn add1_char(c: char) -> char {
if c == char::MAX {
return 0x00 as char;
}
char::from_u32(c as u32 + 1).unwrap()
}

View file

@ -0,0 +1,21 @@
use crate::character_device::CharacterDevice;
pub struct DevZero;
impl CharacterDevice for DevZero {
fn can_read(&self) -> bool {
true
}
fn can_write(&self) -> bool {
true
}
fn read_char(&mut self) -> Option<char> {
Some(0 as char)
}
fn write_char(&mut self, _: char) -> bool {
true
}
}

36
ableos/src/devices/mod.rs Normal file
View file

@ -0,0 +1,36 @@
use alloc::{
boxed::Box,
string::{String, ToString},
};
use hashbrown::HashMap;
use crate::character_device::CharacterDevice;
pub mod dev_null;
pub mod dev_unicode;
pub mod dev_zero;
// FIXME: This is a hack to hold a device.
pub enum Device {
CharacterDevice(Box<dyn CharacterDevice>),
// BlockDevice,
}
unsafe impl Sync for Device {}
unsafe impl Send for Device {}
pub struct DeviceTable {
pub devices: HashMap<String, Device>,
}
use self::dev_null::DevNull;
pub use self::Device::*;
impl DeviceTable {
pub fn new() -> Self {
let mut table: HashMap<String, Device> = HashMap::new();
table.insert("null".to_string(), CharacterDevice(Box::new(DevNull)));
DeviceTable { devices: table }
}
}
lazy_static::lazy_static!(
static ref DEVICE_TABLE: DeviceTable = DeviceTable::new();
);

View file

@ -0,0 +1,10 @@
pub trait CharacterDevice {
/// Returns true if the device can be read from.
fn can_read(&self) -> bool;
/// Returns true if the device can be written to
fn can_write(&self) -> bool;
/// Reads a single character from the device
fn read_char(&mut self) -> Option<char>;
/// Writes a single character to the device and returns true if the write was successful
fn write_char(&mut self, c: char) -> bool;
}

View file

@ -1,4 +0,0 @@
pub trait Device {
fn probe();
fn reset();
}

View file

@ -1,2 +1,4 @@
pub mod graphics; pub mod graphics;
pub mod serial; pub mod serial;
pub mod character_device;

View file

@ -0,0 +1,48 @@
use {
alloc::{format, string::String, vec::Vec},
ext2::{
fs::{
sync::{Inode, Synced},
Ext2,
},
sector::{SectorSize, Size1024},
volume::Volume,
},
};
fn load_fs() -> Synced<Ext2<Size1024, Vec<u8>>> {
let mut volume = Vec::new();
volume.extend_from_slice(include_bytes!("../../../userland/root_rs/ext2.img"));
let fs = Synced::<Ext2<Size1024, _>>::new(volume).unwrap();
fs
}
// use serde::__private::from_utf8_lossy;
pub fn walk<'vol, S: SectorSize, V: Volume<u8, S>>(
fs: &'vol Synced<Ext2<S, V>>,
inode: Inode<S, V>,
name: String,
) {
inode.directory().map(|dir| {
for entry in dir {
assert!(entry.is_ok());
let entry = entry.unwrap();
let entry_name = String::from_utf8_lossy(&entry.name);
println!("{}/{} => {}", name, entry_name, entry.inode,);
if entry_name != "." && entry_name != ".." {
walk(
fs,
fs.inode_nth(entry.inode).unwrap(),
format!("{}/{}", name, entry_name),
);
}
}
});
}
lazy_static::lazy_static!(
pub static ref FILE_SYSTEM:spin::Mutex<Synced<Ext2<Size1024, Vec<u8>>>>= spin::Mutex::new(load_fs());
);

View file

@ -32,6 +32,7 @@ pub mod arch;
#[macro_use] #[macro_use]
pub mod print; pub mod print;
pub mod wasm_jumploader;
#[macro_use] #[macro_use]
pub extern crate log; pub extern crate log;
@ -93,3 +94,4 @@ pub use syscalls::*;
pub mod scratchpad; pub mod scratchpad;
pub use scratchpad::*; pub use scratchpad::*;
pub mod filesystem;

View file

@ -1,67 +1,27 @@
use alloc::{ use alloc::{string::String, vec::Vec};
format, use genfs::{Fs, OpenOptions};
string::{String, ToString},
vec::Vec, use crate::{filesystem::FILE_SYSTEM, wasm_jumploader::interp};
};
use ext2::{
fs::{
sync::{Inode, Synced},
Ext2,
},
sector::{SectorSize, Size1024},
volume::Volume,
};
/// Experimental scratchpad for testing. /// Experimental scratchpad for testing.
pub fn scratchpad() { pub fn scratchpad() {
let mut fs = load_fs(); let fs = &*FILE_SYSTEM.lock();
let file = fs
.open(b"/home/able/kernel.md", OpenOptions::new().read(true))
.unwrap();
let root = fs.root_inode(); let mut file_bytes = Vec::new();
walk(&fs, fs.root_inode(), String::new()); file.read_to_end(&mut file_bytes).unwrap();
let string = String::from_utf8_lossy(&file_bytes);
print!("{}", string);
let pci_list = tinypci::brute_force_scan();
for pci in pci_list {
info!("{}", pci);
} }
fn load_fs() -> Synced<Ext2<Size1024, Vec<u8>>> { interp();
let file = include_bytes!("../../userland/root_rs/ext2.img");
let mut volume = Vec::new();
volume.extend_from_slice(file);
let fs = Synced::<Ext2<Size1024, _>>::new(volume);
assert!(
fs.is_ok(),
"Err({:?})",
fs.err().unwrap_or_else(|| unreachable!()),
);
let fs = fs.unwrap();
fs
}
use genfs::{DirOptions, Fs, OpenOptions};
use serde::__private::from_utf8_lossy;
use crate::{arch::drivers::serial, serial_println};
fn walk<'vol, S: SectorSize, V: Volume<u8, S>>(
fs: &'vol Synced<Ext2<S, V>>,
inode: Inode<S, V>,
name: String,
) {
inode.directory().map(|dir| {
for entry in dir {
assert!(entry.is_ok());
let entry = entry.unwrap();
let entry_name = from_utf8_lossy(&entry.name);
println!("{}/{} => {}", name, entry_name, entry.inode,);
if entry_name != "." && entry_name != ".." {
walk(
fs,
fs.inode_nth(entry.inode).unwrap(),
format!("{}/{}", name, entry_name),
);
}
}
});
} }

View file

@ -22,4 +22,6 @@ pub enum Signals {
/// * `pid` - The PID of the process to send the signal to /// * `pid` - The PID of the process to send the signal to
/// * `signal` - The signal to send /// * `signal` - The signal to send
#[no_mangle] #[no_mangle]
pub extern "C" fn send_signal(pid: PID, signal: Signals) {} pub extern "C" fn send_signal(pid: PID, signal: Signals) {
unimplemented!("send_signal");
}

16
ableos/src/usb/mod.rs Normal file
View file

@ -0,0 +1,16 @@
//!
//!
//!
//!
//!
pub enum UsbSpeed {
/// Super-speed functions operate at up to 5 Gb/s.
Super,
/// High-speed functions operate at up to 480 Mb/s.
High,
/// Full-speed functions operate at up to 12 Mb/s.
Full,
/// Low-speed functions operate at up to 1.5 Mb/s.
Low,
}

View file

@ -0,0 +1,66 @@
use alloc::format;
use wasmi::{
Error, Externals, FuncInstance, FuncRef, ModuleImportResolver, RuntimeArgs, RuntimeValue,
Signature, Trap, ValueType,
};
pub struct HostExternals {
// counter: usize,
}
const ADD_FUNC_INDEX: usize = 0;
impl Externals for HostExternals {
fn invoke_index(
&mut self,
index: usize,
args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Trap> {
match index {
ADD_FUNC_INDEX => {
let a: u32 = args.nth_checked(0)?;
let b: u32 = args.nth_checked(1)?;
let result = a + b;
Ok(Some(RuntimeValue::I32(result as i32)))
}
_ => panic!("Unimplemented function at {}", index),
}
}
}
impl HostExternals {
fn check_signature(&self, index: usize, signature: &Signature) -> bool {
let (params, ret_ty): (&[ValueType], Option<ValueType>) = match index {
ADD_FUNC_INDEX => (&[ValueType::I32, ValueType::I32], Some(ValueType::I32)),
_ => return false,
};
signature.params() == params && signature.return_type() == ret_ty
}
}
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,
_ => {
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
)));
}
Ok(FuncInstance::alloc_host(
Signature::new(&[ValueType::I32, ValueType::I32][..], Some(ValueType::I32)),
index,
))
}
}

View file

@ -0,0 +1,39 @@
pub mod host_functions;
extern crate wasmi;
// extern crate wabt;
use alloc::vec::Vec;
use genfs::{Fs, OpenOptions};
use wasmi::{ImportsBuilder, ModuleInstance, NopExternals};
use crate::{filesystem::FILE_SYSTEM, wasm_jumploader::host_functions::HostExternals};
pub fn interp() {
let fs = &*FILE_SYSTEM.lock();
let file = fs
.open(b"/home/able/test.wasm", OpenOptions::new().read(true))
.unwrap();
let mut wasm_binary = Vec::new();
let ret = file.read_to_end(&mut wasm_binary).unwrap();
// Load wasm binary and prepare it for instantiation.
let module = wasmi::Module::from_buffer(&wasm_binary).expect("failed to load wasm");
let imports = ImportsBuilder::new().with_resolver("env", &host_functions::HostExternals {});
// Instantiate a module with empty imports and
// assert that there is no `start` function.
let instance = ModuleInstance::new(&module, &imports)
.expect("failed to instantiate wasm module")
.assert_no_start();
let ret = instance
.invoke_export("start", &[], &mut HostExternals {})
.expect("failed to execute export");
info!("collected wasm return value: {:?}", ret);
}

View file

@ -1,2 +1,6 @@
[build] [build]
target = "wasm32-unknown-unknown" target = "wasm32-unknown-unknown"
# [unstable]
# build-std = ["core", "compiler_builtins", "alloc"]
# build-std-features = ["compiler-builtins-mem"]

View file

@ -1,13 +1,22 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![deny(improper_ctypes)]
pub struct Command {} #[macro_use]
mod libwasm;
#[no_mangle]
fn start() -> i32 {
let ret = unsafe { add(1, 2) };
info!(b"hello");
ret as i32
}
fn _start(_command: Command) {}
/*
use core::panic::PanicInfo; use core::panic::PanicInfo;
#[panic_handler] #[panic_handler]
fn panic(_info: &PanicInfo) -> ! { fn panic(_info: &PanicInfo) -> ! {
loop {} loop {}
} }
*/

Binary file not shown.