refactor: unsafe only in adapter + libkos; forbid(unsafe_code) everywhere else; libkos Window (volatile, bounds-checked MMIO/DMA/shared mem), entry!, thread::spawn; MapRegion returns pages; kernel const-built (with_cores/install_platform); newtype addrs
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
//! Prints files: `cat <file>...`.
|
||||
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
#![no_main]
|
||||
|
||||
extern crate libkos;
|
||||
@@ -9,7 +10,7 @@ use libkos::fs::{FsError, Storage};
|
||||
use libkos::println;
|
||||
|
||||
/// Where storage's buffer is mapped.
|
||||
const STORAGE_BUF_VA: usize = 0x0180_0000;
|
||||
const STORAGE_BUF_VA: types::address::VirtualAddress = types::address::VirtualAddress::from_raw(0x0180_0000);
|
||||
|
||||
fn cat(fs: &mut Storage, path: &str) -> Result<(), FsError> {
|
||||
let h = fs.open(path.as_bytes())?;
|
||||
@@ -24,8 +25,9 @@ fn cat(fs: &mut Storage, path: &str) -> Result<(), FsError> {
|
||||
fs.close(h)
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn main() {
|
||||
libkos::entry!(main);
|
||||
|
||||
fn main() {
|
||||
let Some(mut fs) = libkos::start::storage().and_then(|ep| Storage::attach(ep, STORAGE_BUF_VA).ok()) else {
|
||||
println!("cat: no storage");
|
||||
return;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
#![no_main]
|
||||
|
||||
extern crate libkos;
|
||||
@@ -6,8 +7,9 @@ extern crate libkos;
|
||||
use types::bounded::CapSlot;
|
||||
use libkos::syscall;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn main() {
|
||||
libkos::entry!(main);
|
||||
|
||||
fn main() {
|
||||
let ep = CapSlot::const_new(0);
|
||||
|
||||
if let Ok(syscall::Received::Call { words: [w0, w1, w2, w3], .. }) = syscall::receive_msg(ep) {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
#![no_main]
|
||||
|
||||
extern crate libkos;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn main() {
|
||||
libkos::entry!(main);
|
||||
|
||||
fn main() {
|
||||
libkos::println!("Hello from k-os!");
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! Lists a directory: `ls [dir]`, the root by default.
|
||||
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
#![no_main]
|
||||
|
||||
extern crate libkos;
|
||||
@@ -9,10 +10,11 @@ use libkos::fs::{FsError, Storage};
|
||||
use libkos::println;
|
||||
|
||||
/// Where storage's buffer is mapped.
|
||||
const STORAGE_BUF_VA: usize = 0x0180_0000;
|
||||
const STORAGE_BUF_VA: types::address::VirtualAddress = types::address::VirtualAddress::from_raw(0x0180_0000);
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn main() {
|
||||
libkos::entry!(main);
|
||||
|
||||
fn main() {
|
||||
let Some(mut fs) = libkos::start::storage().and_then(|ep| Storage::attach(ep, STORAGE_BUF_VA).ok()) else {
|
||||
println!("ls: no storage");
|
||||
return;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
//! then waits for it (Ctrl+C kills it) and takes the storage back.
|
||||
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
#![no_main]
|
||||
|
||||
extern crate libkos;
|
||||
@@ -35,7 +36,7 @@ const MAX_MANIFEST: usize = 512;
|
||||
const PROGRAM: Limits = Limits { pages: 128, endpoints: 1, notifications: 1, regions: 1 };
|
||||
const MAX_ARGS: usize = 16;
|
||||
/// Where storage's buffer is mapped.
|
||||
const STORAGE_BUF_VA: usize = 0x0180_0000;
|
||||
const STORAGE_BUF_VA: types::address::VirtualAddress = types::address::VirtualAddress::from_raw(0x0180_0000);
|
||||
|
||||
/// The current directory, as a path on disk: no leading or trailing `/`.
|
||||
struct Cwd {
|
||||
@@ -227,8 +228,9 @@ impl core::fmt::Display for Joined<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn main() {
|
||||
libkos::entry!(main);
|
||||
|
||||
fn main() {
|
||||
// Everything this shell prints goes to the terminal.
|
||||
libkos::start::set_log(Some(TERMINAL));
|
||||
let Ok(done) = syscall::create_notification() else {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! Waits: `sleep <seconds>`. Mostly something to stop with Ctrl+C.
|
||||
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
#![no_main]
|
||||
|
||||
extern crate libkos;
|
||||
@@ -11,8 +12,9 @@ use types::time::Ticks;
|
||||
/// QEMU virt's timebase.
|
||||
const TICKS_PER_SECOND: u64 = 10_000_000;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn main() {
|
||||
libkos::entry!(main);
|
||||
|
||||
fn main() {
|
||||
let Some(seconds) = libkos::start::args().nth(1).and_then(|s| s.parse::<u64>().ok()) else {
|
||||
println!("usage: sleep <seconds>");
|
||||
return;
|
||||
|
||||
@@ -3,44 +3,43 @@
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
extern crate libkos;
|
||||
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use libkos::syscall;
|
||||
use types::address::{EntryPoint, StackPointer, VirtualAddress};
|
||||
use types::bounded::{CapSlot, PageCount};
|
||||
use types::address::VirtualAddress;
|
||||
use types::bounded::CapSlot;
|
||||
use types::mapping::PagePerms;
|
||||
|
||||
/// Counter page layout (words): 0 next free counter index, 1..=THREADS counters.
|
||||
const COUNTERS_VA: usize = 0x0100_0000;
|
||||
const COUNTERS_VA: VirtualAddress = VirtualAddress::from_raw(0x0100_0000);
|
||||
const THREADS: usize = 4;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn main() {
|
||||
fn main() {
|
||||
let page = CapSlot::const_new(0);
|
||||
if syscall::map_region(page, VirtualAddress::from_raw(COUNTERS_VA), PagePerms::ReadWrite).is_err() {
|
||||
let Ok(window) = libkos::window::map(page, COUNTERS_VA, PagePerms::ReadWrite) else {
|
||||
libkos::println!("smptest: cannot map the counter page");
|
||||
syscall::exit();
|
||||
}
|
||||
};
|
||||
let words = window.atomics(0, 1 + THREADS);
|
||||
for _ in 1..THREADS {
|
||||
let Some(stack) = PageCount::new(1).and_then(syscall::request_pages) else {
|
||||
if !libkos::thread::spawn(words, spin) {
|
||||
break;
|
||||
};
|
||||
let top = StackPointer::from_raw(stack.raw() + 4096);
|
||||
syscall::spawn_thread(EntryPoint::from_raw(spin as *const () as usize), top, 0);
|
||||
}
|
||||
}
|
||||
spin();
|
||||
spin(words);
|
||||
}
|
||||
|
||||
extern "C" fn spin() -> ! {
|
||||
// SAFETY: COUNTERS_VA maps the counter page; every access is atomic.
|
||||
let word = |i: usize| unsafe { &*((COUNTERS_VA + i * 8) as *const AtomicUsize) };
|
||||
let mine = 1 + word(0).fetch_add(1, Ordering::Relaxed) % THREADS;
|
||||
libkos::entry!(main);
|
||||
|
||||
fn spin(word: &'static [AtomicUsize]) -> ! {
|
||||
let mine = 1 + word[0].fetch_add(1, Ordering::Relaxed) % THREADS;
|
||||
loop {
|
||||
// Yield so a spinner sharing init's hart cannot starve it.
|
||||
for _ in 0..1024 {
|
||||
word(mine).fetch_add(1, Ordering::Relaxed);
|
||||
word[mine].fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
syscall::yield_now();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
pub mod game;
|
||||
pub mod renderer;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
#![no_main]
|
||||
|
||||
extern crate libkos;
|
||||
@@ -39,8 +40,9 @@ fn flush() {
|
||||
display_send(&DisplayRequest::Flush);
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn main() {
|
||||
libkos::entry!(main);
|
||||
|
||||
fn main() {
|
||||
if libkos::start::display().is_none() {
|
||||
libkos::println!("snake: needs the display (see /bin/snake.manifest)");
|
||||
return;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
//! a child dies. Reports the whole self-test and halts.
|
||||
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
#![no_main]
|
||||
|
||||
extern crate libkos;
|
||||
@@ -19,8 +20,8 @@ const STORAGE: CapSlot = CapSlot::const_new(0);
|
||||
const INIT: CapSlot = CapSlot::const_new(1);
|
||||
const CONTROL: CapSlot = CapSlot::const_new(2);
|
||||
/// Where storage's buffers are mapped: the whole disk's, a narrowed one's.
|
||||
const STORAGE_BUF_VA: usize = 0x0180_0000;
|
||||
const NARROW_BUF_VA: usize = 0x0190_0000;
|
||||
const STORAGE_BUF_VA: types::address::VirtualAddress = types::address::VirtualAddress::from_raw(0x0180_0000);
|
||||
const NARROW_BUF_VA: types::address::VirtualAddress = types::address::VirtualAddress::from_raw(0x0190_0000);
|
||||
/// Read back from the disk image by scripts/test-qemu.sh.
|
||||
const NOTE: &[u8] = b"written by k-os on ext4\n";
|
||||
|
||||
@@ -73,7 +74,7 @@ fn narrow_storage(fs: &mut Storage, died: CapSlot) -> Result<(), &'static str> {
|
||||
if inner.create(b"x").err() != Some(FsError::Denied) {
|
||||
return Err("a read-only grant created a file");
|
||||
}
|
||||
let widened = inner.grant(b"", true).and_then(|g| Storage::attach(g, NARROW_BUF_VA + 0x10_0000));
|
||||
let widened = inner.grant(b"", true).and_then(|g| Storage::attach(g, types::address::VirtualAddress::from_raw(NARROW_BUF_VA.raw() + 0x10_0000)));
|
||||
if widened.and_then(|mut w| w.create(b"x")).is_ok() {
|
||||
return Err("a grant was widened to write");
|
||||
}
|
||||
@@ -112,8 +113,9 @@ fn check() -> Result<(), &'static str> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn main() {
|
||||
libkos::entry!(main);
|
||||
|
||||
fn main() {
|
||||
match check() {
|
||||
Ok(()) => libkos::println!("SMPTEST PASS"),
|
||||
Err(why) => libkos::println!("SMPTEST FAIL: {}", why),
|
||||
|
||||
Reference in New Issue
Block a user