From e63febad96153e04c02b694a14bb1360e44ab9c9 Mon Sep 17 00:00:00 2001 From: 0x6D70 Date: Thu, 22 Feb 2024 20:25:18 +0100 Subject: [PATCH] improve elf loader --- xernel/kernel/src/main.rs | 8 ++++++++ xernel/kernel/src/mem/paging.rs | 3 +-- xernel/kernel/src/sched/thread.rs | 17 ++++++++++++++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/xernel/kernel/src/main.rs b/xernel/kernel/src/main.rs index 6b5eeb00..67a153e4 100644 --- a/xernel/kernel/src/main.rs +++ b/xernel/kernel/src/main.rs @@ -32,6 +32,7 @@ use alloc::string::ToString; use alloc::sync::Arc; use alloc::vec; use alloc::vec::Vec; +use x86_64::VirtAddr; use core::arch::asm; use core::panic::PanicInfo; use libxernel::sync::Spinlock; @@ -154,6 +155,13 @@ extern "C" fn kernel_main() -> ! { scheduler::init(); let process = Arc::new(Spinlock::new(Process::new(Some(KERNEL_PROCESS.clone())))); + dbg!("before pt load"); + unsafe { + process.lock().page_table.as_ref().unwrap().load_pt(); + dbg!("ffffffff80016140 => {:x}", KERNEL_PAGE_MAPPER.lock().translate(VirtAddr::new(0xffffffff80016140)).unwrap().as_u64()); + dbg!("ffffffff80016140 => {:x}", process.lock().page_table.as_ref().unwrap().translate(VirtAddr::new(0xffffffff80016140)).unwrap().as_u64()); + } + dbg!("after pt load"); let test_elf = include_bytes!("../test-elfloader"); let user_task = Thread::new_user_thread_from_elf(process.clone(), test_elf); diff --git a/xernel/kernel/src/mem/paging.rs b/xernel/kernel/src/mem/paging.rs index f6a1ea3a..cfe5c171 100644 --- a/xernel/kernel/src/mem/paging.rs +++ b/xernel/kernel/src/mem/paging.rs @@ -166,7 +166,6 @@ impl Pagemap { self.flush(virt.start_address()); } } - dbg!("end map"); } pub fn flush(&self, addr: VirtAddr) { @@ -296,7 +295,7 @@ impl Pagemap { } unsafe fn get_pt(pt: *mut PageTable, pt_index: PageTableIndex) -> *mut PageTable { - (*pt)[pt_index].addr().as_u64() as *mut PageTable + ((*pt)[pt_index].addr().as_u64() + *HIGHER_HALF_OFFSET) as *mut PageTable } /// Only works with 4KiB pages diff --git a/xernel/kernel/src/sched/thread.rs b/xernel/kernel/src/sched/thread.rs index fb392e34..f7e5fc80 100644 --- a/xernel/kernel/src/sched/thread.rs +++ b/xernel/kernel/src/sched/thread.rs @@ -3,6 +3,7 @@ use elf::abi::{ET_EXEC, PT_LOAD}; use elf::endian::LittleEndian; use elf::ElfBytes; use libxernel::sync::Spinlock; +use x86_64::registers::control::Cr3; use x86_64::structures::paging::{Page, PageSize, PageTableFlags, PhysFrame, Size4KiB}; use crate::allocator::align_up; @@ -202,7 +203,7 @@ impl Thread { for segment in segments { if segment.p_type == PT_LOAD { - dbg!("{:#x?}", segment); + dbg!("{:x?}", segment); let file_size = segment.p_filesz as usize; let mem_size = segment.p_memsz as usize; let vaddr = segment.p_vaddr as usize; @@ -220,7 +221,11 @@ impl Thread { let process = self.get_process().unwrap(); let process = process.lock(); - dbg!("before mapping"); + // we need to use the page table of the process to copy the content of the segment into the memory + assert!( + process.get_page_table().unwrap().pml4().as_u64() == Cr3::read().0.start_address().as_u64() + ); + process.get_page_table().unwrap().map( frame, page, @@ -230,13 +235,19 @@ impl Thread { | PageTableFlags::WRITABLE, // TODO: make this depend on the elf flags, currently we need it to write the content of the segment ==> make it read-only after writing true, ); - dbg!("after mapping"); unsafe { write_bytes(page.start_address().as_mut_ptr::(), 0, Size4KiB::SIZE as usize); } } + dbg!( + "{:x} - {:x}; executable: {}", + vaddr, + vaddr + file_size, + segment.p_flags & 1 == 1 + ); + unsafe { core::ptr::copy_nonoverlapping( elf_data.as_ptr().add(segment.p_offset as usize),