Support embedding bootstrap blob into the initfs
This commit is contained in:
+2
-1
@@ -2,7 +2,8 @@ ENTRY(_start)
|
||||
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
|
||||
|
||||
SECTIONS {
|
||||
. = 0;
|
||||
. = 4096 + 4096; /* Reserved for the null page and the initfs header prepended by redox-initfs-ar */
|
||||
__initfs_header = . - 4096;
|
||||
. += SIZEOF_HEADERS;
|
||||
. = ALIGN(4096);
|
||||
|
||||
|
||||
+12
-7
@@ -7,7 +7,7 @@ use syscall::flag::{O_CLOEXEC, O_RDONLY};
|
||||
use redox_exec::*;
|
||||
|
||||
pub fn main() -> ! {
|
||||
let (initfs_offset, initfs_length);
|
||||
let initfs_length;
|
||||
|
||||
let envs = {
|
||||
let mut env = [0_u8; 4096];
|
||||
@@ -23,7 +23,6 @@ pub fn main() -> ! {
|
||||
|
||||
let raw_iter = || env.split(|c| *c == b'\n').filter(|var| !var.is_empty());
|
||||
|
||||
let mut initfs_offset_opt = None;
|
||||
let mut initfs_length_opt = None;
|
||||
|
||||
for var in raw_iter() {
|
||||
@@ -32,21 +31,27 @@ pub fn main() -> ! {
|
||||
let value = &var[equal_sign + 1..];
|
||||
|
||||
match name {
|
||||
b"INITFS_OFFSET" => initfs_offset_opt = core::str::from_utf8(value).ok().and_then(|s| usize::from_str_radix(s, 16).ok()),
|
||||
b"INITFS_LENGTH" => initfs_length_opt = core::str::from_utf8(value).ok().and_then(|s| usize::from_str_radix(s, 16).ok()),
|
||||
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
initfs_offset = initfs_offset_opt.expect("missing INITFS_OFFSET");
|
||||
initfs_length = initfs_length_opt.expect("missing INITFS_LENGTH");
|
||||
|
||||
let iter = || raw_iter().filter(|var| !var.starts_with(b"INITFS_"));
|
||||
|
||||
iter().map(|var| var.to_owned()).collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
extern {
|
||||
// The linker script will define this as the location of the initfs header.
|
||||
static __initfs_header: u8;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
spawn_initfs(initfs_offset, initfs_length);
|
||||
// Creating a reference to NULL is UB. Mask the UB for now using black_box.
|
||||
// FIXME use a raw pointer and inline asm for reading instead for the initfs header.
|
||||
spawn_initfs(core::ptr::addr_of!(__initfs_header), initfs_length);
|
||||
}
|
||||
const CWD: &[u8] = b"/scheme/initfs";
|
||||
let extrainfo = redox_exec::ExtraInfo {
|
||||
@@ -65,7 +70,7 @@ pub fn main() -> ! {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
unsafe fn spawn_initfs(initfs_start: usize, initfs_length: usize) {
|
||||
unsafe fn spawn_initfs(initfs_start: *const u8, initfs_length: usize) {
|
||||
let read = syscall::open("pipe:", O_CLOEXEC).expect("failed to open sync read pipe");
|
||||
|
||||
// The write pipe will not inherit O_CLOEXEC, but is closed by the daemon later.
|
||||
@@ -92,5 +97,5 @@ unsafe fn spawn_initfs(initfs_start: usize, initfs_length: usize) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
crate::initfs::run(core::slice::from_raw_parts(initfs_start as *const u8, initfs_length), write);
|
||||
crate::initfs::run(core::slice::from_raw_parts(initfs_start, initfs_length), write);
|
||||
}
|
||||
|
||||
+2
-1
@@ -2,7 +2,8 @@ ENTRY(_start)
|
||||
OUTPUT_FORMAT(elf32-i386)
|
||||
|
||||
SECTIONS {
|
||||
. = 0;
|
||||
. = 4096 + 4096; /* Reserved for the null page and the initfs header prepended by redox-initfs-ar */
|
||||
__initfs_header = . - 4096;
|
||||
. += SIZEOF_HEADERS;
|
||||
. = ALIGN(4096);
|
||||
|
||||
|
||||
+3
-2
@@ -35,13 +35,14 @@ pub unsafe extern "C" fn start() -> ! {
|
||||
let _ = syscall::open("debug:", syscall::O_WRONLY); // stdout
|
||||
let _ = syscall::open("debug:", syscall::O_WRONLY); // stderr
|
||||
|
||||
// TODO: PROT_NONE
|
||||
let _ = syscall::mprotect(0, 4096, MapFlags::PROT_READ | MapFlags::MAP_PRIVATE).expect("mprotect failed for NULL page");
|
||||
let _ = syscall::mprotect(4096, 4096, MapFlags::PROT_READ | MapFlags::MAP_PRIVATE).expect("mprotect failed for initfs header page");
|
||||
|
||||
let _ = syscall::mprotect(text_start, text_end - text_start, MapFlags::PROT_READ | MapFlags::PROT_EXEC | MapFlags::MAP_PRIVATE).expect("mprotect failed for .text");
|
||||
let _ = syscall::mprotect(rodata_start, rodata_end - rodata_start, MapFlags::PROT_READ | MapFlags::MAP_PRIVATE).expect("mprotect failed for .rodata");
|
||||
let _ = syscall::mprotect(data_start, data_end - data_start, MapFlags::PROT_READ | MapFlags::PROT_WRITE | MapFlags::MAP_PRIVATE).expect("mprotect failed for .data/.bss");
|
||||
let _ = syscall::mprotect(data_end, crate::arch::STACK_START - data_end, MapFlags::PROT_READ | MapFlags::MAP_PRIVATE).expect("mprotect failed for rest of memory");
|
||||
|
||||
// FIXME make the initfs read-only
|
||||
|
||||
crate::exec::main();
|
||||
}
|
||||
|
||||
+2
-1
@@ -2,7 +2,8 @@ ENTRY(_start)
|
||||
OUTPUT_FORMAT(elf64-x86-64)
|
||||
|
||||
SECTIONS {
|
||||
. = 0;
|
||||
. = 4096 + 4096; /* Reserved for the null page and the initfs header prepended by redox-initfs-ar */
|
||||
__initfs_header = . - 4096;
|
||||
. += SIZEOF_HEADERS;
|
||||
. = ALIGN(4096);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user