Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/compile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ jobs:
- name: Setup
run: |
sudo apt update && sudo apt install gcc-multilib
sudo modprobe vhost_vsock
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 38 additions & 5 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ pub mod elfloader;
pub mod ipaddr;
pub mod sendable;
pub mod util;
pub mod vhost;

#[cfg(feature = "std")]
pub mod mmap;
Expand All @@ -46,13 +45,47 @@ pub struct SymtabRecord {
}

pub mod hypercall {
use core::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize};

pub const EXIT: u64 = 0;
pub const LOG: u64 = 1;
pub const SYMNAME: u64 = 2;
pub const MEMSET: u64 = 3;
pub const MEMCLR: u64 = 4;
pub const SERVERREAD: u64 = 5;
pub const SERVERWRITE: u64 = 6;
pub const CLIENTREAD: u64 = 7;
pub const CLIENTWRITE: u64 = 8;
pub const TCP_CONNECT: u64 = 5;
pub const TCP_LISTEN: u64 = 6;
pub const TCP_ACCEPT: u64 = 7;
pub const TCP_CLOSE: u64 = 8;
pub const TCP_SEND: u64 = 9;
pub const TCP_RECV: u64 = 10;
pub const FILE_OPEN: u64 = 11;
pub const FILE_CLOSE: u64 = 12;
pub const FILE_READ: u64 = 13;
pub const FILE_WRITE: u64 = 14;
pub const FILE_SEEK: u64 = 15;

#[derive(Debug, Default)]
pub struct TcpInfo {
pub ip: u32,
pub port: u16,
pub id: AtomicU64,
pub buf: usize,
pub len: AtomicUsize,
pub done: AtomicBool,
}

#[derive(Debug, Default)]
pub struct FileInfo {
pub read: bool,
pub write: bool,
pub create: bool,
pub append: bool,
pub truncate: bool,
pub buf: usize,
pub offset: isize,
pub whence: i64,
pub len: AtomicUsize,
pub id: AtomicU64,
pub done: AtomicBool,
}
}
15 changes: 0 additions & 15 deletions common/src/vhost.rs

This file was deleted.

2 changes: 1 addition & 1 deletion fix/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ extern crate alloc;
const MODULE: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/addblob"));

#[kmain]
async fn main(_: &[usize]) {
fn main(_: &[usize]) {
log::info!("creating object store");
let mut store = ObjectStore::new();
log::info!("creating fix runtime");
Expand Down
40 changes: 40 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
alias b := build
alias r := run

target := 'x86_64-unknown-none'

release := if env('RELEASE', '0') != '0'{ '--release' } else { '' }

default:
just --list

build-all:
cargo build {{release}}
cargo build -p kernel {{release}}
cargo build -p fix {{release}}
cargo build -p user {{release}}

test:
cargo test
cargo test -p kernel --target={{target}}

build bin:
cargo build -p kernel --example={{bin}} --target={{target}} {{release}}

run bin:
cargo run -p kernel --example={{bin}} --target={{target}} {{release}}

fix:
cargo run -p fix --target={{target}} {{release}}

fmt:
cargo fmt
cargo fmt -p kernel
cargo fmt -p fix
cargo fmt -p user

lint:
cargo clippy
cargo clippy -p kernel
cargo clippy -p fix
cargo clippy -p user
11 changes: 10 additions & 1 deletion kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,18 @@ version = "0.1.0"
edition = "2021"
forced-target = "x86_64-unknown-none"

[[bin]]
[[example]]
name = "hello"
test = false

[[example]]
name = "threads"
test = false

[[example]]
name = "webserver"
test = false

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
Expand Down Expand Up @@ -46,3 +54,4 @@ glob = "0.3.1"

[dev-dependencies]
postcard = { version = "1.1.3", features = ["alloc"] }
user = { path = "../user", artifact = "bin", target = "x86_64-unknown-none" }
2 changes: 2 additions & 0 deletions kernel/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ fn main() -> Result<()> {
println!("cargo::rerun-if-changed=src/interrupts.S");
cc::Build::new().file("src/util.S").compile("util");
println!("cargo::rerun-if-changed=src/util.S");
cc::Build::new().file("src/cswitch.S").compile("cswitch");
println!("cargo::rerun-if-changed=src/cswitch.S");

let dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
println!("cargo::rerun-if-changed=etc/memmap.ld");
Expand Down
3 changes: 1 addition & 2 deletions kernel/src/bin/hello.rs → kernel/examples/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
#![no_main]

use kernel::prelude::*;
use kernel::rt;

#[kmain]
async fn main(_: &[usize]) {
fn main(_: &[usize]) {
log::info!("hello, world");
}
24 changes: 24 additions & 0 deletions kernel/examples/threads.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#![no_std]
#![no_main]

use kernel::{
kthread::{self, yield_now},
prelude::*,
};

#[kmain]
fn main(_: &[usize]) {
log::info!("about to spawn two threads");
kthread::spawn(|| {
for i in 0..5 {
log::info!("thread 1 says {i}");
yield_now();
}
});
kthread::spawn(|| {
for i in 100..105 {
log::info!("thread 2 says {i}");
yield_now();
}
});
}
64 changes: 64 additions & 0 deletions kernel/examples/webserver.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#![no_std]
#![no_main]

use common::elfloader;
use kernel::host::net::TcpListener;
use kernel::{kthread, prelude::*};

const HANDLER: &[u8] = include_bytes!(env!("CARGO_BIN_FILE_USER_webserver"));

#[kmain]
fn main(_: &[usize]) {
kthread::wfi();
let listener = TcpListener::bind(&[0, 0, 0, 0], 8080);
log::info!("listening on port 8080");
let handler: Function = elfloader::load_elf(HANDLER).unwrap();
loop {
let handler = handler.clone();
let mut stream = listener.accept();
kthread::spawn(move || {
let mut handler = handler;
loop {
let effect: Function = handler
.force()
.try_into()
.expect("handler returned non-effect");
let mut data: Tuple = effect.read().try_into().expect("could not read effect");
let t: Blob = data.take(0).try_into().unwrap();
assert_eq!(&*t, b"Symbolic");
let effect: Blob = data.take(1).try_into().expect("could not find effect name");
let args: Tuple = data
.take(2)
.try_into()
.expect("could not find effect arguments");
let mut args: Vec<Value> = args.into_iter().collect();
let k: Function = args
.pop()
.and_then(|x| x.try_into().ok())
.expect("could not find continuation");
handler = match (&*effect, &*args) {
(b"read", &[Value::Word(fd), Value::Word(len)]) => {
assert_eq!(fd.read(), 0);
let mut v = vec![0; len.read() as usize];
let len = stream.recv(&mut v);
v.truncate(len);
k.apply(Blob::new(v))
}
(b"write", &[Value::Word(fd), Value::Blob(ref data)]) => {
assert_eq!(fd.read(), 1);
let len = stream.send(&*data);
k.apply(Word::new(len as u64))
}
(b"close", &[Value::Word(_)]) => k.apply(None),
(b"exit", &[Value::Word(_)]) => {
break;
}
(e, _) => {
let e: &str = str::from_utf8(e).unwrap();
panic!("unhandled effect: {e}");
}
};
}
});
}
}
77 changes: 77 additions & 0 deletions kernel/examples/webserver2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#![no_std]
#![no_main]

use common::elfloader;
use kernel::host::net::TcpListener;
use kernel::{kthread, prelude::*};

const HANDLER: &[u8] = include_bytes!(env!("CARGO_BIN_FILE_USER_webserver2"));

#[kmain]
fn main(_: &[usize]) {
kthread::wfi();
let listener = Arc::new(TcpListener::bind(&[0, 0, 0, 0], 8081));
log::info!("listening on port 8081");

for _ in 0..kernel::ncores() {
let listener = listener.clone();
kthread::spawn(move || {
let mut handler: Function = elfloader::load_elf(HANDLER).unwrap();
let mut current = None;
loop {
let effect: Function = handler
.force()
.try_into()
.expect("handler returned non-effect");
let mut data: Tuple = effect.read().try_into().expect("could not read effect");
let t: Blob = data.take(0).try_into().unwrap();
assert_eq!(&*t, b"Symbolic");
let effect: Blob = data.take(1).try_into().expect("could not find effect name");
let args: Tuple = data
.take(2)
.try_into()
.expect("could not find effect arguments");
let mut args: Vec<Value> = args.into_iter().collect();
let k: Function = args
.pop()
.and_then(|x| x.try_into().ok())
.expect("could not find continuation");
handler = match (&*effect, &*args) {
(b"accept", &[]) => {
current = Some(listener.accept());
k.apply(None)
}
(b"recv", &[Value::Word(len)]) => {
if let Some(ref mut stream) = current {
let mut v = vec![0; len.read() as usize];
let len = stream.recv(&mut v);
v.truncate(len);
k.apply(Blob::new(v))
} else {
k.apply(None)
}
}
(b"send", &[Value::Blob(ref data)]) => {
if let Some(ref mut stream) = current {
let len = stream.send(&*data);
k.apply(Word::new(len as u64))
} else {
k.apply(None)
}
}
(b"hangup", &[]) => {
current.take();
k.apply(None)
}
(b"exit", &[Value::Word(_)]) => {
break;
}
(e, _) => {
let e: &str = str::from_utf8(e).unwrap();
panic!("unhandled effect: {e}");
}
};
}
});
}
}
Loading
Loading