Add some long mode support

This commit is contained in:
Jeremy Soller
2022-02-07 10:30:29 -07:00
parent fb29a36208
commit 010569fb21
15 changed files with 338 additions and 162 deletions
+7 -1
View File
@@ -24,6 +24,7 @@ use self::vga::{VgaTextBlock, VgaTextColor, Vga};
mod disk;
mod logger;
mod paging;
mod panic;
mod thunk;
mod vbe;
@@ -43,6 +44,8 @@ static ALLOCATOR: LockedHeap = LockedHeap::empty();
static mut VGA: Vga = unsafe { Vga::new(VGA_ADDR as *mut VgaTextBlock, 80, 25) };
static mut KERNEL_PHYS: u64 = 0;
#[no_mangle]
pub unsafe extern "C" fn kstart(
boot_disk: usize,
@@ -77,7 +80,8 @@ pub unsafe extern "C" fn kstart(
}
}
// Initialize allocator at the end of stage 3 with a meager 1 MiB
// Initialize allocator at the end of stage 3 with a meager 1 MiB, which we can be pretty
// sure will be available.
extern "C" {
static mut __end: u8;
}
@@ -119,6 +123,8 @@ pub unsafe extern "C" fn kstart(
}
}
//let page_phys = paging::paging_create(KERNEL_PHYS);
let mut modes = Vec::new();
{
// Get card info
+78
View File
@@ -0,0 +1,78 @@
use core::alloc::{GlobalAlloc, Layout};
use core::slice;
unsafe fn paging_allocate() -> Option<&'static mut [u64]> {
let ptr = crate::ALLOCATOR.alloc_zeroed(
Layout::from_size_align(4096, 4096).unwrap()
);
if ! ptr.is_null() {
Some(slice::from_raw_parts_mut(
ptr as *mut u64,
512 // page size divided by u64 size
))
} else {
None
}
}
pub unsafe fn paging_create(kernel_phys: u64) -> Option<u64> {
// Create PML4
let pml4 = paging_allocate()?;
// Recursive mapping for compatibility
pml4[511] = pml4.as_ptr() as u64 | 1 << 1 | 1;
{
// Create PDP for identity mapping
let pdp = paging_allocate()?;
// Link first user and first kernel PML4 entry to PDP
pml4[0] = pdp.as_ptr() as u64 | 1 << 1 | 1;
pml4[256] = pdp.as_ptr() as u64 | 1 << 1 | 1;
// Identity map 8 GiB pages
for pdp_i in 0..8 {
let pd = paging_allocate()?;
pdp[pdp_i] = pd.as_ptr() as u64 | 1 << 1 | 1;
for pd_i in 0..pd.len() {
let pt = paging_allocate()?;
pd[pd_i] = pt.as_ptr() as u64 | 1 << 1 | 1;
for pt_i in 0..pt.len() {
let addr =
pdp_i as u64 * 0x4000_0000 +
pd_i as u64 * 0x20_0000 +
pt_i as u64 * 0x1000;
pt[pt_i] = addr | 1 << 1 | 1;
}
}
}
}
{
// Create PDP for kernel mapping
let pdp = paging_allocate()?;
// Link second to last PML4 entry to PDP
pml4[510] = pdp.as_ptr() as u64 | 1 << 1 | 1;
// Map 1 GiB at kernel offset
for pdp_i in 0..1 {
let pd = paging_allocate()?;
pdp[pdp_i] = pd.as_ptr() as u64 | 1 << 1 | 1;
for pd_i in 0..pd.len() {
let pt = paging_allocate()?;
pd[pd_i] = pt.as_ptr() as u64 | 1 << 1 | 1;
for pt_i in 0..pt.len() {
let addr =
pdp_i as u64 * 0x4000_0000 +
pd_i as u64 * 0x20_0000 +
pt_i as u64 * 0x1000 +
kernel_phys;
pt[pt_i] = addr | 1 << 1 | 1;
}
}
}
}
Some(pml4.as_ptr() as u64)
}
+2 -2
View File
@@ -11,7 +11,7 @@ pub extern "C" fn rust_eh_personality() {}
#[panic_handler]
#[no_mangle]
pub extern "C" fn rust_begin_unwind(info: &PanicInfo) -> ! {
//println!("BOOTLOADER PANIC: {}", info);
log::error!("BOOTLOADER PANIC: {}", info);
loop {
unsafe {
llvm_asm!("hlt" : : : : "intel", "volatile");
@@ -23,7 +23,7 @@ pub extern "C" fn rust_begin_unwind(info: &PanicInfo) -> ! {
#[no_mangle]
#[allow(improper_ctypes_definitions)] // Layout is not repr(C)
pub extern fn rust_oom(_layout: Layout) -> ! {
panic!("kernel memory allocation failed");
panic!("memory allocation failed");
}
#[allow(non_snake_case)]