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

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]