Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
georglauterbach committed Oct 23, 2023
1 parent 4cc262e commit 57aaec0
Show file tree
Hide file tree
Showing 35 changed files with 455 additions and 1,183 deletions.
2 changes: 1 addition & 1 deletion code/src/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl log::Log for Logger {
println!(
"{:<5} {}",
record.level().as_str().truecolor($r, $g, $b),
record.args().to_string().truecolor($r, $g, $b)
record.args().to_string()
)
}};
}
Expand Down
2 changes: 1 addition & 1 deletion code/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
//! ## `unCORE` Helper
//!
//! Helper program to ease building and running `unCORE`. This is the main binary in the
//! workspace, which enabled a seamless integration of `cargo run --` into the workflow of
//! workspace, which enables a seamless integration of `cargo run --` into the workflow of
//! `unCORE`.

mod runtime;
Expand Down
92 changes: 75 additions & 17 deletions code/src/runtime/command.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-or-later

//! Hols all functionality required for building, running, etc. unCORE.
//! Hols all functionality required for building, running, etc. `unCORE`.

use crate::runtime::environment;

/// Specifies which sub-command are available, i.e. whether the user wants to build the
/// kernel, run the kernel, etc.
Expand All @@ -14,19 +16,32 @@ pub enum Command {
Test,
/// Debug the kernel by allowing GDB to attach
Debug,
/// Check the code (e.g. with `clippy`)
Check,
}

impl Command {
/// Actually dispatches the given subcommand by matching on `Self`.
pub fn execute(self, architecture: super::arguments::Architecture) -> anyhow::Result<()> {
check_dependencies(architecture, self == Self::Debug)?;
build(&architecture.into())?;

match self {
Self::Build => {},
Self::Run => run(&architecture.into())?,
Self::Test => anyhow::bail!("The test sub-command is not yet implemented"),
Self::Debug => debug(&mut architecture.into())?,
Self::Build => build(&architecture.into())?,
Self::Run => {
build(&architecture.into())?;
run(&architecture.into())?;
},
Self::Test => {
anyhow::bail!("The test sub-command is not yet implemented");
// build(&architecture.into())?;
},
Self::Debug => {
build(&architecture.into())?;
debug(&mut architecture.into())?;
},
Self::Check => {
check(&architecture.into())?;
},
}
Ok(())
}
Expand Down Expand Up @@ -57,7 +72,7 @@ impl From<crate::runtime::arguments::Architecture> for ArchitectureSpecification
target: "riscv64gc-unknown-none-elf",
qemu_command: "qemu-system-riscv64",
linker_script_path: std::env::var("CARGO_MANIFEST_DIR").expect("msg")
+ "/uncore/src/arch/risc_v/boot/qemu.ld",
+ "/uncore/src/library/arch/risc_v/boot/qemu.ld",
qemu_arguments: vec![
"-machine".to_string(),
"virt".to_string(),
Expand Down Expand Up @@ -163,6 +178,13 @@ macro_rules! run_command_and_check {
/// Builds the kernel.
fn build(arch_specification: &super::command::ArchitectureSpecification) -> anyhow::Result<()> {
log::info!("Building unCORE");

let mut environment = super::environment::get_all_environment_variables()?;
environment.insert(
"RUSTFLAGS",
format!("-Clink-arg=-T{}", arch_specification.linker_script_path),
);

run_command_and_check!(
env!("CARGO"),
[
Expand All @@ -172,16 +194,7 @@ fn build(arch_specification: &super::command::ArchitectureSpecification) -> anyh
"--target",
arch_specification.target,
],
[
(
"RUSTFLAGS",
format!("-Clink-arg=-T{}", arch_specification.linker_script_path),
),
(
"__UNCORE__BUILD_TIME",
chrono::offset::Local::now().format("%+").to_string()
)
]
environment
);

Ok(())
Expand Down Expand Up @@ -212,3 +225,48 @@ fn debug(arch_specification: &mut super::command::ArchitectureSpecification) ->
);
Ok(())
}

/// Performs miscellaneous code (quality) checks, like running Clippy, formatting,
/// documentation, etc.
fn check(arch_specification: &super::command::ArchitectureSpecification) -> anyhow::Result<()> {
/// A simple wrapper around [`run_command_and_check`] to ease calling checks.
macro_rules! check {
($arguments:expr) => {{
run_command_and_check!(env!("CARGO"), $arguments);
}};
}

// clippy
check!(&["clippy", "--all-features", "--", "-D", "warnings"]);
check!(&[
"clippy",
"--lib",
"--target",
arch_specification.target,
"--package",
"uncore",
"--all-features",
"--",
"-D",
"warnings"
]);

// documentation
check!(&["doc", "--document-private-items"]);
check!(&["doc", "--lib", "--package", "uncore", "--document-private-items"]);

// formatting
check!(&["fmt", "--all", "--message-format", "human", "--", "--check"]);
check!(&[
"fmt",
"--package",
"uncore",
"--all",
"--message-format",
"human",
"--",
"--check",
]);

Ok(())
}
27 changes: 27 additions & 0 deletions code/src/runtime/environment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: GPL-3.0-or-later

//! This module provides functions to work efficiently with environment variables.

fn get_rustc_version() -> anyhow::Result<String> {
Ok(String::from_utf8(
std::process::Command::new("rustc")
.arg("--version")
.output()?
.stdout,
)?.trim().to_string())
}

#[must_use]
pub fn get_all_environment_variables() -> anyhow::Result<std::collections::HashMap<&'static str, String>> {
let mut environment = std::collections::HashMap::new();
environment.insert("RUSTC_VERSION", get_rustc_version()?);
environment.insert(
"COMPILATION_DATE_AND_TIME",
chrono::offset::Local::now().format("%+").to_string(),
);
environment.insert("KERNEL_VERSION", "unknown".to_string());
// environment.insert("LOG_LEVEL", log::max_level().to_string());
environment.insert("LOG_LEVEL", "trace".to_string());

Ok(environment)
}
1 change: 1 addition & 0 deletions code/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@

pub mod arguments;
mod command;
mod environment;
3 changes: 3 additions & 0 deletions code/uncore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,7 @@ autotests = false
[build-dependencies]

[dependencies]
ansi_rgb = "0.2.0"
log = "0.4.20"
owo-colors = "3.5.0"
rgb = "0.8.36"
1 change: 1 addition & 0 deletions code/uncore/gdb/init.gdb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set mi-async
set architecture riscv
set pagination off
set print asm-demangle on

file code/target/riscv64gc-unknown-none-elf/debug/uncore
symbol-file code/target/riscv64gc-unknown-none-elf/debug/uncore
Expand Down
60 changes: 60 additions & 0 deletions code/uncore/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: GPL-3.0-or-later

// ? GLOBAL CRATE ATTRIBUTES AND DOCUMENTATION
// ? ---------------------------------------------------------------------

// This crate does not and cannot use the standard library.
#![no_std]
// As this is no ordinary program, we have a special entry-point,
// which is not the `main()` function.
#![no_main]
// Clippy lint target one. Enables all lints that are on by
// default (correctness, suspicious, style, complexity, perf) .
#![deny(clippy::all)]
// Clippy lint target two. Enables lints which are rather strict
// or have occasional false positives.
#![deny(clippy::nursery)]
// Clippy lint target three. Enables new lints that are still
// under development
#![deny(clippy::pedantic)]
// Clippy lint target four. Enable lints for the cargo manifest
// file, a.k.a. Cargo.toml.
#![deny(clippy::cargo)]
#![allow(clippy::multiple_crate_versions)]
// Lint target for code documentation. This lint enforces code
// documentation on every code item.
#![deny(missing_docs)]
#![deny(clippy::missing_docs_in_private_items)]
// Lint target for code documentation. When running `rustdoc`,
// show an error when using broken links.
#![deny(rustdoc::broken_intra_doc_links)]

//! # The `unCORE` Operating System Kernel Library
//!
//! This is `unCORE`, an operating system kernel completely written in pure, idiomatic and
//! clean Rust. This "crate" provides the library and actual modules for the kernel.

// ? UNSTABLE FEATURES
// ? ---------------------------------------------------------------------

#![feature(panic_info_message)]

// ? MODULES and GLOBAL / CRATE-LEVEL FUNCTIONS
// ? ---------------------------------------------------------------------

// extern crate alloc;

/// ### The Core Library
///
/// This module has been created to give the kernel source code a
/// well-defined structure and layout. The `library` module is used as
/// the child of the `src/lib.rs` "crate", not of `src/main.rs`. This
/// is important, and we are not allowed to mix them up.
mod library;

pub use library::{
arch,
log,
};

pub use crate::panic_on_error as __must_not_fail;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
//! TODO

pub mod uart;

pub fn init() {
/// TODO
pub fn init() -> Result<(), &'static str> {
let mut my_uart = uart::Uart::new(0x1_000_0000);
my_uart.init();

Ok(())
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
// uart.rs
// UART routines and driver

//! TODO

use core::convert::TryInto;
use core::fmt::Write;
use core::fmt::Error;

/// TODO
#[derive(Debug)]
pub struct Uart {
base_address: usize,
}
Expand All @@ -19,8 +23,10 @@ impl Write for Uart {
}

impl Uart {
pub fn new(base_address: usize) -> Self { Uart { base_address } }
/// TODO
pub const fn new(base_address: usize) -> Self { Uart { base_address } }

/// TODO
pub fn init(&mut self) {
let ptr = self.base_address as *mut u8;
unsafe {
Expand Down Expand Up @@ -86,6 +92,7 @@ impl Uart {
}
}

/// TODO
pub fn put(&mut self, c: u8) {
let ptr = self.base_address as *mut u8;
unsafe {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,17 @@ pub fn exit_kernel(code: u32) -> ! {
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
if let Some(p) = info.location() {
crate::println!(
"thread 'X' paniced at {}:{}: {}",
p.file(),
p.line(),
if let Some(message) = info.message() {
message.as_str().unwrap_or("no message provided")
} else {
"no message provided"
}
);
if let Some(message) = info.message() {
log::error!("thread 'X' panicked at {}:{}: {:?}", p.file(), p.line(), message);
} else {
log::error!(
"thread 'X' panicked at {}:{}: no message provided",
p.file(),
p.line(),
);
};
} else {
crate::println!("aborting due to panic (no information available)");
log::error!("thread 'X' panicked: no information available");
}

exit_kernel(10);
Expand Down
Loading

0 comments on commit 57aaec0

Please sign in to comment.