I DONT KNOW WHAT IM DOING AND IM SCARED

This commit is contained in:
River 2025-05-28 23:07:33 -04:00
parent 76b7e7b93c
commit a6c141dda4
Signed by: shibedrill
GPG Key ID: 5FE0CB25945EFAA2
5 changed files with 293 additions and 28 deletions

View File

@ -4,4 +4,5 @@
pub mod asm; pub mod asm;
pub mod gdt; pub mod gdt;
pub mod interrupts; pub mod interrupts;
pub mod paging;
pub mod serial; pub mod serial;

View File

@ -0,0 +1,266 @@
#![allow(dead_code)]
use intbits::Bits;
#[repr(packed)]
pub struct PageMapLevel5 {
entries: [PageMapLevel5Entry; 512],
}
pub struct PageMapLevel5Entry {
value: u64,
}
impl PageMapLevel5Entry {
pub fn execute_disable(&self) -> bool {
self.value.bit(63)
}
pub fn present(&self) -> bool {
self.value.bit(0)
}
pub fn set_present(&mut self, present: bool) {
self.value.set_bit(0, present);
}
pub fn writable(&self) -> bool {
self.value.bit(1)
}
pub fn set_writable(&mut self, writable: bool) {
self.value.set_bit(1, writable);
}
pub fn user_accessible(&self) -> bool {
self.value.bit(2)
}
pub fn set_user_accessible(&mut self, accessible: bool) {
self.value.set_bit(2, accessible);
}
pub fn write_through(&self) -> bool {
self.value.bit(3)
}
pub fn set_write_through(&mut self, write_through: bool) {
self.value.set_bit(3, write_through);
}
pub fn cache_disable(&self) -> bool {
self.value.bit(4)
}
pub fn set_cache_disable(&mut self, cache_disable: bool) {
self.value.set_bit(4, cache_disable);
}
pub fn accessed(&self) -> bool {
self.value.bit(5)
}
pub fn set_accessed(&mut self, accessed: bool) {
self.value.set_bit(5, accessed);
}
pub fn physical_address(&self) -> usize {
self.value.bits(12..=51) as usize
}
pub fn set_physical_address(&mut self, address: u64) {
self.value &= 0xFFF0000000000FFF;
self.value |= (address & 0xFFFFFFFFFF) << 12;
}
pub fn available(&self) -> usize {
(self.value.bits(52..=62) << 4 & self.value.bits(8..=11) << 1 & self.value.bits(6..=6))
as usize
}
}
#[repr(packed)]
pub struct PageMapLevel4 {
entries: [PageMapLevel4Entry; 512],
}
pub struct PageMapLevel4Entry {
value: u64,
}
impl PageMapLevel4Entry {
pub fn execute_disable(&self) -> bool {
self.value.bit(63)
}
pub fn present(&self) -> bool {
self.value.bit(0)
}
pub fn set_present(&mut self, present: bool) {
self.value.set_bit(0, present);
}
pub fn writable(&self) -> bool {
self.value.bit(1)
}
pub fn set_writable(&mut self, writable: bool) {
self.value.set_bit(1, writable);
}
pub fn user_accessible(&self) -> bool {
self.value.bit(2)
}
pub fn set_user_accessible(&mut self, accessible: bool) {
self.value.set_bit(2, accessible);
}
pub fn write_through(&self) -> bool {
self.value.bit(3)
}
pub fn set_write_through(&mut self, write_through: bool) {
self.value.set_bit(3, write_through);
}
pub fn cache_disable(&self) -> bool {
self.value.bit(4)
}
pub fn set_cache_disable(&mut self, cache_disable: bool) {
self.value.set_bit(4, cache_disable);
}
pub fn accessed(&self) -> bool {
self.value.bit(5)
}
pub fn set_accessed(&mut self, accessed: bool) {
self.value.set_bit(5, accessed);
}
pub fn physical_address(&self) -> usize {
self.value.bits(12..=51) as usize
}
pub fn set_physical_address(&mut self, address: u64) {
self.value &= 0xFFF0000000000FFF;
self.value |= (address & 0xFFFFFFFFFF) << 12;
}
pub fn set_pointer_table(&mut self, table: &PageDirectoryPointerTable) {
self.set_physical_address(&raw const table as u64);
}
pub fn available(&self) -> usize {
(self.value.bits(52..=62) << 4 & self.value.bits(8..=11) << 1 & self.value.bits(6..=6))
as usize
}
}
#[repr(packed)]
pub struct PageDirectoryPointerTable {
entries: [*mut PageDirectory; 4],
}
pub struct PageDirectoryPointer {
value: u64
}
impl PageDirectoryPointer {
pub fn execute_disable(&self) -> bool {
self.value.bit(63)
}
pub fn present(&self) -> bool {
self.value.bit(0)
}
pub fn set_present(&mut self, present: bool) {
self.value.set_bit(0, present);
}
pub fn writable(&self) -> bool {
self.value.bit(1)
}
pub fn set_writable(&mut self, writable: bool) {
self.value.set_bit(1, writable);
}
pub fn user_accessible(&self) -> bool {
self.value.bit(2)
}
pub fn set_user_accessible(&mut self, accessible: bool) {
self.value.set_bit(2, accessible);
}
pub fn write_through(&self) -> bool {
self.value.bit(3)
}
pub fn set_write_through(&mut self, write_through: bool) {
self.value.set_bit(3, write_through);
}
pub fn cache_disable(&self) -> bool {
self.value.bit(4)
}
pub fn set_cache_disable(&mut self, cache_disable: bool) {
self.value.set_bit(4, cache_disable);
}
pub fn accessed(&self) -> bool {
self.value.bit(5)
}
pub fn set_accessed(&mut self, accessed: bool) {
self.value.set_bit(5, accessed);
}
pub fn physical_address(&self) -> *mut PageDirectory {
self.value.bits(12..=51) as *mut PageDirectory
}
pub fn set_physical_address(&mut self, address: u64) {
self.value &= 0xFFF0000000000FFF;
self.value |= (address & 0xFFFFFFFFFF) << 12;
}
pub fn set_page_directory(&mut self, dir: &PageDirectory) {
self.set_physical_address(&raw const dir as u64);
}
pub fn available(&self) -> usize {
(self.value.bits(52..=62) << 4 & self.value.bits(8..=11) << 1 & self.value.bits(6..=6))
as usize
}
}
pub struct PageDirectory {
entries: [PageDirectoryEntry; 512],
}
pub struct PageDirectoryEntry {
value: u64,
}
impl PageDirectoryEntry {
pub fn execute_disable(&self) -> bool {
self.value.bit(63)
}
pub fn present(&self) -> bool {
self.value.bit(0)
}
pub fn set_present(&mut self, present: bool) {
self.value.set_bit(0, present);
}
pub fn writable(&self) -> bool {
self.value.bit(1)
}
pub fn set_writable(&mut self, writable: bool) {
self.value.set_bit(1, writable);
}
pub fn user_accessible(&self) -> bool {
self.value.bit(2)
}
pub fn set_user_accessible(&mut self, accessible: bool) {
self.value.set_bit(2, accessible);
}
pub fn write_through(&self) -> bool {
self.value.bit(3)
}
pub fn set_write_through(&mut self, write_through: bool) {
self.value.set_bit(3, write_through);
}
pub fn cache_disable(&self) -> bool {
self.value.bit(4)
}
pub fn set_cache_disable(&mut self, cache_disable: bool) {
self.value.set_bit(4, cache_disable);
}
pub fn accessed(&self) -> bool {
self.value.bit(5)
}
pub fn set_accessed(&mut self, accessed: bool) {
self.value.set_bit(5, accessed);
}
pub fn physical_address(&self) -> usize {
self.value.bits(12..=51) as usize
}
pub fn set_physical_address(&mut self, address: u64) {
self.value &= 0xFFF0000000000FFF;
self.value |= (address & 0xFFFFFFFFFF) << 12;
}
pub fn available(&self) -> usize {
(self.value.bits(52..=62) << 4 & self.value.bits(8..=11) << 1 & self.value.bits(6..=6))
as usize
}
}
#[repr(align(4096))]
pub struct PageTable {
entries: [PageTableEntry; 512],
}
#[repr(packed)]
pub struct PageTableEntry {
value: u64,
}

View File

@ -5,6 +5,7 @@ use crate::format;
use crate::log::LogLevel; use crate::log::LogLevel;
use crate::memory::alloc::string::String; use crate::memory::alloc::string::String;
#[allow(dead_code)]
pub static INITRAMFS_DEFAULT_PATH: &str = "/boot/initramfs.tar.lzma"; pub static INITRAMFS_DEFAULT_PATH: &str = "/boot/initramfs.tar.lzma";
pub static LOG_DEFAULT_LEVEL: LogLevel = LogLevel::Info; pub static LOG_DEFAULT_LEVEL: LogLevel = LogLevel::Info;

View File

@ -22,6 +22,7 @@ mod util;
use core::arch::asm; use core::arch::asm;
use arch::x86_64::gdt::gdt; use arch::x86_64::gdt::gdt;
use arch::x86_64::paging::{self, PageDirectory, PageMapLevel4Entry, PageMapLevel5, PageMapLevel5Entry};
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use arch::x86_64::serial::Serialport; use arch::x86_64::serial::Serialport;
@ -29,12 +30,11 @@ use arch::asm::*;
use boot::{modules::*, params, *}; use boot::{modules::*, params, *};
use constants::*; use constants::*;
use log::*; use log::*;
use memory::{MEMMAP_REQUEST, HHDM_RESPONSE};
use memory::alloc::{format, string::*, vec}; use memory::alloc::{format, string::*, vec};
use memory::{HHDM_RESPONSE, MEMMAP_REQUEST};
use params::*; use params::*;
use intbits::{self, Bits}; use intbits::{self, Bits};
use limine::file::File;
use limine::memory_map::EntryType; use limine::memory_map::EntryType;
#[allow(unused_imports)] #[allow(unused_imports)]
use lzma_rs::lzma_decompress; use lzma_rs::lzma_decompress;
@ -113,27 +113,6 @@ unsafe extern "C" fn main() -> ! {
log_trace!("{log_msg}") log_trace!("{log_msg}")
} }
let irfs_path = {
if let Some(key) = PARAMS.get("-initramfs") {
key
} else {
INITRAMFS_DEFAULT_PATH
}
};
log_trace!("Boot: initramfs path requested: {irfs_path}");
let _initramfs = {
let mut result: Option<&File> = None;
for file in MODULE_RESPONSE.modules() {
if file.path().to_string_lossy() == irfs_path {
result = Some(file);
log_info!("Boot: initramfs found");
}
}
result
}
.expect("initramfs not found in modules list");
// Panic if this is absent. It's needed to set up the GDT and paging // Panic if this is absent. It's needed to set up the GDT and paging
let mmap_response = MEMMAP_REQUEST let mmap_response = MEMMAP_REQUEST
.get_response() .get_response()
@ -223,9 +202,22 @@ unsafe extern "C" fn main() -> ! {
cr3.bits(12..=31) cr3.bits(12..=31)
}; };
log_trace!("Boot: Physical address of page directory: 0x{:x}", pd_addr); log_trace!("Boot: Physical address of page directory: 0x{:x}", pd_addr);
log_trace!("Boot: Virtual address of page directory: 0x{:x}", pd_addr + HHDM_RESPONSE.offset()); log_trace!(
log_trace!("Boot: GDT: 0x{:x} bytes @ 0x{:x}", unsafe { gdt().0 }, unsafe { gdt().1} ); "Boot: Virtual address of page directory: 0x{:x}",
log_trace!("Boot: GDT: 0x{:x}", unsafe { *((gdt().1 + 0x0) as *const u64) }) pd_addr + HHDM_RESPONSE.offset()
);
log_trace!(
"Boot: GDT: 0x{:x} bytes @ 0x{:x}",
unsafe { gdt().0 },
unsafe { gdt().1 }
);
log_trace!("Boot: GDT: 0x{:x}", unsafe {
*((gdt().1 + 0x0) as *const u64)
});
log_trace!(
"Size of page directory: {}",
size_of::<PageMapLevel4Entry>()
);
} }
panic!("Bailing"); panic!("Bailing");

View File

@ -5,7 +5,10 @@
use enumflags2::*; use enumflags2::*;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use limine::{request::{ExecutableAddressRequest, HhdmRequest, MemoryMapRequest}, response::HhdmResponse}; use limine::{
request::{ExecutableAddressRequest, HhdmRequest, MemoryMapRequest},
response::HhdmResponse,
};
use core::alloc::{Allocator, Layout}; use core::alloc::{Allocator, Layout};
use talc::*; use talc::*;
@ -26,7 +29,9 @@ pub static MEMMAP_REQUEST: MemoryMapRequest = limine::request::MemoryMapRequest:
pub static HHDM_REQUEST: HhdmRequest = limine::request::HhdmRequest::new(); pub static HHDM_REQUEST: HhdmRequest = limine::request::HhdmRequest::new();
lazy_static! { lazy_static! {
pub static ref HHDM_RESPONSE: &'static HhdmResponse = HHDM_REQUEST.get_response().expect("Did not get HHDM response from bootloader"); pub static ref HHDM_RESPONSE: &'static HhdmResponse = HHDM_REQUEST
.get_response()
.expect("Did not get HHDM response from bootloader");
} }
static mut ARENA: [u8; 10000] = [0; 10000]; static mut ARENA: [u8; 10000] = [0; 10000];