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:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user