Add some long mode support
This commit is contained in:
+7
-1
@@ -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
|
||||
|
||||
@@ -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
@@ -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)]
|
||||
|
||||
Reference in New Issue
Block a user