diff --git a/src/lib.rs b/src/lib.rs index b4ca55ac9c..1186760eae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,21 @@ #![no_std] -#![feature(alloc_error_handler, core_intrinsics, lang_items, panic_info_message)] +#![feature( + asm_const, + asm_sym, + alloc_error_handler, + core_intrinsics, + lang_items, + naked_functions, + panic_info_message +)] + +#[cfg(target_arch = "x86")] +#[path = "i686.rs"] +pub mod arch; + +#[cfg(target_arch = "x86_64")] +#[path = "x86_64.rs"] +pub mod arch; pub mod exec; pub mod initfs; diff --git a/src/x86_64.asm b/src/x86_64.asm deleted file mode 100644 index e8e49136c8..0000000000 --- a/src/x86_64.asm +++ /dev/null @@ -1,42 +0,0 @@ -BITS 64 - -section .text - -global ustart -extern start - -ustart: - ; Setup a stack. - mov rax, 0x21000384 ; SYS_CLASS_FILE+SYS_ARG_SLICE+SYS_MMAP - mov rdi, 0xFFFFFFFFFFFFFFFF ; dummy `fd`, indicates anonymous map - mov rsi, map ; pointer to Map struct - mov rdx, map_size ; size of Map struct - syscall - - ; Test for success (nonzero value). - cmp rax, 0 - jg .continue - ; (failure) - ud2 -.continue: - ; Subtract 16 since all instructions seem to hate non-canonical RSP values :) - lea rsp, [rax+size-16] - mov rbp, rsp - - ; Stack has the same alignment as `size`. - call start - ; `start` must never return. - ud2 - -section .rodata -map: - dq 0 ; offset (unused) - dq size - dq flags - dq address - size - -map_size equ $ - map - -size equ 65536 ; 64 KiB -address equ 0x0000800000000000 ; highest possible (normal) user address, why not -flags equ 0x0006000E ; PROT_READ+PROT_WRITE, MAP_PRIVATE+MAP_FIXED_NOREPLACE diff --git a/src/x86_64.rs b/src/x86_64.rs new file mode 100644 index 0000000000..f90f651ed8 --- /dev/null +++ b/src/x86_64.rs @@ -0,0 +1,53 @@ +use core::mem; +use syscall::{ + data::Map, + flag::MapFlags, + number::SYS_FMAP, +}; + +const STACK_SIZE: usize = 64 * 1024; // 64 KiB +static MAP: Map = Map { + offset: 0, + size: STACK_SIZE, + flags: MapFlags::PROT_READ + .union(MapFlags::PROT_WRITE) + .union(MapFlags::MAP_PRIVATE) + .union(MapFlags::MAP_FIXED_NOREPLACE), + address: 0x0000_8000_0000_0000 - STACK_SIZE, // highest possible user address +}; + +#[naked] +#[no_mangle] +pub unsafe extern "C" fn ustart() { + core::arch::asm!( + " + # Setup a stack. + mov rax, {number} + mov rdi, {fd} + lea rsi, {map} # pointer to Map struct + mov rdx, {map_size} # size of Map struct + syscall + + # Test for success (nonzero value). + cmp rax, 0 + jg 1f + # (failure) + ud2 + 1: + # Subtract 16 since all instructions seem to hate non-canonical RSP values :) + lea rsp, [rax+{stack_size}-16] + mov rbp, rsp + + # Stack has the same alignment as `size`. + call start + # `start` must never return. + ud2 + ", + fd = const usize::MAX, // dummy fd indicates anonymous map + map = sym MAP, + map_size = const mem::size_of::(), + number = const SYS_FMAP, + stack_size = const STACK_SIZE, + options(noreturn), + ); +} \ No newline at end of file