feat: room for many apps: qemu 512M, pool sized from RAM (448M, 114688 frames), user VA 32M -> 1G, display 8 windows (buffers at 0x1000_0000, stack 14 pages), pm app budget 24 MiB, init 16 children (notif bits moved)
This commit is contained in:
6
Makefile
6
Makefile
@@ -84,17 +84,17 @@ test-qemu: build
|
|||||||
SMP=$(SMP) scripts/test-qemu.sh test.img
|
SMP=$(SMP) scripts/test-qemu.sh test.img
|
||||||
|
|
||||||
run: build
|
run: build
|
||||||
qemu-system-riscv64 -machine virt -smp $(SMP) -nographic -bios default \
|
qemu-system-riscv64 -machine virt -m 512M -smp $(SMP) -nographic -bios default \
|
||||||
-kernel $(KERNEL_BIN)
|
-kernel $(KERNEL_BIN)
|
||||||
|
|
||||||
run-disk: image
|
run-disk: image
|
||||||
qemu-system-riscv64 -machine virt -smp $(SMP) -nographic -bios default \
|
qemu-system-riscv64 -machine virt -m 512M -smp $(SMP) -nographic -bios default \
|
||||||
-kernel $(KERNEL_BIN) \
|
-kernel $(KERNEL_BIN) \
|
||||||
-drive file=boot.img,if=none,format=raw,id=hd0 \
|
-drive file=boot.img,if=none,format=raw,id=hd0 \
|
||||||
-device virtio-blk-device,drive=hd0 $(QEMU_KEYS)
|
-device virtio-blk-device,drive=hd0 $(QEMU_KEYS)
|
||||||
|
|
||||||
run-gui: image
|
run-gui: image
|
||||||
qemu-system-riscv64 -machine virt -smp $(SMP) -bios default \
|
qemu-system-riscv64 -machine virt -m 512M -smp $(SMP) -bios default \
|
||||||
-kernel $(KERNEL_BIN) \
|
-kernel $(KERNEL_BIN) \
|
||||||
-drive file=boot.img,if=none,format=raw,id=hd0 \
|
-drive file=boot.img,if=none,format=raw,id=hd0 \
|
||||||
-device virtio-blk-device,drive=hd0 $(QEMU_KEYS) \
|
-device virtio-blk-device,drive=hd0 $(QEMU_KEYS) \
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
pub const RAM_BASE: usize = 0x80000000;
|
pub const RAM_BASE: usize = 0x80000000;
|
||||||
pub const RAM_SIZE: usize = 128 * 1024 * 1024;
|
/// What the Makefile and scripts give QEMU (`-m 512M`).
|
||||||
|
pub const RAM_SIZE: usize = 512 * 1024 * 1024;
|
||||||
pub const UART_BASE: usize = 0x10000000;
|
pub const UART_BASE: usize = 0x10000000;
|
||||||
pub const VIRTIO_BASE: usize = 0x10001000;
|
pub const VIRTIO_BASE: usize = 0x10001000;
|
||||||
pub const VIRTIO_SIZE: usize = 0x8000;
|
pub const VIRTIO_SIZE: usize = 0x8000;
|
||||||
pub const PLIC_BASE: usize = 0x0C000000;
|
pub const PLIC_BASE: usize = 0x0C000000;
|
||||||
pub const CLINT_BASE: usize = 0x02000000;
|
pub const CLINT_BASE: usize = 0x02000000;
|
||||||
pub const USER_POOL_BASE: usize = 0x84000000;
|
pub const USER_POOL_BASE: usize = 0x84000000;
|
||||||
/// 64 MiB, up to the end of RAM (QEMU virt's default 128 MiB).
|
/// The rest of RAM, from `USER_POOL_BASE` (448 MiB).
|
||||||
pub const USER_POOL_PAGES: usize = 16384;
|
pub const USER_POOL_PAGES: usize = (RAM_BASE + RAM_SIZE - USER_POOL_BASE) / 4096;
|
||||||
pub const TICK_INTERVAL: u64 = 10_000_000;
|
pub const TICK_INTERVAL: u64 = 10_000_000;
|
||||||
|
|
||||||
/// QEMU virt's PLIC lines.
|
/// QEMU virt's PLIC lines.
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
use super::pte::{PAGE_SIZE, PageTable, PageTableEntry, Sv39Flags, table_at, vpn};
|
use super::pte::{PAGE_SIZE, PageTable, PageTableEntry, Sv39Flags, table_at, vpn};
|
||||||
use platform::{FrameSource, MapError};
|
use platform::{FrameSource, MapError};
|
||||||
|
|
||||||
/// User mappings live in root slot 0, in a private L1 per address space.
|
/// User mappings live in root slot 0, in a private L1 per address space:
|
||||||
|
/// all of its 1 GiB (leaf tables are made as pages are mapped).
|
||||||
pub const USER_VA_START: usize = 0x1000;
|
pub const USER_VA_START: usize = 0x1000;
|
||||||
pub const USER_VA_END: usize = 0x0200_0000;
|
pub const USER_VA_END: usize = 0x4000_0000;
|
||||||
|
|
||||||
fn fresh_table(frames: &mut dyn FrameSource) -> Result<usize, MapError> {
|
fn fresh_table(frames: &mut dyn FrameSource) -> Result<usize, MapError> {
|
||||||
let pa = frames
|
let pa = frames
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const INPUT: CapSlot = CapSlot::const_new(1);
|
|||||||
/// `themes/`, read-only.
|
/// `themes/`, read-only.
|
||||||
const THEMES: CapSlot = CapSlot::const_new(2);
|
const THEMES: CapSlot = CapSlot::const_new(2);
|
||||||
/// Where storage's buffer is mapped while the themes are read.
|
/// Where storage's buffer is mapped while the themes are read.
|
||||||
const STORAGE_BUF_VA: types::address::VirtualAddress = types::address::VirtualAddress::from_raw(0x0180_0000);
|
const STORAGE_BUF_VA: types::address::VirtualAddress = types::address::VirtualAddress::from_raw(0x1800_0000);
|
||||||
/// The longest theme file read.
|
/// The longest theme file read.
|
||||||
const THEME_BYTES: usize = 4096;
|
const THEME_BYTES: usize = 4096;
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ mod proofs;
|
|||||||
pub const PAGE_SIZE: usize = 4096;
|
pub const PAGE_SIZE: usize = 4096;
|
||||||
|
|
||||||
/// Frames the kernel can track. The board's user pool must fit.
|
/// Frames the kernel can track. The board's user pool must fit.
|
||||||
pub const MAX_FRAMES: usize = if cfg!(kani) { 6 } else { 16384 };
|
pub const MAX_FRAMES: usize = if cfg!(kani) { 6 } else { 114_688 };
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum FrameUse {
|
pub enum FrameUse {
|
||||||
|
|||||||
@@ -115,11 +115,12 @@ pub const SERVERS: &[Program] = &[
|
|||||||
storage: &[disk(b"themes", false)],
|
storage: &[disk(b"themes", false)],
|
||||||
// Its clients subscribe and take focus.
|
// Its clients subscribe and take focus.
|
||||||
restarts_clients: true,
|
restarts_clients: true,
|
||||||
// Its windows' state (input queues among it) is KiBs.
|
// Its windows' state (input queues among it) is ~10 KiB, and the
|
||||||
stack_pages: 8,
|
// server is built on the stack.
|
||||||
|
stack_pages: 14,
|
||||||
// The framebuffer is ~1000 pages at 1280x800, and so is each of
|
// The framebuffer is ~1000 pages at 1280x800, and so is each of
|
||||||
// the (at most 4) windows' pixel buffers, which it owns.
|
// the (at most 8) windows' pixel buffers, which it owns.
|
||||||
..server("display", b"bin/display", Limits { pages: 5200, regions: 9, ..SMALL })
|
..server("display", b"bin/display", Limits { pages: 9300, regions: 13, ..SMALL })
|
||||||
},
|
},
|
||||||
// Text on the display, lines from the keyboard (it takes input focus).
|
// Text on the display, lines from the keyboard (it takes input focus).
|
||||||
// Its clients wait on lines and Ctrl+C. It draws its own text now,
|
// Its clients wait on lines and Ctrl+C. It draws its own text now,
|
||||||
@@ -149,8 +150,8 @@ pub const GATEKEEPER: Program = Program {
|
|||||||
pub const SESSION: &[Program] = &[Program {
|
pub const SESSION: &[Program] = &[Program {
|
||||||
uses: &["terminal", "display"],
|
uses: &["terminal", "display"],
|
||||||
storage: &[users(b"", true), disk(b"apps", false)],
|
storage: &[users(b"", true), disk(b"apps", false)],
|
||||||
// Room for a few apps at a time.
|
// Room for several apps at a time (24 MiB between them).
|
||||||
spawns: Some(Limits { pages: 2048, endpoints: 8, notifications: 8, regions: 8 }),
|
spawns: Some(Limits { pages: 6144, endpoints: 12, notifications: 12, regions: 12 }),
|
||||||
// The shell holds handles to the apps it ran, which die with it.
|
// The shell holds handles to the apps it ran, which die with it.
|
||||||
restarts_clients: true,
|
restarts_clients: true,
|
||||||
session: Session::PassOn,
|
session: Session::PassOn,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use crate::load;
|
|||||||
|
|
||||||
pub(crate) const MAX_CLIENTS: usize = 4;
|
pub(crate) const MAX_CLIENTS: usize = 4;
|
||||||
/// Death signals carry the child's index as a bit.
|
/// Death signals carry the child's index as a bit.
|
||||||
const MAX_CHILDREN: usize = 8;
|
pub(crate) const MAX_CHILDREN: usize = 16;
|
||||||
|
|
||||||
struct Child {
|
struct Child {
|
||||||
client: usize,
|
client: usize,
|
||||||
|
|||||||
@@ -25,8 +25,11 @@ use crate::watchdog;
|
|||||||
pub(crate) const MAX_SUPERVISED: usize = 12;
|
pub(crate) const MAX_SUPERVISED: usize = 12;
|
||||||
/// Init's death notification: spawned children below, storage, then a bit
|
/// Init's death notification: spawned children below, storage, then a bit
|
||||||
/// per supervised program, and the timer on top.
|
/// per supervised program, and the timer on top.
|
||||||
const FIRST_BIT: usize = 16;
|
const FIRST_BIT: usize = 17;
|
||||||
const STORAGE_BIT: usize = 1 << 15;
|
const STORAGE_BIT: usize = 1 << 16;
|
||||||
|
// Spawned children take the bits below storage's; supervised programs
|
||||||
|
// those above it, clear of the timer's.
|
||||||
|
const _: () = assert!(crate::spawn::MAX_CHILDREN <= 16 && FIRST_BIT + MAX_SUPERVISED < 62);
|
||||||
pub(crate) const TIMER_BIT: usize = 1 << 62;
|
pub(crate) const TIMER_BIT: usize = 1 << 62;
|
||||||
/// Where boot left storage's process.
|
/// Where boot left storage's process.
|
||||||
const STORAGE_PROCESS: CapSlot = CapSlot::const_new(1);
|
const STORAGE_PROCESS: CapSlot = CapSlot::const_new(1);
|
||||||
|
|||||||
@@ -13,8 +13,9 @@ use crate::server::Host;
|
|||||||
use crate::windows::MAX_WINDOWS;
|
use crate::windows::MAX_WINDOWS;
|
||||||
|
|
||||||
/// Where slot `i`'s buffer is mapped in the display: 4 MiB apart, room for
|
/// Where slot `i`'s buffer is mapped in the display: 4 MiB apart, room for
|
||||||
/// a 1280x800 window.
|
/// a 1280x800 window; high, clear of the GPU's mappings and of the heap,
|
||||||
const BUFFERS_VA: usize = 0x0080_0000;
|
/// which grows from the bottom.
|
||||||
|
const BUFFERS_VA: usize = 0x1000_0000;
|
||||||
const BUFFER_SPAN: usize = 0x0040_0000;
|
const BUFFER_SPAN: usize = 0x0040_0000;
|
||||||
const PAGE: usize = 4096;
|
const PAGE: usize = 4096;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
use types::display::window::{BADGE, NAME_BYTES};
|
use types::display::window::{BADGE, NAME_BYTES};
|
||||||
|
|
||||||
pub const MAX_WINDOWS: usize = 4;
|
pub const MAX_WINDOWS: usize = 8;
|
||||||
/// Events received and not yet polled by the window in front.
|
/// Events received and not yet polled by the window in front.
|
||||||
const QUEUED: usize = 32;
|
const QUEUED: usize = 32;
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ owner() {
|
|||||||
boot() {
|
boot() {
|
||||||
: > "${LOG}"; rm -f "${MON}"
|
: > "${LOG}"; rm -f "${MON}"
|
||||||
owner "$@" &
|
owner "$@" &
|
||||||
timeout ${QT:-120} qemu-system-riscv64 -machine virt -smp "${SMP}" -bios default \
|
timeout ${QT:-120} qemu-system-riscv64 -machine virt -m 512M -smp "${SMP}" -bios default \
|
||||||
-kernel "${KERNEL}" \
|
-kernel "${KERNEL}" \
|
||||||
-drive "file=${IMAGE},if=none,format=raw,id=hd0" -device virtio-blk-device,drive=hd0 \
|
-drive "file=${IMAGE},if=none,format=raw,id=hd0" -device virtio-blk-device,drive=hd0 \
|
||||||
-drive "file=${KEYS},if=none,format=raw,id=ks" -device virtio-blk-device,drive=ks \
|
-drive "file=${KEYS},if=none,format=raw,id=ks" -device virtio-blk-device,drive=ks \
|
||||||
|
|||||||
Reference in New Issue
Block a user