kernel: move limine to lib
This commit is contained in:
parent
87d7f5860d
commit
6645607c69
|
|
@ -20,6 +20,7 @@ harness = false
|
|||
[[test]]
|
||||
name = "stack_overflow"
|
||||
harness = false
|
||||
test = false # currently doesn't work reliably because the stack corrupts something
|
||||
|
||||
[dependencies]
|
||||
bit_field = "0.10.3"
|
||||
|
|
|
|||
|
|
@ -100,12 +100,19 @@ const impl Default for MemoryRegion {
|
|||
pub struct BootInfo {
|
||||
pub hhdm_base: u64,
|
||||
pub memory_map: &'static [MemoryRegion],
|
||||
pub executable_file: Option<&'static [u8]>,
|
||||
}
|
||||
|
||||
pub static BOOT_INFO: OnceLock<BootInfo> = OnceLock::new();
|
||||
static mut MEMORY_MAP: [MemoryRegion; 128] = [MemoryRegion::default(); 128];
|
||||
|
||||
pub fn init_boot_info<I: Iterator<Item = MemoryRegion>>(hhdm_base: u64, memory_map: I) {
|
||||
pub fn init_boot_info<I: Iterator<Item = MemoryRegion>>(
|
||||
hhdm_base: u64,
|
||||
memory_map: I,
|
||||
executable_file: Option<&'static [u8]>,
|
||||
) {
|
||||
_ = crate::memory::HHDM_BASE.try_insert(hhdm_base);
|
||||
|
||||
BOOT_INFO.initialize(|| {
|
||||
for (i, region) in memory_map.enumerate() {
|
||||
assert!(i < 128, "Memory map has more than 128 entries");
|
||||
|
|
@ -117,6 +124,7 @@ pub fn init_boot_info<I: Iterator<Item = MemoryRegion>>(hhdm_base: u64, memory_m
|
|||
Ok::<_, !>(BootInfo {
|
||||
hhdm_base,
|
||||
memory_map: unsafe { (&raw const MEMORY_MAP).as_ref_unchecked() },
|
||||
executable_file,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
use core::{cell::UnsafeCell, ffi::CStr, fmt::Debug, ptr::NonNull};
|
||||
use core::{cell::UnsafeCell, fmt::Debug, ptr::NonNull};
|
||||
|
||||
use crate::serial_println;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct BaseRevision(UnsafeCell<[u64; 3]>);
|
||||
|
|
@ -326,6 +328,46 @@ impl LimineFile {
|
|||
}
|
||||
}
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".limine_requests_start")]
|
||||
static LIMINE_REQUESTS_START: RequestsStartMarker = REQUESTS_START_MARKER;
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".limine_requests")]
|
||||
pub static EXECUTABLE_FILE_REQUEST: ExecutableFileRequest = ExecutableFileRequest::new();
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".limine_requests")]
|
||||
pub static LIMINE_BASE_REVISION: BaseRevision = BaseRevision::from_revision(6);
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".limine_requests")]
|
||||
pub static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new();
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".limine_requests")]
|
||||
pub static HHDM_REQUEST: HhdmRequest = HhdmRequest::new();
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".limine_requests")]
|
||||
pub static MEMMAP_REQUEST: MemMapRequest = MemMapRequest::new();
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".limine_requests_end")]
|
||||
static LIMINE_REQUESTS_END: RequestsEndMarker = REQUESTS_END_MARKER;
|
||||
|
||||
pub fn init_limine_boot_info() {
|
||||
crate::boot::init_boot_info(
|
||||
HHDM_REQUEST
|
||||
.offset()
|
||||
.expect("HHDM offset not provided by bootloader"),
|
||||
MEMMAP_REQUEST
|
||||
.entries()
|
||||
.iter()
|
||||
.inspect(|e| {
|
||||
serial_println!("{e:?}");
|
||||
})
|
||||
.map(|&&e| e.into()),
|
||||
EXECUTABLE_FILE_REQUEST.file().map(|f| f.bytes()),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,25 +23,9 @@ static GDT: LazyLock<GlobalDescriptorTable> = LazyLock::new(GlobalDescriptorTabl
|
|||
#[unsafe(no_mangle)]
|
||||
extern "C" fn _start() -> ! {
|
||||
kernel::logger::init(log::LevelFilter::Trace);
|
||||
assert!(limine_requests::LIMINE_BASE_REVISION.is_supported());
|
||||
assert!(kernel::limine::LIMINE_BASE_REVISION.is_supported());
|
||||
|
||||
_ = kernel::memory::HHDM_BASE
|
||||
.try_insert(
|
||||
limine_requests::HHDM_REQUEST
|
||||
.offset()
|
||||
.expect("HHDM offset not provided by bootloader"),
|
||||
)
|
||||
.expect("HHDM offset already set");
|
||||
|
||||
kernel::boot::init_boot_info(
|
||||
limine_requests::HHDM_REQUEST
|
||||
.offset()
|
||||
.expect("HHDM offset not provided by bootloader"),
|
||||
limine_requests::MEMMAP_REQUEST
|
||||
.entries()
|
||||
.iter()
|
||||
.map(|&&e| e.into()),
|
||||
);
|
||||
kernel::limine::init_limine_boot_info();
|
||||
|
||||
kernel::serial_println!(
|
||||
"HHDM offset: 0x{:#x}",
|
||||
|
|
@ -50,13 +34,12 @@ extern "C" fn _start() -> ! {
|
|||
|
||||
kernel::serial_println!(
|
||||
"Memory map: {:#?}",
|
||||
limine_requests::MEMMAP_REQUEST.entries()
|
||||
kernel::limine::MEMMAP_REQUEST.entries()
|
||||
);
|
||||
|
||||
GDT.load();
|
||||
IDT.load();
|
||||
|
||||
|
||||
kernel::serial_println!("entry point: 0x{:x}", _start as *const () as usize);
|
||||
kernel::serial_println!(
|
||||
"entry point phy: {:?}",
|
||||
|
|
@ -75,7 +58,7 @@ extern "C" fn _start() -> ! {
|
|||
|
||||
kernel::serial_println!("PMM: {pmm:#?}");
|
||||
|
||||
let fb = limine_requests::FRAMEBUFFER_REQUEST
|
||||
let fb = kernel::limine::FRAMEBUFFER_REQUEST
|
||||
.framebuffers()
|
||||
.first()
|
||||
.expect("No framebuffer found");
|
||||
|
|
@ -95,34 +78,3 @@ extern "C" fn _start() -> ! {
|
|||
|
||||
kernel::x86_64::halt_loop()
|
||||
}
|
||||
|
||||
mod limine_requests {
|
||||
use kernel::limine::{
|
||||
BaseRevision, FramebufferRequest, REQUESTS_END_MARKER, REQUESTS_START_MARKER,
|
||||
RequestsEndMarker, RequestsStartMarker,
|
||||
};
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".limine_requests_start")]
|
||||
static LIMINE_REQUESTS_START: RequestsStartMarker = REQUESTS_START_MARKER;
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".limine_requests")]
|
||||
pub static LIMINE_BASE_REVISION: BaseRevision = BaseRevision::from_revision(6);
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".limine_requests")]
|
||||
pub static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new();
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".limine_requests")]
|
||||
pub static HHDM_REQUEST: kernel::limine::HhdmRequest = kernel::limine::HhdmRequest::new();
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".limine_requests")]
|
||||
pub static MEMMAP_REQUEST: kernel::limine::MemMapRequest = kernel::limine::MemMapRequest::new();
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".limine_requests_end")]
|
||||
static LIMINE_REQUESTS_END: RequestsEndMarker = REQUESTS_END_MARKER;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use core::ffi::{CStr, c_void};
|
||||
use core::ffi::c_void;
|
||||
|
||||
use crate::{
|
||||
limine::LimineFile,
|
||||
|
|
|
|||
|
|
@ -472,7 +472,6 @@ const PRIVILEGE_STACK_TABLE_SIZE: usize = 3;
|
|||
const INTERRUPT_STACK_TABLE_SIZE: usize = 7;
|
||||
|
||||
#[repr(C, packed(4))]
|
||||
#[derive(Debug)]
|
||||
pub struct TaskStateSegment {
|
||||
_reserved1: [u8; 4],
|
||||
pub privilege_stack_table: [u64; PRIVILEGE_STACK_TABLE_SIZE],
|
||||
|
|
@ -482,6 +481,31 @@ pub struct TaskStateSegment {
|
|||
pub iomap_base: u16,
|
||||
}
|
||||
|
||||
impl Debug for TaskStateSegment {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
let mut dbg = f.debug_struct("TaskStateSegment");
|
||||
|
||||
let rsps = self.privilege_stack_table;
|
||||
let ists = self.interrupt_stack_table;
|
||||
|
||||
dbg.field("RSP0", &format_args!("{:#x}", rsps[0]))
|
||||
.field("RSP1", &format_args!("{:#x}", rsps[1]))
|
||||
.field("RSP2", &format_args!("{:#x}", rsps[2]));
|
||||
|
||||
dbg.field("IST1", &format_args!("{:#x}", ists[0]))
|
||||
.field("IST2", &format_args!("{:#x}", ists[1]))
|
||||
.field("IST3", &format_args!("{:#x}", ists[2]))
|
||||
.field("IST4", &format_args!("{:#x}", ists[3]))
|
||||
.field("IST5", &format_args!("{:#x}", ists[4]))
|
||||
.field("IST6", &format_args!("{:#x}", ists[5]))
|
||||
.field("IST7", &format_args!("{:#x}", ists[6]));
|
||||
|
||||
dbg.field("iomap_base", &format_args!("{:#x}", self.iomap_base));
|
||||
|
||||
dbg.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl TaskStateSegment {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
|
|
@ -514,7 +538,7 @@ pub const MC_STACK: u8 = 2;
|
|||
pub const PF_STACK: u8 = 3;
|
||||
|
||||
const STACK_SIZE: usize = super::PAGE_SIZE * 5;
|
||||
#[repr(align(16))]
|
||||
#[repr(align(4096))]
|
||||
pub struct Stack(MaybeUninit<[u8; STACK_SIZE]>);
|
||||
|
||||
impl Stack {
|
||||
|
|
|
|||
|
|
@ -523,7 +523,12 @@ extern "C" fn global_interrupt_handler(
|
|||
serial_println!("Breakpoint interrupt handled successfully.");
|
||||
}
|
||||
ExceptionVector::PAGE_FAULT => {
|
||||
serial_println!("Page fault occurred! Error code: {:#x}", error_code);
|
||||
let cr2 = super::registers::Cr2::read();
|
||||
serial_println!(
|
||||
"Page fault occurred! Error code: {:#x} CR2: {:#x}",
|
||||
error_code,
|
||||
cr2.0
|
||||
);
|
||||
debug_backtrace(&Context {
|
||||
rip: frame.instruction_pointer,
|
||||
registers: *registers,
|
||||
|
|
|
|||
|
|
@ -64,6 +64,17 @@ bitflags::bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Cr2(pub u64);
|
||||
impl Cr2 {
|
||||
pub fn read() -> Self {
|
||||
let value: u64;
|
||||
unsafe {
|
||||
asm!("mov {}, cr2", out(reg) value, options(nomem, nostack, preserves_flags));
|
||||
}
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl Cr4 {
|
||||
pub fn read() -> Self {
|
||||
let value: u64;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
use core::{cell::UnsafeCell, mem::offset_of};
|
||||
|
||||
use kernel::{
|
||||
serial_println,
|
||||
sync::LazyLock,
|
||||
x86_64::{
|
||||
gdt::{DF_STACK, GlobalDescriptorTable, RING0},
|
||||
|
|
@ -17,6 +18,7 @@ pub static GDT: LazyLock<GlobalDescriptorTable> = LazyLock::new(GlobalDescriptor
|
|||
#[unsafe(export_name = "_start")]
|
||||
pub extern "C" fn main() -> ! {
|
||||
kernel::serial_println!("Hello, world!");
|
||||
kernel::limine::init_limine_boot_info();
|
||||
|
||||
GDT.load();
|
||||
kernel::serial_println!("[ok] GDT loaded");
|
||||
|
|
|
|||
Loading…
Reference in a new issue