mirror of
https://github.com/panpaul/tiny_os
synced 2024-09-20 09:45:19 +08:00
init
This commit is contained in:
commit
4736cfcb4e
2
.cargo/config.toml
Normal file
2
.cargo/config.toml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[build]
|
||||||
|
target = "riscv64imac-unknown-none-elf"
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/target
|
91
Cargo.lock
generated
Normal file
91
Cargo.lock
generated
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bit_field"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "raw-cpuid"
|
||||||
|
version = "10.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sbi-rt"
|
||||||
|
version = "0.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8c113c53291db8ac141e01f43224ed488b8d6001ab66737b82e04695a43a42b7"
|
||||||
|
dependencies = [
|
||||||
|
"sbi-spec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sbi-spec"
|
||||||
|
version = "0.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6d4027cf9bb591a9fd0fc0e283be6165c5abe96cb73e9f0e24738c227f425377"
|
||||||
|
dependencies = [
|
||||||
|
"static_assertions",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_assertions"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tiny_os"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"sbi-rt",
|
||||||
|
"uart_16550",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uart_16550"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6dc00444796f6c71f47c85397a35e9c4dbf9901902ac02386940d178e2b78687"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"rustversion",
|
||||||
|
"x86",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "x86"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2781db97787217ad2a2845c396a5efe286f87467a5810836db6d74926e94a385"
|
||||||
|
dependencies = [
|
||||||
|
"bit_field",
|
||||||
|
"bitflags",
|
||||||
|
"raw-cpuid",
|
||||||
|
]
|
26
Cargo.toml
Normal file
26
Cargo.toml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
[package]
|
||||||
|
name = "tiny_os"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["arch_riscv64", "board_virt"]
|
||||||
|
arch_riscv64 = []
|
||||||
|
arch_arm = []
|
||||||
|
arch_x86 = []
|
||||||
|
board_default = []
|
||||||
|
board_virt = []
|
||||||
|
board_thead = []
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
sbi-rt = { version = "0.0.2", features = ["legacy"] }
|
||||||
|
uart_16550 = "0.3"
|
||||||
|
log = "0.4"
|
23
build.rs
Normal file
23
build.rs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
fn main() {
|
||||||
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
|
|
||||||
|
struct TargetConfiguration {
|
||||||
|
target: &'static str,
|
||||||
|
lds: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
const TARGET_CONFIGURATIONS: &[TargetConfiguration] = &[TargetConfiguration {
|
||||||
|
target: "riscv64",
|
||||||
|
lds: "src/arch/riscv/boot/linker64.ld",
|
||||||
|
}];
|
||||||
|
|
||||||
|
let target = std::env::var("TARGET").unwrap();
|
||||||
|
for cfg in TARGET_CONFIGURATIONS {
|
||||||
|
if target.starts_with(cfg.target) {
|
||||||
|
println!("cargo:rustc-link-arg=-T{}", cfg.lds);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("Unsupported target: {}", target);
|
||||||
|
}
|
2
rust-toolchain.toml
Normal file
2
rust-toolchain.toml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
72
src/arch/io.rs
Normal file
72
src/arch/io.rs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
use core::fmt::Write;
|
||||||
|
|
||||||
|
pub struct RawConsole;
|
||||||
|
|
||||||
|
pub trait Printer: Write {
|
||||||
|
fn put_char(c: char);
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn put_str(s: &str) {
|
||||||
|
for c in s.chars() {
|
||||||
|
Self::put_char(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn put_line(s: &str) {
|
||||||
|
Self::put_str(s);
|
||||||
|
Self::put_char('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
fn put_num(mut num: usize) {
|
||||||
|
if num == 0 {
|
||||||
|
Self::put_char('0');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let digits = "0123456789".as_bytes();
|
||||||
|
let mut buf = [0u8; 10];
|
||||||
|
let mut i = 0;
|
||||||
|
|
||||||
|
while num != 0 {
|
||||||
|
buf[i] = digits[num % 10];
|
||||||
|
num /= 10;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[..i]
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.for_each(|c| Self::put_char(*c as char));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn put_hex(mut num: usize) {
|
||||||
|
if num == 0 {
|
||||||
|
Self::put_str("0x0");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let alphabet = "0123456789abcdef".as_bytes();
|
||||||
|
let mut buf = [0u8; 8];
|
||||||
|
let mut i = 0;
|
||||||
|
|
||||||
|
while num != 0 {
|
||||||
|
buf[i] = alphabet[num % 16];
|
||||||
|
num /= 16;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::put_str("0x");
|
||||||
|
buf[..i]
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.for_each(|c| Self::put_char(*c as char));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Write for RawConsole {
|
||||||
|
fn write_str(&mut self, s: &str) -> core::fmt::Result {
|
||||||
|
Self::put_str(s);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
18
src/arch/lowlevel.rs
Normal file
18
src/arch/lowlevel.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
pub struct Hardware;
|
||||||
|
|
||||||
|
pub trait LowLevel {
|
||||||
|
fn halt() {}
|
||||||
|
|
||||||
|
fn shutdown(_failure: bool) -> ! {
|
||||||
|
Self::halt();
|
||||||
|
|
||||||
|
#[allow(clippy::empty_loop)]
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reset(_failure: bool) -> ! {
|
||||||
|
panic!("Reset is not implemented for this architecture");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn disable_interrupt() {}
|
||||||
|
}
|
10
src/arch/mod.rs
Normal file
10
src/arch/mod.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// Basic IO
|
||||||
|
pub mod io;
|
||||||
|
|
||||||
|
// Low Level
|
||||||
|
pub mod lowlevel;
|
||||||
|
|
||||||
|
// Arch Level
|
||||||
|
#[cfg(feature = "arch_riscv64")]
|
||||||
|
#[path = "riscv/mod.rs"]
|
||||||
|
mod riscv;
|
3
src/arch/riscv/board/virt/mod.rs
Normal file
3
src/arch/riscv/board/virt/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub const UART0_BASE: usize = 0x1000_0000;
|
||||||
|
|
||||||
|
pub mod printer;
|
17
src/arch/riscv/board/virt/printer.rs
Normal file
17
src/arch/riscv/board/virt/printer.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
use crate::arch::io::{Printer, RawConsole};
|
||||||
|
|
||||||
|
impl Printer for RawConsole {
|
||||||
|
#[inline]
|
||||||
|
fn put_char(c: char) {
|
||||||
|
let uart = super::UART0_BASE as *mut char;
|
||||||
|
unsafe { uart.write_volatile(c) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn put_str(s: &str) {
|
||||||
|
let uart = super::UART0_BASE as *mut char;
|
||||||
|
for c in s.chars() {
|
||||||
|
unsafe { uart.write_volatile(c) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
52
src/arch/riscv/boot/linker64.ld
Normal file
52
src/arch/riscv/boot/linker64.ld
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
OUTPUT_ARCH(riscv)
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
BASE_ADDRESS = 0x80200000;
|
||||||
|
|
||||||
|
MEMORY {
|
||||||
|
DRAM : ORIGIN = BASE_ADDRESS, LENGTH = 16M
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
. = BASE_ADDRESS;
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
__text_start = .;
|
||||||
|
*(.text.entry)
|
||||||
|
*(.text .text.*)
|
||||||
|
__text_end = .;
|
||||||
|
} > DRAM
|
||||||
|
|
||||||
|
.rodata : {
|
||||||
|
. = ALIGN(8);
|
||||||
|
__rodata_start = .;
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.srodata .srodata.*)
|
||||||
|
__rodata_end = .;
|
||||||
|
} > DRAM
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
. = ALIGN(8);
|
||||||
|
__data_start = .;
|
||||||
|
*(.data .data.*)
|
||||||
|
*(.sdata .sdata.*)
|
||||||
|
__data_end = .;
|
||||||
|
} > DRAM
|
||||||
|
|
||||||
|
.stack : {
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.boot_stack)
|
||||||
|
} > DRAM
|
||||||
|
|
||||||
|
.bss : {
|
||||||
|
. = ALIGN(8);
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(.sbss .sbss.*)
|
||||||
|
__bss_end = .;
|
||||||
|
} > DRAM
|
||||||
|
|
||||||
|
/DISCARD/ : {
|
||||||
|
*(.eh_frame)
|
||||||
|
}
|
||||||
|
}
|
43
src/arch/riscv/entry.rs
Normal file
43
src/arch/riscv/entry.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#[naked]
|
||||||
|
#[no_mangle]
|
||||||
|
#[link_section = ".text.entry"]
|
||||||
|
unsafe extern "C" fn _start(hart_id: usize, device_tree_addr: usize) -> ! {
|
||||||
|
// simplest starter
|
||||||
|
// no stack here
|
||||||
|
|
||||||
|
const STACK_SIZE: usize = 4096 * 16;
|
||||||
|
#[link_section = ".boot_stack"]
|
||||||
|
static mut STACK: [u8; STACK_SIZE] = [0u8; STACK_SIZE];
|
||||||
|
|
||||||
|
core::arch::asm!(
|
||||||
|
"la sp, {stack} + {stack_size}",
|
||||||
|
"j {main}",
|
||||||
|
stack_size = const STACK_SIZE,
|
||||||
|
stack = sym STACK,
|
||||||
|
main = sym pre_main,
|
||||||
|
options(noreturn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" fn pre_main(hart_id: usize, device_tree_addr: usize) -> ! {
|
||||||
|
unsafe { zero_bss() }
|
||||||
|
|
||||||
|
// TODO: initialize page table
|
||||||
|
|
||||||
|
crate::entry::rust_main(hart_id, device_tree_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
static mut __bss_start: u8;
|
||||||
|
static mut __bss_end: u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn zero_bss() {
|
||||||
|
let mut cur = &mut __bss_start as *mut u8;
|
||||||
|
let end = &mut __bss_end as *mut u8;
|
||||||
|
|
||||||
|
while cur < end {
|
||||||
|
cur.write_volatile(0);
|
||||||
|
cur = cur.add(1);
|
||||||
|
}
|
||||||
|
}
|
10
src/arch/riscv/io.rs
Normal file
10
src/arch/riscv/io.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#[allow(unused_imports)]
|
||||||
|
use crate::arch::io::{Printer, RawConsole};
|
||||||
|
|
||||||
|
#[cfg(feature = "board_default")]
|
||||||
|
impl Printer for RawConsole {
|
||||||
|
fn put_char(c: char) {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
sbi_rt::legacy::console_putchar(c as usize);
|
||||||
|
}
|
||||||
|
}
|
37
src/arch/riscv/lowlevel.rs
Normal file
37
src/arch/riscv/lowlevel.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
use crate::arch::lowlevel::{Hardware, LowLevel};
|
||||||
|
use log::error;
|
||||||
|
|
||||||
|
impl LowLevel for Hardware {
|
||||||
|
#[inline]
|
||||||
|
fn halt() {
|
||||||
|
unsafe { core::arch::asm!("wfi") }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn shutdown(failure: bool) -> ! {
|
||||||
|
Self::disable_interrupt();
|
||||||
|
|
||||||
|
if failure {
|
||||||
|
sbi_rt::system_reset(sbi_rt::Shutdown, sbi_rt::SystemFailure);
|
||||||
|
} else {
|
||||||
|
sbi_rt::system_reset(sbi_rt::Shutdown, sbi_rt::NoReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// in case system_reset failed
|
||||||
|
Self::halt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn reset(failure: bool) -> ! {
|
||||||
|
if failure {
|
||||||
|
sbi_rt::system_reset(sbi_rt::ColdReboot, sbi_rt::SystemFailure);
|
||||||
|
} else {
|
||||||
|
sbi_rt::system_reset(sbi_rt::WarmReboot, sbi_rt::NoReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
error!("[riscv/lowlevel] system_reset failed, shutdown instead");
|
||||||
|
Self::shutdown(true);
|
||||||
|
}
|
||||||
|
}
|
7
src/arch/riscv/mod.rs
Normal file
7
src/arch/riscv/mod.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#[cfg(feature = "board_virt")]
|
||||||
|
#[path = "board/virt/mod.rs"]
|
||||||
|
mod board;
|
||||||
|
|
||||||
|
pub mod entry;
|
||||||
|
pub mod io;
|
||||||
|
pub mod lowlevel;
|
30
src/entry.rs
Normal file
30
src/entry.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
use crate::arch::lowlevel::{Hardware, LowLevel};
|
||||||
|
use log::{error, info};
|
||||||
|
|
||||||
|
pub extern "C" fn rust_main(hart_id: usize, device_tree_addr: usize) -> ! {
|
||||||
|
crate::logging::init();
|
||||||
|
|
||||||
|
info!("[rust_main] Kernel Started");
|
||||||
|
|
||||||
|
info!("Hello World!");
|
||||||
|
info!("hart_id = {}", hart_id);
|
||||||
|
info!("device_tree_addr = {:#x}", device_tree_addr);
|
||||||
|
|
||||||
|
// TODO: setup and start scheduler
|
||||||
|
|
||||||
|
error!("[rust_main] Should not reach here! Maybe scheduler is not working?");
|
||||||
|
Hardware::shutdown(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_hello() {
|
||||||
|
const SERIAL_PORT_BASE_ADDRESS: usize = 0x1000_0000;
|
||||||
|
const HELLO: &[u8] = b"Hello World!\n";
|
||||||
|
|
||||||
|
use uart_16550::MmioSerialPort;
|
||||||
|
let mut serial_port = unsafe { MmioSerialPort::new(SERIAL_PORT_BASE_ADDRESS) };
|
||||||
|
serial_port.init();
|
||||||
|
|
||||||
|
for &byte in HELLO {
|
||||||
|
serial_port.send(byte);
|
||||||
|
}
|
||||||
|
}
|
21
src/lang.rs
Normal file
21
src/lang.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use crate::arch::lowlevel::{Hardware, LowLevel};
|
||||||
|
use core::panic::PanicInfo;
|
||||||
|
use log::error;
|
||||||
|
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(info: &PanicInfo) -> ! {
|
||||||
|
error!("[lang] Kernel panic!");
|
||||||
|
|
||||||
|
if let Some(location) = info.location() {
|
||||||
|
error!(
|
||||||
|
"[lang] Panicked: [{}:{}] {}",
|
||||||
|
location.file(),
|
||||||
|
location.line(),
|
||||||
|
info.message().unwrap(),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
error!("[lang] Panicked: {}", info.message().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
Hardware::shutdown(true);
|
||||||
|
}
|
17
src/lib.rs
Normal file
17
src/lib.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![feature(asm_const)]
|
||||||
|
#![feature(naked_functions)]
|
||||||
|
#![feature(panic_info_message)]
|
||||||
|
#![feature(fmt_internals)]
|
||||||
|
|
||||||
|
// arch
|
||||||
|
pub mod arch;
|
||||||
|
|
||||||
|
// rust language runtime
|
||||||
|
pub mod lang;
|
||||||
|
|
||||||
|
// entrypoint
|
||||||
|
pub mod entry;
|
||||||
|
|
||||||
|
// logging
|
||||||
|
pub mod logging;
|
31
src/logging.rs
Normal file
31
src/logging.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
use crate::arch::io::RawConsole;
|
||||||
|
use core::fmt::Write;
|
||||||
|
use log::{self, LevelFilter, Log, Metadata, Record};
|
||||||
|
|
||||||
|
struct SimpleLogger;
|
||||||
|
|
||||||
|
impl Log for SimpleLogger {
|
||||||
|
fn enabled(&self, _metadata: &Metadata) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log(&self, record: &Record) {
|
||||||
|
if !self.enabled(record.metadata()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RawConsole
|
||||||
|
.write_fmt(format_args!("[{}] {}\n", record.level(), record.args()))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init() {
|
||||||
|
static LOGGER: SimpleLogger = SimpleLogger;
|
||||||
|
log::set_logger(&LOGGER).unwrap();
|
||||||
|
|
||||||
|
// TODO: get log level from boot env
|
||||||
|
log::set_max_level(LevelFilter::Trace);
|
||||||
|
}
|
6
src/main.rs
Normal file
6
src/main.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
#[allow(clippy::single_component_path_imports)]
|
||||||
|
use tiny_os;
|
Loading…
Reference in New Issue
Block a user