diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml
index c93dfe7..ed35d9b 100644
--- a/.github/workflows/docker-build.yml
+++ b/.github/workflows/docker-build.yml
@@ -10,7 +10,7 @@ jobs:
build:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
diff --git a/.gitmodules b/.gitmodules
index 3851b15..de3dd3f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,9 +1,6 @@
[submodule "src/services/src/supervisor-riscv"]
path = src/services/src/supervisor-riscv
url = https://github.com/diodesign/supervisor-riscv.git
-[submodule "src/mason"]
- path = src/mason
- url = https://github.com/diodesign/mason.git
[submodule "src/mkdmfs"]
path = src/mkdmfs
url = https://github.com/diodesign/mkdmfs
@@ -19,3 +16,6 @@
[submodule "src/services/src/gooey"]
path = src/services/src/gooey
url = https://github.com/diodesign/gooey.git
+[submodule "src/itsylinker"]
+ path = src/itsylinker
+ url = https://github.com/diodesign/itsylinker.git
diff --git a/Dockerfile b/Dockerfile
index aedfb22..8bb3b3c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -22,7 +22,7 @@ COPY . /diosix
WORKDIR /diosix
# Install necessary bits and pieces of Rust and just, pull in the submodules, and then build diosix
-RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly -y \
+RUN curl https://sh.rustup.rs -sSf | sh -s -- --profile minimal --default-toolchain nightly -y \
&& . $HOME/.cargo/env \
&& cargo install --force just \
&& git submodule update --init --recursive \
diff --git a/docs/running.md b/docs/running.md
index 1310ce9..ec1e30a 100644
--- a/docs/running.md
+++ b/docs/running.md
@@ -32,11 +32,7 @@ These steps will prepare your system for building and running Diosix using its l
sudo apt -y install build-essential pkg-config git curl binutils-riscv64-linux-gnu qemu-system-misc libssl-dev
```
-2. If you have not yet installed the Rust toolchain, follow [these instructions](https://www.rust-lang.org/tools/install) to do so. Make the `nightly` version of Rust the default toolchain:
-
- ```
- rustup default nightly
- ```
+2. If you have not yet installed the Rust toolchain, follow [these instructions](https://www.rust-lang.org/tools/install) to do so.
3. Install [`just`](https://github.com/casey/just), which Diosix uses to automate the steps needed to build and run the project:
@@ -63,7 +59,7 @@ This will check to see if Diosix needs to be built. If so, the project will auto
Diosix is then booted in a Qemu RISC-V environment, and the hypervisor will start the included services and guests. To exit the emulator, press `Control-a` then `x`. The guest OSes provided by default are BusyBox-based Linux operating systems. To log in, use the username `root`. No password is required.
-## Using the system console
+### Using the system console
By default, Diosix will run a system service called `gooey` that provides a very simple user interface. This is accessed through the terminal when using Qemu, and on real hardware, through the system's first serial port.
diff --git a/justfile b/justfile
index 0bc5778..ad62615 100644
--- a/justfile
+++ b/justfile
@@ -155,6 +155,9 @@ guests_sw := if guests == "no" { "--skip-guests" } else { "" }
downloads_sw := if guests-download == "no" { "--skip-downloads" } else { "" }
builds_sw := if guests-build == "no" { "--skip-buildroot" } else { "" }
+# use rustc's nightly build
+cargo_cmd := "cargo +nightly"
+
# the default recipe
# build diosix with its components, and run it within qemu
@qemu: build
@@ -176,7 +179,7 @@ builds_sw := if guests-build == "no" { "--skip-buildroot" } else { "" }
# the core workflow for building diosix and its components
# a link is created at final-exe-path to the final packaged executable
-@build: _descr _rustup _hypervisor
+@build: _descr _rustup _itsylinker _hypervisor
ln -fs {{target}}/{{quality_sw}}/hypervisor {{final-exe-path}}
echo "{{builtmsg}} {{final-exe-path}}"
@@ -184,43 +187,49 @@ builds_sw := if guests-build == "no" { "--skip-buildroot" } else { "" }
@_descr:
echo "{{buildmsg}} {{quality_sw}}-grade Diosix for {{target}} systems"
-# build the hypervisor and ensure it has a boot file system to include
+# build the itsy-bitsy linker ready for use
+@_itsylinker:
+ echo "{{buildmsg}} linker"
+ cd src/itsylinker && {{cargo_cmd}} build {{quiet_sw}}
+
+# build the hypervisor after ensuring it has a boot file system to include
@_hypervisor: _mkdmfs
echo "{{buildmsg}} hypervisor"
- cd src/hypervisor && cargo build {{cargo_sw}} {{qemuprint_sw}} {{sifiveprint_sw}} {{htifprint_sw}} {{integritychecks_sw}}
+ cd src/hypervisor && {{cargo_cmd}} build {{cargo_sw}} {{qemuprint_sw}} {{sifiveprint_sw}} {{htifprint_sw}} {{integritychecks_sw}}
# build and run the dmfs generator to include banners and system services.
# mkdmfs is configured by manifest.toml in the project root directory.
-# the output fs image is linked in the hypervisor and unpacked at run-time
+# the output fs image is linked in the hypervisor and unpacked at run-time.
#
# the target directory stores the dmfs image file
@_mkdmfs: _services
echo "{{buildmsg}} dmfs image"
- cd src/mkdmfs && cargo run {{quiet_sw}} -- -t {{target}} -q {{quality_sw}} {{verbose_sw}} {{services_sw}} {{guests_sw}} {{downloads_sw}} {{builds_sw}}
+ cd src/mkdmfs && {{cargo_cmd}} run {{quiet_sw}} --release -- -t {{target}} -q {{quality_sw}} {{verbose_sw}} {{services_sw}} {{guests_sw}} {{downloads_sw}} {{builds_sw}}
# build the system services
@_services:
echo "{{buildmsg}} system services"
- cd src/services && cargo build {{cargo_sw}}
+ cd src/services && {{cargo_cmd}} build {{cargo_sw}}
# make sure we've got the cross-compiler installed and setup
@_rustup:
echo "{{rustupmsg}} {{target}}"
- rustup {{quiet_sw}} target install {{target}}
+ rustup {{quiet_sw}} toolchain install nightly
+ rustup {{quiet_sw}} target install {{target}} --toolchain nightly
# delete intermediate build files and update cargo dependencies to start afresh
@clean:
echo "{{cleanmsg}}"
- -cd src/hypervisor && cargo {{quiet_sw}} clean && cargo {{quiet_sw}} update
- -cd src/services && cargo {{quiet_sw}} clean && cargo {{quiet_sw}} update
- -cd src/mkdmfs && cargo {{quiet_sw}} clean && cargo {{quiet_sw}} update
+ -cd src/hypervisor && {{cargo_cmd}} {{quiet_sw}} clean && {{cargo_cmd}} {{quiet_sw}} update
+ -cd src/services && {{cargo_cmd}} {{quiet_sw}} clean && {{cargo_cmd}} {{quiet_sw}} update
+ -cd src/mkdmfs && {{cargo_cmd}} {{quiet_sw}} clean && {{cargo_cmd}} {{quiet_sw}} update
# FIXME: the framework for this is broken.
# run unit tests for each major component
# @_test:
-# -cd src/hypervisor && cargo {{quiet_sw}} test
-# -cd src/services && cargo {{quiet_sw}} test
-# -cd src/mkdmfs && cargo {{quiet_sw}} test
+# -cd src/hypervisor && {{cargo_cmd}} {{quiet_sw}} test
+# -cd src/services && {{cargo_cmd}} {{quiet_sw}} test
+# -cd src/mkdmfs && {{cargo_cmd}} {{quiet_sw}} test
# are we allowed one easter egg?
@_incredible:
diff --git a/manifest.toml b/manifest.toml
index 6d4e0e8..bdc37a9 100644
--- a/manifest.toml
+++ b/manifest.toml
@@ -63,6 +63,14 @@ description = "64-bit RISC-V Linux with Busybox"
ram = 128
cpus = 2
+# repnop's vanadinite Rust operating system
+# see https://github.com/repnop/vanadinite
+[guest.vanadinite]
+path = "boot/guests"
+description = "RV64GC Vanadinite microkernel with userspace"
+ram = 128
+cpus = 1
+
# select the guests to include for a given target
# To include and boot more than one guest, add more than one entry to the guests array
diff --git a/src/hypervisor/.cargo/config b/src/hypervisor/.cargo/config
index c073061..ad5290d 100644
--- a/src/hypervisor/.cargo/config
+++ b/src/hypervisor/.cargo/config
@@ -5,20 +5,16 @@
# See LICENSE for usage and copying.
#
-#
# set the default build triple
-#
[build]
target = "riscv64gc-unknown-none-elf"
# Find the linker for 64-bit RISC-V (IMAC) targets
[target.riscv64imac-unknown-none-elf]
-rustflags = [ "-Z", "pre-link-arg=-nostartfiles", "-C", "link-arg=-Tsrc/platform-riscv/link.ld", "-C", "link-arg=--no-eh-frame-hdr" ]
-linker = "riscv64-linux-gnu-ld"
-ar = "riscv64-linux-gnu-ar"
+linker = "../itsylinker/target/debug/itsylinker"
+rustflags = [ "-C", "link-arg=-T", "-C", "link-arg=src/platform-riscv/link.toml" ]
# Find the linker for 64-bit RISC-V (GC) targets
[target.riscv64gc-unknown-none-elf]
-rustflags = [ "-Z", "pre-link-arg=-nostartfiles", "-C", "link-arg=-Tsrc/platform-riscv/link.ld", "-C", "link-arg=--no-eh-frame-hdr" ]
-linker = "riscv64-linux-gnu-ld"
-ar = "riscv64-linux-gnu-ar"
+linker = "../itsylinker/target/debug/itsylinker"
+rustflags = [ "-C", "link-arg=-T", "-C", "link-arg=src/platform-riscv/link.toml" ]
diff --git a/src/hypervisor/Cargo.toml b/src/hypervisor/Cargo.toml
index 4cd80ea..51698c1 100644
--- a/src/hypervisor/Cargo.toml
+++ b/src/hypervisor/Cargo.toml
@@ -3,7 +3,6 @@ name = "hypervisor"
version = "0.0.2"
authors = ["Chris Williams "]
license = "MIT"
-build = "../mason/build.rs"
publish = false
edition = "2018"
@@ -31,12 +30,12 @@ xmas-elf = { git = "https://github.com/nrc/xmas-elf.git" }
# external dependencies
[dependencies.hashbrown]
-version = "0.9.1"
+version = "0.11.1"
features = [ "nightly" ]
-[dependencies.lazy_static]
-version = "1.4.0"
-features = [ "spin_no_std" ]
+[dependencies.spinning]
+git = "https://github.com/diodesign/spinning-rs"
+default-features = false
# supported build targets - don't forget to update .cargo with details for the linker and runner when adding new ports
[target.riscv64imac-unknown-none-elf.dependencies]
diff --git a/src/hypervisor/mason.toml b/src/hypervisor/mason.toml
deleted file mode 100644
index b975208..0000000
--- a/src/hypervisor/mason.toml
+++ /dev/null
@@ -1,17 +0,0 @@
-# Configure Mason to build non-Rust portions of the diosix hypervisor
-#
-# Directory paths are relative to this manifest.toml file
-
-[defaults]
-# include_files is a colon-separated list of arbitrary files
-# to include in the hypervisor's executable
-include_files = [ "../mkdmfs/target/dmfs.img" ]
-
-# Set up assembly code directories for supported architectures
-# asm_dirs is a colon-separated list of directories to scan
-# for assembly code to build and link to the hypervisor's executable
-[target.riscv64imac-unknown-none-elf]
-asm_dirs = [ "src/platform-riscv/asm" ]
-
-[target.riscv64gc-unknown-none-elf]
-asm_dirs = [ "src/platform-riscv/asm" ]
\ No newline at end of file
diff --git a/src/hypervisor/src/capsule.rs b/src/hypervisor/src/capsule.rs
index bb83393..858ca24 100644
--- a/src/hypervisor/src/capsule.rs
+++ b/src/hypervisor/src/capsule.rs
@@ -10,6 +10,7 @@ use super::lock::Mutex;
use hashbrown::hash_map::HashMap;
use hashbrown::hash_map::Entry::{Occupied, Vacant};
use hashbrown::hash_set::HashSet;
+use spinning::Lazy;
use alloc::vec::Vec;
use alloc::string::{String, ToString};
use platform::cpu::{Entry, CPUcount};
@@ -29,26 +30,20 @@ pub type CapsuleID = usize;
const CAPSULES_MAX: usize = 1000000;
/* needed to assign system-wide unique capsule ID numbers */
-lazy_static!
-{
- static ref CAPSULE_ID_NEXT: AtomicUsize = AtomicUsize::new(0);
-}
+static CAPSULE_ID_NEXT: Lazy = Lazy::new(|| AtomicUsize::new(0));
/* maintain a shared table of capsules and linked data */
-lazy_static!
-{
- /* acquire CAPSULES lock before accessing any capsules */
- static ref CAPSULES: Mutex> = Mutex::new("capsule ID table", HashMap::new());
+/* acquire CAPSULES lock before accessing any capsules */
+static CAPSULES: Lazy>> = Lazy::new(|| Mutex::new("capsule ID table", HashMap::new()));
- /* set of capsules to restart */
- static ref TO_RESTART: Mutex> = Mutex::new("capsule restart list", HashSet::new());
+/* set of capsules to restart */
+static TO_RESTART: Lazy>> = Lazy::new(|| Mutex::new("capsule restart list", HashSet::new()));
- /* maintain collective input and output system console buffers for capsules.
- the console system service capsule (ServiceConsole) will read from
- STDOUT to display capsules' text, and will write to STDIN to inject characters into capsules */
- static ref STDIN: Mutex>> = Mutex::new("capsule STDIN table", HashMap::new());
- static ref STDOUT: Mutex>> = Mutex::new("capsule STDOUT table", HashMap::new());
-}
+/* maintain collective input and output system console buffers for capsules.
+ the console system service capsule (ServiceConsole) will read from
+ STDOUT to display capsules' text, and will write to STDIN to inject characters into capsules */
+static STDIN: Lazy>>> = Lazy::new(|| Mutex::new("capsule STDIN table", HashMap::new()));
+static STDOUT: Lazy>>> = Lazy::new(|| Mutex::new("capsule STDOUT table", HashMap::new()));
/* perform housekeeping duties on idle physical CPU cores */
macro_rules! capsulehousekeeper
diff --git a/src/hypervisor/src/debug.rs b/src/hypervisor/src/debug.rs
index edc3458..0733a20 100644
--- a/src/hypervisor/src/debug.rs
+++ b/src/hypervisor/src/debug.rs
@@ -13,6 +13,7 @@ use core::fmt;
use super::lock::Mutex;
use alloc::vec::Vec;
use alloc::string::String;
+use spinning::Lazy;
use super::hardware;
use super::service;
use super::message;
@@ -30,12 +31,9 @@ use super::message;
const DEBUG_LOG_MAX_LEN: usize = 64 * 1024; /* 64KB max length for debug log buffer */
-lazy_static!
-{
- pub static ref DEBUG_LOCK: Mutex = Mutex::new("primary debug lock", false);
- static ref DEBUG_QUEUE: Mutex = Mutex::new("debug output queue", String::new());
- static ref DEBUG_LOG: Mutex> = Mutex::new("debug log buffer", Vec::new());
-}
+pub static DEBUG_LOCK: Lazy> = Lazy::new(|| Mutex::new("primary debug lock", false));
+static DEBUG_QUEUE: Lazy> = Lazy::new(|| Mutex::new("debug output queue", String::new()));
+static DEBUG_LOG: Lazy>> = Lazy::new(|| Mutex::new("debug log buffer", Vec::new()));
/* top level debug macros */
/* bad news: bug detection, failures, etc. */
diff --git a/src/hypervisor/src/devicetree b/src/hypervisor/src/devicetree
index 87c23af..8b4da16 160000
--- a/src/hypervisor/src/devicetree
+++ b/src/hypervisor/src/devicetree
@@ -1 +1 @@
-Subproject commit 87c23afedf37d12213a9cc8606d5df839fb0ac4d
+Subproject commit 8b4da16e569b869b9e4860aeceefe3bd2c749469
diff --git a/src/hypervisor/src/hardware.rs b/src/hypervisor/src/hardware.rs
index b39df79..eb36d06 100644
--- a/src/hypervisor/src/hardware.rs
+++ b/src/hypervisor/src/hardware.rs
@@ -7,16 +7,14 @@
use alloc::vec::Vec;
use super::lock::Mutex;
+use spinning::Lazy;
use platform::devices::Devices;
use platform::physmem::{PhysMemBase, PhysMemSize};
use platform::timer;
use super::error::Cause;
-lazy_static!
-{
- /* acquire HARDWARE before accessing any system hardware */
- static ref HARDWARE: Mutex