Reduce complexity of arch-specific assembly
This commit is contained in:
+17
-1
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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::<Map>(),
|
||||
number = const SYS_FMAP,
|
||||
stack_size = const STACK_SIZE,
|
||||
options(noreturn),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user