forked from LowLevelDevs/FoundryOS
first interrupt handler + setup IDT
This commit is contained in:
+3
-1
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "kernel"
|
||||
name = "FoundryOS"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
@@ -8,6 +8,8 @@ limine = "0.3.1"
|
||||
lib_framebuffer = { path = "../lib/lib_framebuffer" }
|
||||
lib_serial = { path = "../lib/lib_serial" }
|
||||
lib_ascii = { path = "../lib/lib_ascii" }
|
||||
x86_64 = "0.15.2"
|
||||
spin = "0.9.8"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.2.14"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
pub mod x86_64;
|
||||
@@ -0,0 +1,22 @@
|
||||
use lib_ascii::println_log;
|
||||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
||||
|
||||
use spin::Lazy;
|
||||
|
||||
static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| {
|
||||
let mut idt = InterruptDescriptorTable::new();
|
||||
idt.breakpoint.set_handler_fn(breakpoint_handler);
|
||||
idt
|
||||
});
|
||||
|
||||
|
||||
pub fn init_idt() {
|
||||
IDT.load();
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn breakpoint_handler(
|
||||
stack_frame: InterruptStackFrame
|
||||
) {
|
||||
println_log!("Exception: Breakpoint\n{:#?}", stack_frame);
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
pub mod interrupts;
|
||||
@@ -0,0 +1,62 @@
|
||||
#![no_std]
|
||||
|
||||
#![feature(abi_x86_interrupt)]
|
||||
|
||||
use core::arch::asm;
|
||||
use limine::request::{RequestsEndMarker, RequestsStartMarker};
|
||||
use limine::BaseRevision;
|
||||
|
||||
pub use lib_serial::{serial_print, serial_println, serial_read};
|
||||
pub use lib_ascii::{print, print_log, println, println_log, WRITER};
|
||||
|
||||
mod arch;
|
||||
|
||||
use lib_framebuffer;
|
||||
|
||||
|
||||
/// Sets the base revision to the latest revision supported by the crate.
|
||||
/// See specification for further info.
|
||||
/// Be sure to mark all limine requests with #[used], otherwise they may be removed by the compiler.
|
||||
#[used]
|
||||
// The .requests section allows limine to find the requests faster and more safely.
|
||||
#[link_section = ".requests"]
|
||||
static BASE_REVISION: BaseRevision = BaseRevision::new();
|
||||
|
||||
/// Define the stand and end markers for Limine requests.
|
||||
#[used]
|
||||
#[link_section = ".requests_start_marker"]
|
||||
static _START_MARKER: RequestsStartMarker = RequestsStartMarker::new();
|
||||
#[used]
|
||||
#[link_section = ".requests_end_marker"]
|
||||
static _END_MARKER: RequestsEndMarker = RequestsEndMarker::new();
|
||||
|
||||
#[panic_handler]
|
||||
fn rust_panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
hcf();
|
||||
}
|
||||
|
||||
pub fn hcf() -> ! {
|
||||
loop {
|
||||
unsafe {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
asm!("hlt");
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||
asm!("wfi");
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
asm!("idle 0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn boot() -> Result<(), &'static str> {
|
||||
|
||||
if !BASE_REVISION.is_supported() {
|
||||
return Err("base revision not supported");
|
||||
}
|
||||
|
||||
lib_serial::init()?;
|
||||
arch::x86_64::interrupts::init_idt();
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
+11
-52
@@ -1,46 +1,23 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::arch::asm;
|
||||
|
||||
use lib_serial::{serial_println, serial_read};
|
||||
use lib_ascii::{print, println, WRITER};
|
||||
|
||||
use limine::request::{RequestsEndMarker, RequestsStartMarker};
|
||||
use limine::BaseRevision;
|
||||
|
||||
use lib_framebuffer;
|
||||
|
||||
/// Sets the base revision to the latest revision supported by the crate.
|
||||
/// See specification for further info.
|
||||
/// Be sure to mark all limine requests with #[used], otherwise they may be removed by the compiler.
|
||||
#[used]
|
||||
// The .requests section allows limine to find the requests faster and more safely.
|
||||
#[link_section = ".requests"]
|
||||
static BASE_REVISION: BaseRevision = BaseRevision::new();
|
||||
|
||||
/// Define the stand and end markers for Limine requests.
|
||||
#[used]
|
||||
#[link_section = ".requests_start_marker"]
|
||||
static _START_MARKER: RequestsStartMarker = RequestsStartMarker::new();
|
||||
#[used]
|
||||
#[link_section = ".requests_end_marker"]
|
||||
static _END_MARKER: RequestsEndMarker = RequestsEndMarker::new();
|
||||
use FoundryOS::{
|
||||
println, println_log
|
||||
};
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn kmain() -> ! {
|
||||
// All limine requests must also be referenced in a called function, otherwise they may be
|
||||
// removed by the linker.
|
||||
assert!(BASE_REVISION.is_supported());
|
||||
|
||||
|
||||
if let Err(_) = lib_serial::init() {
|
||||
loop {}
|
||||
}
|
||||
FoundryOS::boot();
|
||||
|
||||
let dimensions = lib_ascii::screensize_chars();
|
||||
let dimensions2 = lib_framebuffer::screensize_px();
|
||||
println!("Hello World!");
|
||||
println_log!(" [ Initialising ] ");
|
||||
|
||||
x86_64::instructions::interrupts::int3();
|
||||
|
||||
println!("Dimensions: {}x{} (px)", dimensions2.0, dimensions2.1);
|
||||
println!("Dimensions: {}x{} (chars)", dimensions.0, dimensions.1);
|
||||
|
||||
@@ -63,27 +40,9 @@ unsafe extern "C" fn kmain() -> ! {
|
||||
\\______/ \\______/ \\_/ \\______|
|
||||
");
|
||||
|
||||
for i in 0u8..128 {
|
||||
print!("{}", i as char);
|
||||
}
|
||||
|
||||
hcf();
|
||||
|
||||
FoundryOS::hcf();
|
||||
}
|
||||
|
||||
#[panic_handler]
|
||||
fn rust_panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
hcf();
|
||||
}
|
||||
|
||||
fn hcf() -> ! {
|
||||
loop {
|
||||
unsafe {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
asm!("hlt");
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||
asm!("wfi");
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
asm!("idle 0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user