diff --git a/README.md b/README.md index a72f158..33fe929 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,56 @@ # runix -*"rust written microkernel soon hopefully"* +***"rust written microkernel hopefully"*** -ok so far i think you need to switch to nightly rust and then run cargo install bootimage and rustup component add llvm-tools-preview and then you can run `cargo bootimage` and then you can run the cargo run command and it should work. \ No newline at end of file +---- + +## Features +- [x] Booting +- [x] VGA Text Mode +- [x] Serial Output +- bout it so far + + +## Roadmap +- [ ] ISO Generation or IMG Generation +- [ ] Memory Management +- [ ] Multitasking +- [ ] Filesystem +- [ ] Userland +- [ ] Networking + + +## Building + +```bash +rustup default nightly +cargo install bootimage +rustup component add llvm-tools-preview +cargo run +``` + +## License + +``` +MIT License + +Copyright (c) 2023 Amarnath P. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +``` \ No newline at end of file diff --git a/src/basic_boot.rs b/src/basic_boot.rs new file mode 100644 index 0000000..6057c14 --- /dev/null +++ b/src/basic_boot.rs @@ -0,0 +1,22 @@ +#![no_std] +#![no_main] +#![feature(custom_test_frameworks)] +#![test_runner(crate::test_runner)] +#![reexport_test_harness_main = "test_main"] + +use core::panic::PanicInfo; + +#[no_mangle] // i wonder why compilers mangle names lol +pub extern "C" fn _start() -> ! { + test_main(); + loop {} +} + +fn test_runner(tests: &[&dyn Fn()]) { + unimlpemented!(); +} + +#[panic_handler] +fn panic(info: &PanicInfo) -> ! { + loop {} +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..3c226b8 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,74 @@ +#![no_std] +#![cfg_attr(test, no_main)] +#![feature(custom_test_frameworks)] +#![test_runner(crate::test_runner)] +#![reexport_test_harness_main = "test_main"] + +use core::panic::PanicInfo; +pub mod serial; +pub mod vga_buffer; + +pub trait Testable { + fn run(&self) -> (); +} + +impl Testable for T +where + T: Fn(), +{ + fn run(&self) { + serial_print!("{}...\t", core::any::type_name::()); + self(); + serial_println!("[ok]"); + } +} + +pub fn test_runner(tests: &[&dyn Testable]) { + serial_println!("Running {} tests", tests.len()); + for test in tests { + test.run(); + } + exit_qemu(QemuExitCode::Success); +} + +pub fn test_panic_handler(info: &PanicInfo) -> ! { + serial_println!("[failed]\n"); + serial_println!("Error: {}\n", info); + exit_qemu(QemuExitCode::Failed); + loop {} +} + +/// entry point for cargo test-tickles + +#[cfg(test)] +#[no_mangle] + +pub extern "C" fn _start() -> ! { + test_main(); + loop {} +} + +#[cfg(test)] +#[panic_handler] + +fn panic(info: &PanicInfo) -> ! { + test_panic_handler(info) +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u32)] + +pub enum QemuExitCode { + Success = 0x10, + Failed = 0x11, +} + +pub fn exit_qemu(exit_code: QemuExitCode) { + use x86_64::instructions::port::Port; + + unsafe { + let mut port = Port::new(0xf4); + port.write(exit_code as u32); + } +} + diff --git a/src/main.rs b/src/main.rs index 920e6ab..26de023 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,9 +5,12 @@ #![test_runner(crate::test_runner)] #![reexport_test_harness_main = "test_main"] -mod vga_buffer; -mod serial; +//mod vga_buffer; moved to lib.rs +//mod serial; moved to lib.rs use core::panic::PanicInfo; +use runix::println; +use runix::test_runner; + /// This function is called on panic. #[cfg(not(test))] // new attribute dropped ayyy @@ -17,14 +20,12 @@ fn panic(info: &PanicInfo) -> ! { loop {} } + // panic handler in test mode #[cfg(test)] #[panic_handler] fn panic(info: &PanicInfo) -> ! { - serial_println!("[failed]\n"); - serial_println!("Error: {}\n", info); - exit_qemu(QemuExitCode::Failed); - loop {} + runix::test_panic_handler(info) } @@ -68,20 +69,21 @@ pub extern "C" fn _start() -> ! { // THERE IS A BUG IN CARGO WHERE THERE ARE "duplicate lang item" ERRORS // ON CARGO TEST IN SOME CASES. TO FIX REMOVE/COMMENT OUT THE ' panic = "abort" ' // FOR A PROFILE IN THE CARGO.TOML FILE -#[cfg(test)] +/* #[cfg(test)] old test runner moved to lib.rs pub fn test_runner(tests: &[&dyn Testable]) { // new serial_println!("Running {} tests", tests.len()); for test in tests { test.run(); // new } exit_qemu(QemuExitCode::Success); -} +} */ #[test_case] fn trivial_assertion() { assert_eq!(1, 1); } +/* old qemu stuff moved to lib.rs #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(u32)] pub enum QemuExitCode { @@ -111,4 +113,5 @@ where self(); serial_println!("[ok]"); } -} \ No newline at end of file +} +*/ \ No newline at end of file