feat(boot): gatekeeper gates boot (init→UI→gatekeeper→data); keystore disk + virtio-rng discovery; terminal READ_SECRET; storage SET_KEY; PageCount ≤8192, alloc cap gone; device window 0x01D0_0000; test-qemu types passcode over 2 boots

This commit is contained in:
2026-10-27 23:43:47 +01:00
parent b7ef67ffd8
commit 3b7d004285
36 changed files with 455 additions and 74 deletions

View File

@@ -3,7 +3,6 @@ use core::cell::UnsafeCell;
use core::ptr;
const PAGE_SIZE: usize = 4096;
const MAX_PAGES: usize = 64;
struct FreeBlock {
size: usize,
@@ -14,10 +13,10 @@ pub struct KosAllocator {
inner: UnsafeCell<AllocatorInner>,
}
/// How much heap a process gets is its page budget's business (the kernel
/// enforces it), not the allocator's.
struct AllocatorInner {
free_list: *mut FreeBlock,
pages: [usize; MAX_PAGES],
page_count: usize,
}
unsafe impl Sync for KosAllocator {}
@@ -25,11 +24,7 @@ unsafe impl Sync for KosAllocator {}
impl KosAllocator {
pub const fn new() -> Self {
Self {
inner: UnsafeCell::new(AllocatorInner {
free_list: ptr::null_mut(),
pages: [0; MAX_PAGES],
page_count: 0,
}),
inner: UnsafeCell::new(AllocatorInner { free_list: ptr::null_mut() }),
}
}
@@ -41,19 +36,12 @@ impl KosAllocator {
impl AllocatorInner {
/// `n` pages in one piece, so an allocation larger than a page fits.
fn request_pages(&mut self, n: usize) -> *mut u8 {
if self.page_count + n > MAX_PAGES {
return ptr::null_mut();
}
let Some(count) = u16::try_from(n).ok().and_then(types::bounded::PageCount::new) else {
return ptr::null_mut();
};
let Some(va) = crate::syscall::request_pages(count) else {
return ptr::null_mut();
};
if let Some(slot) = self.pages.get_mut(self.page_count) {
*slot = va.raw();
}
self.page_count += n;
va.raw() as *mut u8
}

View File

@@ -6,9 +6,18 @@ use types::bounded::CapSlot;
/// Reads a typed line into `buf`, newline included if it fits; how much.
pub fn read_line(terminal: CapSlot, buf: &mut [u8]) -> usize {
read(terminal, types::terminal::READ, buf)
}
/// Reads a typed line without showing it (`*` for each character).
pub fn read_secret(terminal: CapSlot, buf: &mut [u8]) -> usize {
read(terminal, types::terminal::READ_SECRET, buf)
}
fn read(terminal: CapSlot, op: usize, buf: &mut [u8]) -> usize {
let mut n = 0;
while n < buf.len() {
let Ok(words) = syscall::request(terminal, [types::terminal::READ, 0, 0, 0]) else {
let Ok(words) = syscall::request(terminal, [op, 0, 0, 0]) else {
break;
};
let Some((bytes, len)) = types::log::text_of(words) else {