refactored for architectures and added riscv support

This commit is contained in:
Bryan McShea
2024-01-24 00:41:51 -05:00
parent e5a6b6073f
commit 461269ed32
30 changed files with 683 additions and 425 deletions

View File

@@ -1,5 +0,0 @@
# [build]
# rustflags = ["-g"]
[unstable]
bindeps = true

2
.gitignore vendored
View File

@@ -1 +1,3 @@
/target
kernel/target
runner/target

View File

@@ -1,19 +0,0 @@
[package]
name = "os"
version = "0.1.0"
edition = "2021"
default-run = "qemu"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[workspace]
members = ["kernel"]
[dependencies]
clap = { version = "4.4.16", features = ["derive"] }
ovmf-prebuilt = "0.1.0-alpha.1"
[build-dependencies]
kernel = { path = "kernel", artifact = "bin", target = "x86_64-unknown-none" }
bootloader = "0.11.5"

5
Cargo.toml-old Normal file
View File

@@ -0,0 +1,5 @@
[workspace]
resolver = "2"
members = ["kernel", "runner"]
default-members = ["runner"]

View File

@@ -1,20 +0,0 @@
use bootloader::DiskImageBuilder;
use std::{env, path::PathBuf};
fn main() {
let kernel_path = env::var("CARGO_BIN_FILE_KERNEL").unwrap();
println!("{kernel_path}");
let disk_builder = DiskImageBuilder::new(PathBuf::from(kernel_path.clone()));
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let name = env::var("CARGO_PKG_NAME").unwrap();
let uefi_path = out_dir.join(name.clone() + "-uefi.img");
let bios_path = out_dir.join(name + "-bios.img");
disk_builder.create_uefi_image(&uefi_path).unwrap();
disk_builder.create_bios_image(&bios_path).unwrap();
println!("cargo:rustc-env=UEFI_IMAGE={}", uefi_path.display());
println!("cargo:rustc-env=BIOS_IMAGE={}", bios_path.display());
println!("cargo:rustc-env=KERNEL_BIN={}", kernel_path);
}

10
kernel/.cargo/config.toml Normal file
View File

@@ -0,0 +1,10 @@
[build]
# rustflags = ["-g"]
target = ["riscv64gc-unknown-none-elf", "x86_64-unknown-none"]
[target.riscv64gc-unknown-none-elf]
rustflags = [
"-C", "link-arg=-Tsrc/arch/riscv64/link.ld",
"-C", "link-arg=--omagic",
]

216
kernel/Cargo.lock generated Normal file
View File

@@ -0,0 +1,216 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "az"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973"
[[package]]
name = "bit_field"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
[[package]]
name = "bootloader_api"
version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daaa1fb791aea49e19db7b7b3662665d511eb4e30a0627fa525fd92652f39358"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "embedded-graphics"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0649998afacf6d575d126d83e68b78c0ab0e00ca2ac7e9b3db11b4cbe8274ef0"
dependencies = [
"az",
"byteorder",
"embedded-graphics-core",
"float-cmp",
"micromath",
]
[[package]]
name = "embedded-graphics-core"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba9ecd261f991856250d2207f6d8376946cd9f412a2165d3b75bc87a0bc7a044"
dependencies = [
"az",
"byteorder",
]
[[package]]
name = "float-cmp"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
dependencies = [
"num-traits",
]
[[package]]
name = "kernel"
version = "0.1.0"
dependencies = [
"bootloader_api",
"embedded-graphics",
"lazy_static",
"pc-keyboard",
"pic8259",
"spin 0.9.8",
"uart_16550",
"x86_64",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
dependencies = [
"spin 0.5.2",
]
[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "micromath"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815"
[[package]]
name = "num-traits"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
dependencies = [
"autocfg",
]
[[package]]
name = "pc-keyboard"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6f2d937e3b8d63449b01401e2bae4041bc9dd1129c2e3e0d239407cf6635ac"
[[package]]
name = "pic8259"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb844b5b01db1e0b17938685738f113bfc903846f18932b378bc0eabfa40e194"
dependencies = [
"x86_64",
]
[[package]]
name = "raw-cpuid"
version = "10.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "rustversion"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]]
name = "uart_16550"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dc00444796f6c71f47c85397a35e9c4dbf9901902ac02386940d178e2b78687"
dependencies = [
"bitflags 1.3.2",
"rustversion",
"x86",
]
[[package]]
name = "volatile"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "442887c63f2c839b346c192d047a7c87e73d0689c9157b00b53dcc27dd5ea793"
[[package]]
name = "x86"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2781db97787217ad2a2845c396a5efe286f87467a5810836db6d74926e94a385"
dependencies = [
"bit_field",
"bitflags 1.3.2",
"raw-cpuid",
]
[[package]]
name = "x86_64"
version = "0.14.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b835097a84e4457323331ec5d6eb23d096066cbfb215d54096dcb4b2e85f500"
dependencies = [
"bit_field",
"bitflags 2.4.2",
"rustversion",
"volatile",
]

View File

@@ -9,15 +9,23 @@ test = false
bench = false
[dependencies]
bootloader_api = "0.11.5"
embedded-graphics = "0.8.1"
uart_16550 = "0.3.0"
x86_64 = "0.14.11"
spin = "0.9.8"
pic8259 = "0.10.1"
pc-keyboard = "0.5.0"
[target.'cfg(target_arch = "x86_64")'.dependencies]
pic8259 = "0.10.1"
bootloader_api = "0.11.5"
x86_64 = "0.14.11"
uart_16550 = "0.3.0"
[dependencies.lazy_static]
version = "1.4.0"
features = ["spin_no_std"]
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"

9
kernel/src/arch/mod.rs Normal file
View File

@@ -0,0 +1,9 @@
#[cfg(target_arch = "x86_64")]
mod x86_64;
#[cfg(target_arch = "x86_64")]
pub use x86_64::*;
#[cfg(target_arch = "riscv64")]
mod riscv64;
#[cfg(target_arch = "riscv64")]
pub use riscv64::*;

View File

@@ -0,0 +1,26 @@
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
SECTIONS
{
. = 0x80000000;
.text : {
*(.text.init)
*(.text)
}
PROVIDE(global_pointer = .);
.rodata : {
*(.rodata .rodata.*)
}
.data : {
*(.sdata .sdata.*) *(.data .data.*)
}
.bss : {
PROVIDE(_bss_start = .);
*(.sbss .sbss.*) *(.bss .bss.*)
PROVIDE(_bss_end = .);
}
. += 0x8000;
. = ALIGN(16);
PROVIDE(stack_top = .);
}

View File

@@ -0,0 +1,34 @@
use crate::main;
pub mod qemu;
#[no_mangle]
#[link_section = ".text.init"]
pub extern "C" fn _start() -> ! {
unsafe {
core::arch::asm!(
"csrr t0, mhartid",
"bnez t0, {_start}",
_start = sym _start
);
core::arch::asm!(
".option push",
".option norelax",
"la gp, global_pointer",
"la sp, stack_top",
"tail {entry}",
entry = sym entry,
options(noreturn)
);
}
}
extern "C" fn entry() -> ! {
main()
}
pub fn hlt_loop() -> ! {
loop {}
}

View File

@@ -0,0 +1,28 @@
const UART_BASE: u32 = 0x10010000;
const UART_REG_TXFIFO: *mut i32 = (UART_BASE + 0) as *mut i32;
pub fn exit() -> ! {
unsafe {
core::arch::asm!(
"li t0, 0x20026",
"sw t0, 0(sp)",
"move a1, sp",
"li a0, 0x18",
".balign 16",
".option push",
".option norvc",
"slli zero, zero, 0x1f",
"ebreak",
"srai zero, zero, 0x7",
options(noreturn)
);
}
}
pub fn _print(args: core::fmt::Arguments<'_>) {
let msg = args.as_str().expect("bruh");
for b in msg.as_bytes() {
while unsafe { *UART_REG_TXFIFO } < 0 {}
unsafe { *UART_REG_TXFIFO = *b as i32 }
}
}

View File

@@ -1,7 +1,8 @@
use crate::{gdt, print, println};
use super::gdt;
use crate::{print, println};
use lazy_static::lazy_static;
use pic8259::ChainedPics;
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode};
#[derive(Debug, Clone, Copy)]
#[repr(u8)]
@@ -36,6 +37,7 @@ lazy_static! {
idt.breakpoint.set_handler_fn(breakpoint);
idt[InterruptIndex::Timer.as_usize()].set_handler_fn(timer);
idt[InterruptIndex::Keyboard.as_usize()].set_handler_fn(keyboard);
idt.page_fault.set_handler_fn(page_fault);
idt
};
}
@@ -56,16 +58,28 @@ extern "x86-interrupt" fn double_fault(stack_frame: InterruptStackFrame, _error_
panic!("double fault exception: {:#?}", stack_frame);
}
extern "x86-interrupt" fn page_fault(
stack_frame: InterruptStackFrame,
error_code: PageFaultErrorCode,
) {
use x86_64::registers::control::Cr2;
println!("EXCEPTION: PAGE FAULT");
println!("Accessed Address: {:?}", Cr2::read());
println!("Error Code: {:?}", error_code);
println!("{:#?}", stack_frame);
super::hlt_loop();
}
extern "x86-interrupt" fn keyboard(_stack_frame: InterruptStackFrame) {
use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1};
use spin::Mutex;
use x86_64::instructions::port::Port;
lazy_static! {
static ref KEYBOARD: Mutex<Keyboard<layouts::Us104Key, ScancodeSet1>> =
Mutex::new(Keyboard::new(layouts::Us104Key, ScancodeSet1,
HandleControl::Ignore)
);
static ref KEYBOARD: Mutex<Keyboard<layouts::Us104Key, ScancodeSet1>> = Mutex::new(
Keyboard::new(layouts::Us104Key, ScancodeSet1, HandleControl::Ignore)
);
}
let mut keyboard = KEYBOARD.lock();

View File

@@ -0,0 +1,23 @@
use crate::main;
pub mod framebuffer;
pub mod gdt;
pub mod interrupts;
pub mod qemu;
bootloader_api::entry_point!(_start);
fn _start(boot_info: &'static mut bootloader_api::BootInfo) -> ! {
gdt::init();
interrupts::init();
if let Some(framebuffer) = boot_info.framebuffer.as_mut() {
framebuffer::draw_test(framebuffer);
}
main();
}
pub fn hlt_loop() -> ! {
loop {
x86_64::instructions::hlt();
}
}

View File

@@ -0,0 +1,25 @@
use core::fmt::Arguments;
use spin::Mutex;
use uart_16550::SerialPort;
use x86_64::instructions::{interrupts, port::Port};
use super::hlt_loop;
pub static UART: Mutex<SerialPort> = Mutex::new(unsafe { SerialPort::new(0x3F8) });
pub fn exit() -> ! {
unsafe {
let mut port = Port::new(0xf4);
port.write(0x10u32);
}
hlt_loop()
}
#[doc(hidden)]
pub fn _print(args: Arguments<'_>) {
use core::fmt::Write;
interrupts::without_interrupts(|| {
UART.lock().write_fmt(args).unwrap();
})
}

View File

@@ -1,25 +0,0 @@
#![no_std]
#![feature(abi_x86_interrupt)]
pub mod framebuffer;
pub mod gdt;
pub mod interrupts;
pub mod qemu;
pub mod log;
pub fn init() {
gdt::init();
interrupts::init();
}
pub fn exit() -> ! {
qemu::exit();
hlt_loop()
}
pub fn hlt_loop() -> ! {
loop {
x86_64::instructions::hlt();
}
}

26
kernel/src/lib2.rs Normal file
View File

@@ -0,0 +1,26 @@
#![no_std]
#![feature(abi_x86_interrupt)]
pub mod arch;
pub mod log;
pub mod qemu;
pub fn main() -> ! {
println!("we out here vibin");
for _ in 0..20000000 {}
qemu::exit();
}
pub fn exit() -> ! {
qemu::exit();
}
pub fn hlt_loop() -> ! {
arch::hlt_loop();
}
#[panic_handler]
pub fn panic(info: &core::panic::PanicInfo) -> ! {
println!("{}", info);
exit()
}

View File

@@ -1,20 +1,19 @@
#![no_std]
#![no_main]
#![feature(abi_x86_interrupt)]
use kernel::{framebuffer, init, exit, println, hlt_loop};
bootloader_api::entry_point!(kernel_main);
pub mod arch;
pub mod log;
pub mod qemu;
fn kernel_main(boot_info: &'static mut bootloader_api::BootInfo) -> ! {
init();
if let Some(framebuffer) = boot_info.framebuffer.as_mut() {
framebuffer::draw_test(framebuffer);
}
pub fn main() -> ! {
println!("we out here vibin");
for _ in 0..20000000 {}
hlt_loop();
qemu::exit();
}
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
pub fn panic(info: &core::panic::PanicInfo) -> ! {
println!("{}", info);
exit()
qemu::exit()
}

View File

@@ -1,29 +1,8 @@
use core::fmt::Arguments;
use spin::Mutex;
use uart_16550::SerialPort;
use x86_64::instructions::{interrupts, port::Port};
pub static UART: Mutex<SerialPort> = Mutex::new(unsafe { SerialPort::new(0x3F8) });
pub fn exit() {
unsafe {
let mut port = Port::new(0xf4);
port.write(0x10u32);
}
}
#[doc(hidden)]
pub fn _print(args: Arguments<'_>) {
use core::fmt::Write;
interrupts::without_interrupts(|| {
UART.lock().write_fmt(args).unwrap();
})
}
pub use crate::arch::qemu::*;
#[macro_export]
macro_rules! print {
($($arg:tt)*) => ($crate::qemu::_print(format_args!($($arg)*)));
($($arg:tt)*) => ($crate::arch::qemu::_print(format_args!($($arg)*)));
}
#[macro_export]

View File

@@ -4,9 +4,9 @@ version = 3
[[package]]
name = "anstream"
version = "0.6.7"
version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd2405b3ac1faab2990b74d728624cd9fd115651fcecc7c2d8daf01376275ba"
checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5"
dependencies = [
"anstyle",
"anstyle-parse",
@@ -91,9 +91,9 @@ dependencies = [
[[package]]
name = "async-io"
version = "2.2.2"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7"
checksum = "fb41eb19024a91746eba0773aa5e16036045bbf45733766661099e182ea6a744"
dependencies = [
"async-lock 3.3.0",
"cfg-if",
@@ -101,7 +101,7 @@ dependencies = [
"futures-io",
"futures-lite 2.2.0",
"parking",
"polling 3.3.1",
"polling 3.3.2",
"rustix 0.38.30",
"slab",
"tracing",
@@ -151,7 +151,7 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5"
dependencies = [
"async-io 2.2.2",
"async-io 2.3.0",
"async-lock 2.8.0",
"atomic-waker",
"cfg-if",
@@ -181,12 +181,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "az"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973"
[[package]]
name = "bincode"
version = "1.3.3"
@@ -196,12 +190,6 @@ dependencies = [
"serde",
]
[[package]]
name = "bit_field"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]]
name = "bitflags"
version = "1.3.2"
@@ -210,9 +198,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.4.1"
version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
[[package]]
name = "bitvec"
@@ -270,12 +258,6 @@ dependencies = [
"serde",
]
[[package]]
name = "bootloader_api"
version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daaa1fb791aea49e19db7b7b3662665d511eb4e30a0627fa525fd92652f39358"
[[package]]
name = "byteorder"
version = "1.5.0"
@@ -290,9 +272,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.4.16"
version = "4.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58e54881c004cec7895b0068a0a954cd5d62da01aef83fa35b1e594497bf5445"
checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c"
dependencies = [
"clap_builder",
"clap_derive",
@@ -300,9 +282,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.4.16"
version = "4.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59cb82d7f531603d2fd1f507441cdd35184fa81beff7bd489570de7f773460bb"
checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7"
dependencies = [
"anstream",
"anstyle",
@@ -364,29 +346,6 @@ version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
[[package]]
name = "embedded-graphics"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0649998afacf6d575d126d83e68b78c0ab0e00ca2ac7e9b3db11b4cbe8274ef0"
dependencies = [
"az",
"byteorder",
"embedded-graphics-core",
"float-cmp",
"micromath",
]
[[package]]
name = "embedded-graphics-core"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba9ecd261f991856250d2207f6d8376946cd9f412a2165d3b75bc87a0bc7a044"
dependencies = [
"az",
"byteorder",
]
[[package]]
name = "errno"
version = "0.3.8"
@@ -461,15 +420,6 @@ dependencies = [
"log",
]
[[package]]
name = "float-cmp"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
dependencies = [
"num-traits",
]
[[package]]
name = "funty"
version = "2.0.0"
@@ -620,7 +570,7 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8283e7331b8c93b9756e0cfdbcfb90312852f953c6faf9bf741e684cc3b6ad69"
dependencies = [
"bitflags 2.4.1",
"bitflags 2.4.2",
"crc",
"log",
"uuid",
@@ -634,9 +584,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "hermit-abi"
version = "0.3.3"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f"
[[package]]
name = "instant"
@@ -664,29 +614,6 @@ version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "kernel"
version = "0.1.0"
dependencies = [
"bootloader_api",
"embedded-graphics",
"lazy_static",
"pc-keyboard",
"pic8259",
"spin 0.9.8",
"uart_16550",
"x86_64",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
dependencies = [
"spin 0.5.2",
]
[[package]]
name = "libc"
version = "0.2.152"
@@ -701,9 +628,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
[[package]]
name = "linux-raw-sys"
version = "0.4.12"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]]
name = "llvm-tools"
@@ -711,16 +638,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "955be5d0ca0465caf127165acb47964f911e2bc26073e865deb8be7189302faf"
[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.20"
@@ -746,31 +663,6 @@ version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "micromath"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815"
[[package]]
name = "num-traits"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
dependencies = [
"autocfg",
]
[[package]]
name = "os"
version = "0.1.0"
dependencies = [
"bootloader",
"clap",
"kernel",
"ovmf-prebuilt",
]
[[package]]
name = "ovmf-prebuilt"
version = "0.1.0-alpha.1"
@@ -783,21 +675,6 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae"
[[package]]
name = "pc-keyboard"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6f2d937e3b8d63449b01401e2bae4041bc9dd1129c2e3e0d239407cf6635ac"
[[package]]
name = "pic8259"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb844b5b01db1e0b17938685738f113bfc903846f18932b378bc0eabfa40e194"
dependencies = [
"x86_64",
]
[[package]]
name = "pin-project"
version = "1.1.3"
@@ -859,9 +736,9 @@ dependencies = [
[[package]]
name = "polling"
version = "3.3.1"
version = "3.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e"
checksum = "545c980a3880efd47b2e262f6a4bb6daad6555cf3367aa9c4e52895f69537a41"
dependencies = [
"cfg-if",
"concurrent-queue",
@@ -873,9 +750,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.76"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
dependencies = [
"unicode-ident",
]
@@ -895,15 +772,6 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]]
name = "raw-cpuid"
version = "10.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "redox_syscall"
version = "0.4.1"
@@ -913,6 +781,15 @@ dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "runner"
version = "0.1.0"
dependencies = [
"bootloader",
"clap",
"ovmf-prebuilt",
]
[[package]]
name = "rustix"
version = "0.37.27"
@@ -933,31 +810,19 @@ version = "0.38.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca"
dependencies = [
"bitflags 2.4.1",
"bitflags 2.4.2",
"errno",
"libc",
"linux-raw-sys 0.4.12",
"linux-raw-sys 0.4.13",
"windows-sys 0.52.0",
]
[[package]]
name = "rustversion"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "ryu"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
version = "1.0.195"
@@ -1018,9 +883,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.11.2"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
[[package]]
name = "socket2"
@@ -1032,21 +897,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]]
name = "strsim"
version = "0.10.0"
@@ -1119,17 +969,6 @@ version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
[[package]]
name = "uart_16550"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dc00444796f6c71f47c85397a35e9c4dbf9901902ac02386940d178e2b78687"
dependencies = [
"bitflags 1.3.2",
"rustversion",
"x86",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
@@ -1144,19 +983,13 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "uuid"
version = "1.6.1"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560"
checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
dependencies = [
"getrandom",
]
[[package]]
name = "volatile"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "442887c63f2c839b346c192d047a7c87e73d0689c9157b00b53dcc27dd5ea793"
[[package]]
name = "waker-fn"
version = "1.1.1"
@@ -1331,26 +1164,3 @@ checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
dependencies = [
"tap",
]
[[package]]
name = "x86"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2781db97787217ad2a2845c396a5efe286f87467a5810836db6d74926e94a385"
dependencies = [
"bit_field",
"bitflags 1.3.2",
"raw-cpuid",
]
[[package]]
name = "x86_64"
version = "0.14.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b835097a84e4457323331ec5d6eb23d096066cbfb215d54096dcb4b2e85f500"
dependencies = [
"bit_field",
"bitflags 2.4.1",
"rustversion",
"volatile",
]

10
runner/Cargo.toml Normal file
View File

@@ -0,0 +1,10 @@
[package]
name = "runner"
version = "0.1.0"
edition = "2021"
[dependencies]
clap = { version = "4.4.16", features = ["derive"] }
ovmf-prebuilt = "0.1.0-alpha.1"
bootloader = { version = "0.11.5" }

40
runner/src/boot.rs Normal file
View File

@@ -0,0 +1,40 @@
use bootloader::DiskImageBuilder;
use clap::ValueEnum;
use std::{path::PathBuf, process};
use crate::target::Target;
#[derive(Copy, Clone, ValueEnum)]
pub enum Bootloader {
UEFI,
BIOS,
}
impl Bootloader {
pub fn to_str(&self) -> &'static str {
match self {
Self::UEFI => "UEFI",
Self::BIOS => "BIOS",
}
}
}
pub fn build_bootloader_img(bootloader: &Bootloader) {
let target = Target::X86_64 {
bootloader: *bootloader,
};
let kernel_path = PathBuf::from(target.binary_path());
let disk_builder = DiskImageBuilder::new(kernel_path.clone());
let img_path = PathBuf::from(target.qemu_bin_path());
let result = match bootloader {
Bootloader::UEFI => disk_builder.create_uefi_image(&img_path),
Bootloader::BIOS => disk_builder.create_bios_image(&img_path),
};
if let Err(err) = result {
println!("Failed to build bootloader: {}", err);
process::exit(1);
}
}

63
runner/src/main.rs Normal file
View File

@@ -0,0 +1,63 @@
use clap::Parser;
use std::process::{self, Command, Stdio};
use target::Target;
mod boot;
mod target;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Args {
/// what architecture / machine to target
#[command(subcommand)]
target: Option<Target>,
/// whether to use gdb
#[arg(long, short, id = "port")]
gdb: Option<Option<u16>>,
}
fn main() {
let args = Args::parse();
let target = args.target.unwrap_or(Target::default());
std::env::set_current_dir("../kernel").expect("uh oh");
build(&target);
run_qemu(&target, args.gdb);
}
fn run_qemu(target: &Target, gdb: Option<Option<u16>>) {
let mut qemu = target.qemu();
if let Some(port) = gdb {
let port = port.unwrap_or(1234);
qemu.arg("-S");
qemu.args(["-gdb", &format!("tcp::{}", port)]);
let mut gdb = target.gdb();
gdb.arg("-q");
gdb.args(["-ex", &format!("target remote :{}", port)]);
// gdb.args(["-ex", "b kernel::kernel_main"]);
// gdb.args(["-ex", "c"]);
let handle = std::thread::spawn(move || {
qemu.stdin(Stdio::null());
qemu.stdout(Stdio::null());
let exit_status = qemu.status().unwrap();
});
gdb.status().unwrap();
handle.join().unwrap();
} else {
let exit_status = qemu.status().unwrap();
// process::exit(exit_status.code().unwrap_or(-1));
}
}
fn build(target: &Target) {
let mut cargo = Command::new("cargo");
cargo.arg("build");
cargo.args(["--package", "kernel"]);
cargo.args(["--target", target.rust_target()]);
let status = cargo.status().expect("uh oh");
if !status.success() {
process::exit(status.code().unwrap_or(-1));
}
if let Target::X86_64 { bootloader } = target {
boot::build_bootloader_img(bootloader);
}
}

87
runner/src/target.rs Normal file
View File

@@ -0,0 +1,87 @@
use std::process::Command;
use clap::Subcommand;
use crate::boot::Bootloader;
#[derive(Copy, Clone, Subcommand)]
pub enum Target {
X86_64 {
#[arg(long, short, id = "type", default_value = "bios")]
bootloader: Bootloader,
},
Riscv64,
}
impl Default for Target {
fn default() -> Self {
Self::Riscv64
}
}
impl Target {
pub const X86_64_RUST_TARGET: &'static str = "x86_64-unknown-none";
pub fn qemu(&self) -> Command {
match self {
Self::X86_64 { bootloader } => {
let mut cmd = Command::new("qemu-system-x86_64");
if let Bootloader::UEFI = bootloader {
cmd.arg("-bios").arg(ovmf_prebuilt::ovmf_pure_efi());
}
cmd.args([
"-drive",
&format!("format=raw,file={}", self.qemu_bin_path()),
]);
cmd.args(["-device", "isa-debug-exit,iobase=0xf4,iosize=0x04"]);
cmd.args(["-serial", "stdio"]);
cmd
}
Self::Riscv64 => {
let mut cmd = Command::new("qemu-system-riscv64");
cmd.arg("-nographic");
cmd.arg("-semihosting");
cmd.args(["-machine", "sifive_u"]);
cmd.args(["-bios", "none"]);
cmd.args(["-kernel", &self.qemu_bin_path()]);
cmd
}
}
}
pub fn gdb(&self) -> Command {
match self {
Self::X86_64 { .. } => {
let mut cmd = Command::new("rust-gdb");
cmd.args([
"-ex",
&format!("symbol-file {} -o 0x8000000000", self.qemu_bin_path()),
]);
cmd
}
Self::Riscv64 => {
let mut cmd = Command::new("gdb");
cmd.arg(self.qemu_bin_path());
cmd
}
}
}
pub fn rust_target(&self) -> &'static str {
match self {
Self::X86_64 { .. } => Self::X86_64_RUST_TARGET,
Self::Riscv64 => "riscv64gc-unknown-none-elf",
}
}
pub fn target_folder(&self) -> String {
format!("target/{}/debug", self.rust_target())
}
pub fn binary_path(&self) -> String {
format!("{}/kernel", self.target_folder())
}
pub fn qemu_bin_path(&self) -> String {
match self {
Self::X86_64 { bootloader } => {
self.binary_path() + &format!("-{}.img", bootloader.to_str().to_lowercase())
}
Self::Riscv64 => self.binary_path(),
}
}
}

View File

@@ -1,5 +0,0 @@
[toolchain]
channel = "nightly"
profile = "default"
targets = ["x86_64-unknown-none"]
components = ["rust-src", "llvm-tools-preview"]

View File

@@ -1,10 +0,0 @@
use std::{env, fs};
fn main() {
let current_exe = env::current_exe().unwrap();
let uefi = current_exe.with_file_name("uefi.img");
let bios = current_exe.with_file_name("bios.img");
fs::copy(env!("UEFI_IMAGE"), &uefi).unwrap();
fs::copy(env!("BIOS_IMAGE"), &bios).unwrap();
}

View File

@@ -1,54 +0,0 @@
use std::{
env,
process::{self, Command, Stdio},
};
use clap::Parser;
use os::Bootloader;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
/// whether to use BIOS or UEFI
#[arg(long, short, id = "type", default_value = "bios")]
bootloader: Bootloader,
/// whether to use gdb
#[arg(long, short, id = "port")]
gdb: Option<Option<u16>>,
}
fn main() {
let args = Cli::parse();
let mut qemu = Command::new("qemu-system-x86_64");
qemu.args(["-device", "isa-debug-exit,iobase=0xf4,iosize=0x04"]);
qemu.args(["-serial", "stdio"]);
qemu.arg("-drive");
qemu.arg(format!("format=raw,file={}", args.bootloader.img_path()));
if let Bootloader::UEFI = args.bootloader {
qemu.arg("-bios").arg(ovmf_prebuilt::ovmf_pure_efi());
}
if let Some(port) = args.gdb {
let port = port.unwrap_or(1234);
qemu.arg("-S");
qemu.args(["-gdb", &format!("tcp::{}", port)]);
let mut gdb = Command::new("rust-gdb");
gdb.arg("-q");
gdb.args(["-ex", "target remote :1234"]);
gdb.args([
"-ex",
&format!("symbol-file {} -o 0x8000000000", env!("KERNEL_BIN")),
]);
gdb.args(["-ex", "b kernel::kernel_main"]);
gdb.args(["-ex", "c"]);
let handle = std::thread::spawn(move || {
qemu.stdin(Stdio::null());
qemu.stdout(Stdio::null());
let exit_status = qemu.status().unwrap();
});
gdb.status().unwrap();
handle.join().unwrap();
} else {
let exit_status = qemu.status().unwrap();
process::exit(exit_status.code().unwrap_or(-1));
}
}

View File

@@ -1,18 +0,0 @@
use std::env;
use clap::ValueEnum;
#[derive(Copy, Clone, ValueEnum)]
pub enum Bootloader {
UEFI,
BIOS,
}
impl Bootloader {
pub fn img_path(&self) -> &'static str {
match self {
Bootloader::UEFI => env!("UEFI_IMAGE"),
Bootloader::BIOS => env!("BIOS_IMAGE"),
}
}
}