refactored for architectures and added riscv support
This commit is contained in:
9
kernel/src/arch/mod.rs
Normal file
9
kernel/src/arch/mod.rs
Normal 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::*;
|
||||
26
kernel/src/arch/riscv64/link.ld
Normal file
26
kernel/src/arch/riscv64/link.ld
Normal 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 = .);
|
||||
}
|
||||
|
||||
34
kernel/src/arch/riscv64/mod.rs
Normal file
34
kernel/src/arch/riscv64/mod.rs
Normal 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 {}
|
||||
}
|
||||
28
kernel/src/arch/riscv64/qemu.rs
Normal file
28
kernel/src/arch/riscv64/qemu.rs
Normal 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 }
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
23
kernel/src/arch/x86_64/mod.rs
Normal file
23
kernel/src/arch/x86_64/mod.rs
Normal 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();
|
||||
}
|
||||
}
|
||||
25
kernel/src/arch/x86_64/qemu.rs
Normal file
25
kernel/src/arch/x86_64/qemu.rs
Normal 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();
|
||||
})
|
||||
}
|
||||
@@ -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
26
kernel/src/lib2.rs
Normal 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()
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user