feat(adapter): init+storage packed into kernel image; drop adapter FAT16 reader + virtio-blk
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
use crate::hw::uart::Uart;
|
||||
use crate::hw::virtio_blk::VirtioBlk;
|
||||
use crate::{boot_fs, mmu};
|
||||
use crate::mmu;
|
||||
use types::address::VirtualAddress;
|
||||
use types::budget::Limits;
|
||||
use types::id::{ProcessId, ThreadId};
|
||||
@@ -10,7 +9,6 @@ const PAGE_SIZE: usize = mmu::PAGE_SIZE;
|
||||
const USER_VA_BASE: usize = 0x10000;
|
||||
/// The stack sits just below the image and stops short of the null page.
|
||||
const USER_STACK_PAGES: usize = USER_VA_BASE / PAGE_SIZE - 1;
|
||||
const MAX_FILE_SIZE: usize = 64 * 1024;
|
||||
|
||||
pub struct LoadedProcess {
|
||||
pub pid: ProcessId,
|
||||
@@ -20,23 +18,11 @@ fn kern() -> &'static mut kernel::Kernel<crate::platform::RiscVPlatform> {
|
||||
unsafe { &mut *crate::kernel_ptr() }
|
||||
}
|
||||
|
||||
/// Scratch space for reading ELF files, allocated once from the boot heap.
|
||||
fn elf_buffer() -> &'static mut [u8] {
|
||||
static mut BUF: usize = 0;
|
||||
// SAFETY: boot is single threaded; the buffer is kernel-only memory
|
||||
// from the boot allocator and is never handed to a process.
|
||||
unsafe {
|
||||
if BUF == 0 {
|
||||
BUF = mmu::allocator::alloc_zeroed_page();
|
||||
for _ in 1..MAX_FILE_SIZE / PAGE_SIZE {
|
||||
mmu::allocator::alloc_zeroed_page();
|
||||
}
|
||||
}
|
||||
core::slice::from_raw_parts_mut(BUF as *mut u8, MAX_FILE_SIZE)
|
||||
}
|
||||
}
|
||||
/// The two programs boot starts, packed into the kernel image.
|
||||
pub static INIT_ELF: &[u8] = include_bytes!(env!("KOS_INIT_ELF"));
|
||||
pub static STORAGE_ELF: &[u8] = include_bytes!(env!("KOS_STORAGE_ELF"));
|
||||
|
||||
pub fn load_init(uart: &Uart, blk: &mut VirtioBlk) -> LoadedProcess {
|
||||
pub fn load_init(uart: &Uart) -> LoadedProcess {
|
||||
let (pid, tid) = kern()
|
||||
.boot(
|
||||
types::bounded::Priority::DEFAULT,
|
||||
@@ -44,7 +30,7 @@ pub fn load_init(uart: &Uart, blk: &mut VirtioBlk) -> LoadedProcess {
|
||||
)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "boot failed"));
|
||||
|
||||
let entry = load_elf(uart, blk, pid, b"init.elf");
|
||||
let entry = load_elf(uart, pid, INIT_ELF);
|
||||
setup_thread(tid, entry);
|
||||
uart.write_str("k-os: init loaded\n");
|
||||
|
||||
@@ -60,24 +46,18 @@ const STORAGE: Limits = Limits {
|
||||
regions: 12,
|
||||
};
|
||||
|
||||
pub fn load_server(
|
||||
uart: &Uart,
|
||||
blk: &mut VirtioBlk,
|
||||
init: ProcessId,
|
||||
filename: &[u8],
|
||||
label: &str,
|
||||
) -> LoadedProcess {
|
||||
/// Storage, which init needs to read anything else, its budget carved
|
||||
/// from init's.
|
||||
pub fn load_storage(uart: &Uart, init: ProcessId) -> LoadedProcess {
|
||||
let pid = kern()
|
||||
.create_process_internal(init, STORAGE)
|
||||
.unwrap_or_else(|| crate::halt(uart, "process create failed"));
|
||||
let entry = load_elf(uart, blk, pid, filename);
|
||||
let entry = load_elf(uart, pid, STORAGE_ELF);
|
||||
let tid = kern()
|
||||
.spawn_thread_internal(pid)
|
||||
.unwrap_or_else(|| crate::halt(uart, "thread spawn failed"));
|
||||
setup_thread(tid, entry);
|
||||
uart.write_str("k-os: ");
|
||||
uart.write_str(label);
|
||||
uart.write_str(" loaded\n");
|
||||
uart.write_str("k-os: storage loaded\n");
|
||||
|
||||
LoadedProcess { pid }
|
||||
}
|
||||
@@ -127,13 +107,10 @@ fn segment_perms(flags: elf::SegmentFlags) -> Option<PagePerms> {
|
||||
/// Loads `filename` into `pid` through the kernel's own mapping API, so
|
||||
/// every page is tracked, charged and checked like any other. Halts on any
|
||||
/// malformed or overlapping image: boot servers are trusted to be sane.
|
||||
fn load_elf(uart: &Uart, blk: &mut VirtioBlk, pid: ProcessId, filename: &[u8]) -> usize {
|
||||
let buf = elf_buffer();
|
||||
let file_size = boot_fs::read_file_from_disk(blk, filename, buf).unwrap_or(0);
|
||||
if file_size == 0 {
|
||||
crate::halt(uart, "ELF not found");
|
||||
fn load_elf(uart: &Uart, pid: ProcessId, file: &[u8]) -> usize {
|
||||
if file.is_empty() {
|
||||
crate::halt(uart, "program missing from the kernel image (make build)");
|
||||
}
|
||||
let file = &buf[..file_size];
|
||||
let elf_info = elf::parse(file).unwrap_or_else(|_| crate::halt(uart, "bad ELF"));
|
||||
|
||||
for segment in elf_info.segments() {
|
||||
|
||||
Reference in New Issue
Block a user