Add rust skeleton code and build system
* panic_fmt lang-item * arch-based crates, inspired by Redox * Port over target files from Robigalia, add aarch64 * Use rlibc for memset/memcpy * Create linker script for raspberry pi 3 * Implement primitive dmb() * Important: initialize stack pointer! Kernel interface is to be defined in a separate crate.
This commit is contained in:
parent
3cb7dc3025
commit
072e0a05aa
|
@ -0,0 +1,2 @@
|
|||
[target.aarch64-vesper-metta]
|
||||
runner=".cargo/runscript.sh"
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
aarch64-unknown-linux-musl-objcopy -O binary $1 $1.bin
|
||||
|
||||
# -d unimp,int -serial stdio -S
|
||||
qemu-system-aarch64 -M raspi3 -d in_asm -serial null -serial stdio -kernel $1.bin
|
|
@ -0,0 +1,42 @@
|
|||
[package]
|
||||
name = "vesper"
|
||||
version = "1.0.0"
|
||||
authors = ["Berkus Decker <berkus+cargo@metta.systems>"]
|
||||
description = "Vesper exokernel"
|
||||
documentation = "https://docs.metta.systems/vesper"
|
||||
homepage = "https://github.com/metta-systems/vesper"
|
||||
repository = "https://github.com/metta-systems/vesper"
|
||||
readme = "README.md"
|
||||
license = "BSL-1.0"
|
||||
categories = ["no-std", "embedded", "os"]
|
||||
publish = false
|
||||
|
||||
[features]
|
||||
unstable = []
|
||||
realtime = []
|
||||
|
||||
#[lib]
|
||||
#name = "nucleus"
|
||||
#path = "src/lib.rs"
|
||||
#crate-type = ["staticlib"]
|
||||
|
||||
[dependencies]
|
||||
rlibc = "1.0.0"
|
||||
bitflags = "1.0.1"
|
||||
register = "0.2"
|
||||
cortex-a = "2.2"
|
||||
|
||||
[profile.dev]
|
||||
panic = "abort"
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
debug = true
|
||||
lto = true
|
||||
|
||||
[package.metadata.cargo-xbuild]
|
||||
memcpy = true
|
||||
|
||||
[package.metadata.bootimage]
|
||||
default-target = "targets/aarch64-vesper-metta.json"
|
||||
#run-command = ".cargo/runscript.sh"
|
30
README.md
30
README.md
|
@ -6,7 +6,7 @@ Vesper is a capability-based single-address-space exokernel, it tries to remain
|
|||
|
||||
Exokernel's distinctive trait is that it provides mechanisms but not policies. Vesper tries to move as many policy decisions as possible to the library OS.
|
||||
|
||||
* Single-address-space is a mechanism for providing pointer transparency between processes. Sharing a buffer is nearly as simple as passing out its address.
|
||||
* Single-address-space is a mechanism for providing pointer transparency between processes. Sharing a buffer is nearly as simple as passing out its address. Even though single-address-space is not a basic requirement and may be seen as an imposed policy decision, it does provide mechanism for efficient data passing between protection domains. This is important for modern media-rich communications.
|
||||
|
||||
* IPC is a mechanism providing secure interaction between processes.
|
||||
|
||||
|
@ -18,13 +18,39 @@ Exokernel's distinctive trait is that it provides mechanisms but not policies. V
|
|||
|
||||
Scheduling can be viewed as the process of multiplexing the CPU resource between computational tasks. The schedulable entity of an operating system often places constraints both on the scheduling algorithms which may be employed and the functionality provided to the application. The recent gain in popularity of multi-threaded programming due to languages such as Modula-3 [Nelson 91] has led many operating system designers to provide kernel-level thread support mechanisms [Accetta 86, Rozier 90]. The kernel therefore schedules threads rather than processes. Whilst this reduces the functionality required in applications and usually results in more efficient processor context-switches, the necessary thread scheduling policy decisions must also be migrated into the kernel. As pointed out in [Barham 96], this is highly undesirable.
|
||||
|
||||
The desire to move such decisions out of the kernel make interesting variants where actual scheduling is performed by the user-level domain scheduler upon an **upcall** from the kernel. TBD
|
||||
|
||||
## Real Time
|
||||
|
||||
At the moment this is not a real-time kernel. It has a small number of potentially long-running kernel operations that are not preemptable (e.g., endpoint deletion and recycling, scheduling, frame and CNode initialisation). This may change in future versions.
|
||||
|
||||
## Credits
|
||||
|
||||
|
||||
Vesper has been influenced by the kernels in L4 family, notably seL4. Fawn and Nemesis provided inspiration for single-address-space and vertical integration of the applications.
|
||||
|
||||
## Build instructions
|
||||
|
||||
Use rustc nightly 2018-04-01 or later because of [bugs fixed](https://github.com/rust-lang/rust/issues/48884).
|
||||
|
||||
```
|
||||
cargo xbuild --target=targets/aarch64-vesper-metta.json --release
|
||||
|
||||
# Post-command:
|
||||
sh .cargo/runscript.sh
|
||||
cp target/aarch64-vesper-metta/release/vesper.bin /Volumes/boot/vesper
|
||||
|
||||
# config.txt on RPi3
|
||||
kernel=vesper
|
||||
arm_64bit=1
|
||||
|
||||
# To run in qemu, `brew install qemu --HEAD --with-libusb` and
|
||||
### This command is not supported by cargo-xbuild yet: xargo run --target=aarch64-vesper-metta
|
||||
# Use this instead:
|
||||
sh .cargo/runscript.sh
|
||||
```
|
||||
|
||||
## OSdev help
|
||||
|
||||
Based on [Raspi3 tutorials by Andre Richter](https://github.com/rust-embedded/rust-raspi3-tutorial/blob/master/05_uart0/src/uart.rs),
|
||||
which are in turn based on [Raspi3 tutorials by bzt](https://github.com/bztsrc/raspi3-tutorial/).
|
||||
Various references from [OSDev Wiki](https://wiki.osdev.org/Raspberry_Pi_Bare_Bones) and [RaspberryPi.org manuals](https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf).
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
ENTRY(karch_start)
|
||||
OUTPUT_ARCH(aarch64)
|
||||
/*OUTPUT_FORMAT(binary) Cannot change output format whilst linking AArch64 binaries.*/
|
||||
|
||||
START_ADDRESS = 0x80000; /* AArch64 boot address is 0x80000 */
|
||||
|
||||
SECTIONS {
|
||||
.text START_ADDRESS : AT(START_ADDRESS) {
|
||||
*(.text.karch_start)
|
||||
*(.text*)
|
||||
}
|
||||
|
||||
.rodata ALIGN (4) : {
|
||||
*(.rodata*)
|
||||
FILL(0x00)
|
||||
}
|
||||
|
||||
.data ALIGN (4) : {
|
||||
*(.data*)
|
||||
FILL(0x00)
|
||||
}
|
||||
|
||||
.bss ALIGN (4) : {
|
||||
*(COMMON*)
|
||||
*(.bss*)
|
||||
}
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.comment .note* .dtors)
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
nightly
|
|
@ -0,0 +1,5 @@
|
|||
# Architecture-specific code
|
||||
|
||||
This directory contains code specific to a certain architecture.
|
||||
|
||||
Implementations of arch-specific kernel calls are also placed here.
|
|
@ -0,0 +1,69 @@
|
|||
// mod arch::aarch64
|
||||
|
||||
use cortex_a::{asm, barrier, regs::*};
|
||||
|
||||
/// The entry to Rust, all things must be initialized
|
||||
/// This is invoked from the linker script, does arch-specific init
|
||||
/// and passes control to the kernel boot function kmain().
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn karch_start() -> ! {
|
||||
// Set sp to 0x80000 (just before kernel start)
|
||||
const STACK_START: u64 = 0x8_0000;
|
||||
|
||||
SP.set(STACK_START);
|
||||
|
||||
match read_cpu_id() {
|
||||
0 => ::kmain(),
|
||||
_ => endless_sleep(), // if not core0, indefinitely wait for events
|
||||
}
|
||||
}
|
||||
|
||||
// Data memory barrier
|
||||
#[inline]
|
||||
pub fn dmb() {
|
||||
unsafe {
|
||||
barrier::dmb(barrier::SY);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn flushcache(address: usize) {
|
||||
unsafe {
|
||||
asm!("dc ivac, $0" :: "r"(address) :: "volatile");
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_cpu_id() -> u64 {
|
||||
const CORE_MASK: u64 = 0x3;
|
||||
MPIDR_EL1.get() & CORE_MASK
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn current_el() -> u32 {
|
||||
CurrentEL.get()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn endless_sleep() -> ! {
|
||||
loop {
|
||||
asm::wfe();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn loop_delay(rounds: u32) {
|
||||
for _ in 0..rounds {
|
||||
asm::nop();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn loop_until<F: Fn() -> bool>(f: F) {
|
||||
loop {
|
||||
if f() {
|
||||
break;
|
||||
}
|
||||
asm::nop();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#[cfg(target_arch = "aarch64")]
|
||||
#[macro_use]
|
||||
pub mod aarch64;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub use self::aarch64::*;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[macro_use]
|
||||
pub mod x86_64;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub use self::x86_64::*;
|
|
@ -0,0 +1 @@
|
|||
// mod arch::x86_64
|
|
@ -0,0 +1,42 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
#![feature(asm)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(ptr_internals)] // until we mark with PhantomData instead?
|
||||
#![doc(html_root_url = "https://docs.metta.systems/")]
|
||||
|
||||
#[cfg(not(any(target_arch = "aarch64", target_arch = "x86_64")))]
|
||||
use architecture_not_supported_sorry;
|
||||
|
||||
extern crate bitflags;
|
||||
#[macro_use]
|
||||
extern crate register;
|
||||
extern crate cortex_a;
|
||||
extern crate rlibc;
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
#[macro_use]
|
||||
pub mod arch;
|
||||
pub use arch::*;
|
||||
|
||||
// User-facing kernel parts - syscalls and capability invocations.
|
||||
// pub mod vesper; -- no mod exported, because available through syscall interface
|
||||
|
||||
// Actual interfaces to call these syscalls are in vesper-user (similar to libsel4)
|
||||
// pub mod vesper; -- exported from vesper-user
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_info: &PanicInfo) -> ! {
|
||||
// @todo rect() + drawtext("PANIC")?
|
||||
endless_sleep()
|
||||
}
|
||||
|
||||
// Kernel entry point
|
||||
// arch crate is responsible for calling this
|
||||
pub fn kmain() -> ! {
|
||||
if current_el() == 1 {
|
||||
endless_sleep();
|
||||
}
|
||||
|
||||
endless_sleep()
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
# Board Support Packages
|
||||
|
||||
This directory contains support for specific Boards like RaspberryPi3 etc.
|
|
@ -0,0 +1,24 @@
|
|||
@todo - factor it out into separate repo
|
||||
@todo - "panic-strategy": "abort" is ok for baremetal, but not for -metta, right?
|
||||
|
||||
# vesper-targets
|
||||
|
||||
These are [target
|
||||
specifications](https://github.com/rust-lang/rfcs/blob/master/text/0131-target-specification.md)
|
||||
suitable for cross-compiling Rust crates for Vesper. Set your `RUST_TARGET_PATH` to point to this directory.
|
||||
|
||||
These are very much based on Robigalia's [sel4-targets](https://gitlab.com/robigalia/sel4-targets).
|
||||
|
||||
## Status
|
||||
|
||||
Complete for aarch64. Untested for anything else.
|
||||
|
||||
## Generating target specifications:
|
||||
|
||||
See [description in rust docs](https://doc.rust-lang.org/rustc/targets/custom.html).
|
||||
|
||||
To generate a target specification json template, run
|
||||
|
||||
```
|
||||
rustc +nightly -Z unstable-options --target=wasm32-unknown-unknown --print target-spec-json
|
||||
```
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"llvm-target": "aarch64-unknown-none",
|
||||
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
|
||||
"arch": "aarch64",
|
||||
"os": "vesper",
|
||||
"vendor": "metta",
|
||||
"env": "",
|
||||
"executables": true,
|
||||
"panic-strategy": "abort",
|
||||
"linker-flavor": "ld.lld",
|
||||
"linker": "rust-lld",
|
||||
"pre-link-args": {
|
||||
"ld.lld": [
|
||||
"--script=linker/aarch64.ld",
|
||||
"--print-gc-sections"
|
||||
]
|
||||
},
|
||||
"disable-redzone": true,
|
||||
"target-endian": "little",
|
||||
"target-c-int-width": "32",
|
||||
"target-pointer-width": "64"
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
|
||||
"llvm-target": "arm-unknown-linux-musleabihf",
|
||||
"target-endian": "little",
|
||||
"target-pointer-width": "32",
|
||||
"target-c-int-width": "32",
|
||||
"os": "vesper",
|
||||
"env": "metta",
|
||||
"arch": "arm",
|
||||
"linker-is-gnu": true,
|
||||
"executables": true,
|
||||
"linker-flavor": "ld",
|
||||
"linker": "arm-unknown-linux-musleabihf-ld",
|
||||
"ar": "arm-unknown-linux-musleabihf-ar",
|
||||
"position-independent-executables": true,
|
||||
"has-elf-tls": true,
|
||||
"panic-strategy": "abort",
|
||||
"no-default-libraries": true,
|
||||
"pre-link-args": {
|
||||
"gcc": ["-ffreestanding", "-nodefaultlibs", "-nostdlib"]
|
||||
},
|
||||
"default-codegen-units": 1
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"data-layout": "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128",
|
||||
"llvm-target": "i686-elf",
|
||||
"target-endian": "little",
|
||||
"target-pointer-width": "32",
|
||||
"target-c-int-width": "32",
|
||||
"os": "vesper",
|
||||
"env": "metta",
|
||||
"arch": "x86",
|
||||
"linker-is-gnu": true,
|
||||
"executables": true,
|
||||
"no-compiler-rt": false,
|
||||
"relocation-model": "pic",
|
||||
"position-independent-executables": false,
|
||||
"dynamic-linking": false,
|
||||
"has-elf-tls": true,
|
||||
"panic-strategy": "abort",
|
||||
"no-default-libraries": true,
|
||||
"linker-flavor": "gcc",
|
||||
"pre-link-args": {
|
||||
"gcc": ["-m32", "-ffreestanding", "-nodefaultlibs", "-nostdlib"]
|
||||
},
|
||||
"default-codegen-units": 1
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
||||
"llvm-target": "x86_64-elf",
|
||||
"target-endian": "little",
|
||||
"target-pointer-width": "64",
|
||||
"target-c-int-width": "32",
|
||||
"os": "vesper",
|
||||
"env": "metta",
|
||||
"arch": "x86_64",
|
||||
"cpu": "x86-64",
|
||||
"linker-is-gnu": true,
|
||||
"executables": true,
|
||||
"no-compiler-rt": false,
|
||||
"relocation-model": "pic",
|
||||
"position-independent-executables": false,
|
||||
"dynamic_linking": false,
|
||||
"has-elf-tls": true,
|
||||
"panic-strategy": "abort",
|
||||
"disable-redzone": true,
|
||||
"no-default-libraries": true,
|
||||
"linker-flavor": "gcc",
|
||||
"pre-link-args": {
|
||||
"gcc": ["-m64", "-ffreestanding", "-nodefaultlibs", "-nostdlib"]
|
||||
},
|
||||
"default-codegen-units": 1
|
||||
}
|
Loading…
Reference in New Issue