Compare commits

..

No commits in common. "7d5e5db7b12772a513b3f09c2496b6ac27a3e98d" and "daf96a0c64022cb7bb8c74a81668c0f955d2324c" have entirely different histories.

20 changed files with 386 additions and 52 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
/.idea
/target
**/*/target

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/tiny_os.iml" filepath="$PROJECT_DIR$/.idea/tiny_os.iml" />
</modules>
</component>
</project>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/kernel/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/kernel/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -1,15 +1,7 @@
[env]
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
CARGO_MAKE_WORKSPACE_EMULATION = true
CARGO_MAKE_CRATE_WORKSPACE_MEMBERS = [
"kernel"
]
[tasks.clipppy]
install_crate = "clippy"
command = "cargo"
args = ["clippy"]
dependencies = ["fmt"]
CARGO_MAKE_CRATE_WORKSPACE_MEMBERS = ["kernel"]
[tasks.build]
args = ["build"]

72
api/Cargo.lock generated Normal file
View File

@ -0,0 +1,72 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "api"
version = "0.1.0"
dependencies = [
"num-derive",
"num-traits",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "num-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "num-traits"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
]
[[package]]
name = "proc-macro2"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "2.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"

8
api/Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "api"
version = "0.1.0"
edition = "2021"
[dependencies]
num-traits = { version = "0.2", default-features = false }
num-derive = "0.4"

20
api/src/cap.rs Normal file
View File

@ -0,0 +1,20 @@
#[derive(Clone, Copy, Eq, PartialEq, FromPrimitive, ToPrimitive)]
pub enum ObjectType {
Null = 0,
CNode = 1,
TCB = 2,
SchedCtx = 3,
Endpoint = 4,
Reply = 5,
Notification = 6,
Frame = 7,
PageTable = 8,
Interrupt = 9,
Untyped = 10,
}
impl Default for ObjectType {
fn default() -> Self {
Self::Null
}
}

6
api/src/lib.rs Normal file
View File

@ -0,0 +1,6 @@
#![no_std]
#[macro_use]
extern crate num_derive;
pub mod cap;

156
kernel/Cargo.lock generated
View File

@ -2,6 +2,14 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "api"
version = "0.1.0"
dependencies = [
"num-derive 0.4.2",
"num-traits",
]
[[package]]
name = "autocfg"
version = "1.1.0"
@ -44,14 +52,46 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
[[package]]
name = "endian-type-rs"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6419a5c75e40011b9fe0174db3fe24006ab122fbe1b7e9cc5974b338a755c76"
[[package]]
name = "fallible-iterator"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
[[package]]
name = "fdt-rs"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581d3afdd654deb68c19fcbe4bc411910cc64067d4a13d8637bda7722cb9c2ea"
dependencies = [
"endian-type-rs",
"fallible-iterator",
"memoffset",
"num-derive 0.3.3",
"num-traits",
"rustc_version",
"static_assertions",
"unsafe_unwrap",
]
[[package]]
name = "kernel"
version = "0.1.0"
dependencies = [
"api",
"bitflags 2.4.2",
"cfg-if",
"fdt-rs",
"lazy_static",
"log",
"num-derive 0.4.2",
"num-traits",
"riscv",
"sbi-rt",
"spin 0.9.8",
@ -84,6 +124,64 @@ version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "memoffset"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
dependencies = [
"autocfg",
]
[[package]]
name = "num-derive"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "num-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.50",
]
[[package]]
name = "num-traits"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
]
[[package]]
name = "proc-macro2"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "raw-cpuid"
version = "10.7.0"
@ -103,6 +201,15 @@ dependencies = [
"embedded-hal",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[package]]
name = "rustversion"
version = "1.0.14"
@ -130,6 +237,21 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "spin"
version = "0.5.2"
@ -151,6 +273,28 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "uart_16550"
version = "0.3.0"
@ -162,6 +306,18 @@ dependencies = [
"x86",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unsafe_unwrap"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1230ec65f13e0f9b28d789da20d2d419511893ea9dac2c1f4ef67b8b14e5da80"
[[package]]
name = "x86"
version = "0.52.0"

View File

@ -27,12 +27,17 @@ panic = "abort"
lto = "thin"
[dependencies]
api = { path = "../api" }
bitflags = "2.4.2"
cfg-if = "1.0.0"
fdt-rs = { version = "0.4.5", default-features = false }
lazy_static = { version = "1.4.0", features = ["spin_no_std"] }
log = "0.4"
num-derive = "0.4"
num-traits = { version = "0.2", default-features = false }
riscv = { version = "0.11.1", features = ["s-mode"] }
sbi-rt = { version = "0.0.3", features = ["legacy"] }
sbi-rt = { version = "0.0.3" }
spin = "0.9.8"
static_assertions = "1.1.0"
uart_16550 = "0.3"
cfg-if = "1.0.0"

View File

@ -1,21 +1,28 @@
use crate::plat::io::{Printer, RawConsole, Reader};
impl Printer for RawConsole {
#[inline]
fn put_char(c: char) {
#[allow(deprecated)]
sbi_rt::legacy::console_putchar(c as usize);
sbi_rt::console_write_byte(c as u8);
}
#[inline]
fn put_str(s: &str) {
sbi_rt::console_write(sbi_rt::Physical::new(s.len(), s.as_ptr() as _, 0));
}
}
impl Reader for RawConsole {
#[inline]
fn get_char() -> char {
let mut buf = [0u8; 1];
loop {
#[allow(deprecated)]
let ch = sbi_rt::legacy::console_getchar();
if ch == usize::MAX {
continue;
let ret = sbi_rt::console_read(sbi_rt::Physical::new(1, buf.as_mut_ptr() as _, 0));
if let Some(len) = ret.ok()
&& len == 1
{
return buf[0] as char;
}
return ch as u8 as char;
}
}
}

View File

@ -13,7 +13,7 @@ pub trait ArchLLOps {
impl LowLevel for Hardware {
#[inline]
fn halt() {
unsafe { core::arch::asm!("wfi") }
riscv::asm::wfi()
}
#[inline]
@ -35,11 +35,11 @@ impl LowLevel for Hardware {
#[inline]
fn enable_interrupt() {
unsafe { riscv::register::sstatus::set_sie() }
unsafe { riscv::interrupt::enable() }
}
#[inline]
fn disable_interrupt() {
unsafe { riscv::register::sstatus::clear_sie() }
riscv::interrupt::disable()
}
}

View File

@ -1,6 +1,7 @@
use cfg_if::cfg_if;
use log::trace;
use riscv::register::scause::{Interrupt as I, Trap as T};
use riscv::register::stvec::TrapMode;
use super::cpu::get_hart_id;
use crate::plat::timer::{Timer, TimerOps};
@ -49,9 +50,9 @@ extern "C" fn trap_handler(_tf: &mut TrapContext) {
impl TrapOps for Trap {
fn init() {
// anyway, clear sscratch
unsafe { core::arch::asm!("csrw sscratch, zero") }
riscv::register::sscratch::write(0);
// set trap_entry
unsafe { core::arch::asm!("csrw stvec, {}", in(reg) trap_entry as usize) }
unsafe { riscv::register::stvec::write(trap_entry as usize, TrapMode::Direct) }
}
}

View File

@ -6,11 +6,11 @@ use crate::plat::lowlevel::{Hardware, LowLevel};
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
error!("[lang] Kernel panic!");
error!("Kernel panic!");
match info.location() {
Some(location) => error!(
"[lang] Panicked: [{}:{}:{}] {}",
"Panicked: [{}:{}:{}] {}",
location.file(),
location.line(),
location.column(),

View File

@ -1,6 +1,6 @@
use core::fmt::Write;
use log::{self, LevelFilter, Log, Metadata, Record};
use log::{LevelFilter, Log, Metadata, Record};
use crate::plat::io::RawConsole;

View File

@ -3,6 +3,7 @@
#![no_main]
// Features
#![feature(asm_const)]
#![feature(let_chains)]
#![feature(naked_functions)]
#![feature(panic_info_message)]
#![feature(stmt_expr_attributes)]
@ -29,6 +30,9 @@ pub mod mm;
// plat
pub mod plat;
// object
pub mod objects;
// logging
pub mod logging;

23
kernel/src/objects/cap.rs Normal file
View File

@ -0,0 +1,23 @@
use api::cap::ObjectType;
/// RawCap is the specific implementation of capability which stores in CNode
pub struct RawCap {
/// args: in vanilla seL4 implementation, a cap use two 64-bit words to store all information,
/// but we'll waste some space rather than using bitfield to simplify the implementation
args: [usize; 2],
/// cap_type: every capability links to one specific object
cap_type: ObjectType,
}
impl RawCap {
pub fn new(arg0: usize, arg1: usize, cap_type: ObjectType) -> Self {
Self {
args: [arg0, arg1],
cap_type,
}
}
pub fn cap_type(&self) -> ObjectType {
self.cap_type
}
}

38
kernel/src/objects/mod.rs Normal file
View File

@ -0,0 +1,38 @@
/*
10 kernel object types:
Threads (thread-control blocks: TCBs)
Scheduling contexts (SCs)
Address spaces (page table objects: PDs, PTs)
Endpoints (IPC)
Reply objects (ROs)
Notifications
Capability spaces (CNodes)
Frames
Interrupt objects (architecture specific)
Untyped memory
*/
use api::cap::ObjectType;
use cap::RawCap;
use core::cell::Cell;
use core::marker::PhantomData;
pub mod cap;
pub mod null;
pub mod untyped;
/// Cap is the high-level wrapper of RawCap, it's a typed reference to RawCap (which is untyped in Rust)
/// For the typed objects, we should bound it with an empty traits `KernelObject`
/// And for those objects, at least implement `mint` method and `decodeInvocation` (not enforcing in `KernelObject` for complexity)
pub struct Cap<'a, T: KernelObject> {
cap: &'a Cell<RawCap>,
cap_type: PhantomData<T>,
}
/// KernelObject is the base trait for all kernel objects
pub trait KernelObject {
// this should be optimized by compiler?
const OBJ_TYPE: ObjectType;
}

View File

@ -0,0 +1,27 @@
use super::cap::RawCap;
use super::{Cap, KernelObject};
use api::cap::ObjectType;
use core::marker::PhantomData;
/// NullObject is used as empty (capability) slot
pub struct NullObject {}
pub type NullCap<'a> = Cap<'a, NullObject>;
impl KernelObject for NullObject {
const OBJ_TYPE: ObjectType = ObjectType::Null;
}
impl<'a> NullCap<'a> {
pub fn mint() -> RawCap {
let cap = RawCap::new(0, 0, ObjectType::Null);
cap
}
pub fn retype<T: KernelObject>(self, new: RawCap) -> Cap<'a, T> {
assert!(T::OBJ_TYPE == new.cap_type());
self.cap.set(new);
Cap {
cap: self.cap,
cap_type: PhantomData,
}
}
}