Load a very simple ELF and launch it in usermode

This commit is contained in:
Jeremy Soller 2016-09-07 21:16:30 -06:00
parent 398838dc1b
commit 850792bbf1
11 changed files with 201 additions and 59 deletions

View file

@ -60,6 +60,7 @@ pub unsafe fn init() {
// Set syscall function
IDT[0x80].set_func(syscall::syscall);
IDT[0x80].set_flags(IDT_PRESENT | IDT_RING_3 | IDT_INTERRUPT);
dtables::lidt(&IDTR);
}

View file

@ -1,22 +1,29 @@
#[naked]
pub unsafe extern fn syscall() {
extern {
fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> usize;
#[inline(never)]
unsafe fn inner() {
extern {
fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> usize;
}
let mut a;
{
let b;
let c;
let d;
let e;
let f;
asm!("xchg bx, bx" : "={rax}"(a), "={rbx}"(b), "={rcx}"(c), "={rdx}"(d), "={rsi}"(e), "={rdi}"(f)
: : : "intel", "volatile");
a = syscall(a, b, c, d, e, f);
}
asm!("xchg bx, bx" : : "{rax}"(a) : : "intel", "volatile");
}
let a;
let b;
let c;
let d;
let e;
let f;
asm!("" : "={rax}"(a), "={rbx}"(b), "={rcx}"(c), "={rdx}"(d), "={rsi}"(e), "={rdi}"(f)
: : : "intel", "volatile");
inner();
let a = syscall(a, b, c, d, e, f);
asm!("" : : "{rax}"(a) : : "intel", "volatile");
// Pop scratch registers, error code, and return
// Interrupt return
asm!("iretq" : : : : "intel", "volatile");
}

View file

@ -17,7 +17,7 @@ extern crate hole_list_allocator as allocator;
extern crate bitflags;
extern crate ransid;
extern crate spin;
extern crate x86;
pub extern crate x86;
/// Print to console
#[macro_export]

View file

@ -46,6 +46,15 @@ impl Mapper {
self.map_to(page, frame, flags)
}
/// Update flags for a page
pub fn remap(&mut self, page: Page, flags: EntryFlags) {
let mut p3 = self.p4_mut().next_table_mut(page.p4_index()).expect("failed to remap: no p3");
let mut p2 = p3.next_table_mut(page.p3_index()).expect("failed to remap: no p2");
let mut p1 = p2.next_table_mut(page.p2_index()).expect("failed to remap: no p1");
let frame = p1[page.p1_index()].pointed_frame().expect("failed to remap: not mapped");
p1[page.p1_index()].set(frame, flags | entry::PRESENT);
}
/// Identity map a frame
pub fn identity_map(&mut self, frame: Frame, flags: EntryFlags) {
let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));

View file

@ -66,7 +66,7 @@ impl<L> Table<L> where L: HierarchicalLevel {
assert!(!self[index].flags().contains(HUGE_PAGE),
"mapping code does not support huge pages");
let frame = allocate_frame().expect("no frames available");
self[index].set(frame, PRESENT | WRITABLE);
self[index].set(frame, PRESENT | WRITABLE | USER_ACCESSIBLE /* Allow users to go down the page table, implement permissions at the page level */);
self.next_table_mut(index).unwrap().zero();
}
self.next_table_mut(index).unwrap()

View file

@ -137,28 +137,6 @@ pub unsafe extern fn kstart() -> ! {
kmain();
}
unsafe fn usermode(ip: usize, sp: usize) {
// Test usermode
asm!("xchg bx, bx
mov rax, 0x2B
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
push rax
push rbx
pushfq
mov rax, 0x23
push rax
push rcx
iretq"
:
: "{rbx}"(sp), "{rcx}"(ip)
: "rax", "rbx", "rcx", "sp"
: "intel", "volatile");
}
/// Entry to rust for an AP
pub unsafe extern fn kstart_ap(stack_start: usize, stack_end: usize) -> ! {
{
@ -223,3 +201,25 @@ pub unsafe extern fn kstart_ap(stack_start: usize, stack_end: usize) -> ! {
kmain_ap(ap_number);
}
pub unsafe fn usermode(ip: usize, sp: usize) {
// Test usermode
asm!("xchg bx, bx
mov rax, 0x2B
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
push rax
push rbx
pushfq
mov rax, 0x23
push rax
push rcx
iretq"
:
: "{rbx}"(sp), "{rcx}"(ip)
: "rax", "rbx", "rcx", "sp"
: "intel", "volatile");
}