forked from LearningOS/template-2024a-rcore
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
debian@utm
committed
Nov 4, 2024
1 parent
9053c74
commit 0b517ad
Showing
8 changed files
with
294 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ version = "0.1.0" | |
edition = "2021" | ||
|
||
[dependencies] | ||
log = "0.4" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# Building | ||
TARGET := riscv64gc-unknown-none-elf | ||
MODE := release | ||
KERNEL_ELF := target/$(TARGET)/$(MODE)/os | ||
KERNEL_BIN := $(KERNEL_ELF).bin | ||
DISASM_TMP := target/$(TARGET)/$(MODE)/asm | ||
|
||
# Building mode argument | ||
ifeq ($(MODE), release) | ||
MODE_ARG := --release | ||
endif | ||
|
||
# BOARD | ||
BOARD := qemu | ||
SBI ?= rustsbi | ||
BOOTLOADER := ../bootloader/$(SBI)-$(BOARD).bin | ||
|
||
# KERNEL ENTRY | ||
KERNEL_ENTRY_PA := 0x80200000 | ||
|
||
# Binutils | ||
OBJDUMP := rust-objdump --arch-name=riscv64 | ||
OBJCOPY := rust-objcopy --binary-architecture=riscv64 | ||
|
||
# Disassembly | ||
DISASM ?= -x | ||
|
||
build: env $(KERNEL_BIN) | ||
|
||
env: | ||
(rustup target list | grep "riscv64gc-unknown-none-elf (installed)") || rustup target add $(TARGET) | ||
cargo install cargo-binutils | ||
rustup component add rust-src | ||
rustup component add llvm-tools-preview | ||
|
||
$(KERNEL_BIN): kernel | ||
@$(OBJCOPY) $(KERNEL_ELF) --strip-all -O binary $@ | ||
|
||
kernel: | ||
@echo Platform: $(BOARD) | ||
@cargo build $(MODE_ARG) | ||
|
||
clean: | ||
@cargo clean | ||
|
||
disasm: kernel | ||
@$(OBJDUMP) $(DISASM) $(KERNEL_ELF) | less | ||
|
||
disasm-vim: kernel | ||
@$(OBJDUMP) $(DISASM) $(KERNEL_ELF) > $(DISASM_TMP) | ||
@vim $(DISASM_TMP) | ||
@rm $(DISASM_TMP) | ||
|
||
run: run-inner | ||
|
||
run-inner: build | ||
@qemu-system-riscv64 \ | ||
-machine virt \ | ||
-nographic \ | ||
-bios $(BOOTLOADER) \ | ||
-device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY_PA) | ||
|
||
debug: build | ||
@tmux new-session -d \ | ||
"qemu-system-riscv64 -machine virt -nographic -bios $(BOOTLOADER) -device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY_PA) -s -S" && \ | ||
tmux split-window -h "riscv64-unknown-elf-gdb -ex 'file $(KERNEL_ELF)' -ex 'set arch riscv:rv64' -ex 'target remote localhost:1234'" && \ | ||
tmux -2 attach-session -d | ||
|
||
gdbserver: build | ||
@qemu-system-riscv64 -machine virt -nographic -bios $(BOOTLOADER) -device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY_PA) -s -S | ||
|
||
gdbclient: | ||
@riscv64-unknown-elf-gdb -ex 'file $(KERNEL_ELF)' -ex 'set arch riscv:rv64' -ex 'target remote localhost:1234' | ||
|
||
.PHONY: build env kernel clean disasm disasm-vim run-inner gdbserver gdbclient |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
//ref:: https://github.com/andre-richter/qemu-exit | ||
use core::arch::asm; | ||
|
||
const EXIT_SUCCESS: u32 = 0x5555; // Equals `exit(0)`. qemu successful exit | ||
|
||
const EXIT_FAILURE_FLAG: u32 = 0x3333; | ||
const EXIT_FAILURE: u32 = exit_code_encode(1); // Equals `exit(1)`. qemu failed exit | ||
const EXIT_RESET: u32 = 0x7777; // qemu reset | ||
|
||
pub trait QEMUExit { | ||
/// Exit with specified return code. | ||
/// | ||
/// Note: For `X86`, code is binary-OR'ed with `0x1` inside QEMU. | ||
fn exit(&self, code: u32) -> !; | ||
|
||
/// Exit QEMU using `EXIT_SUCCESS`, aka `0`, if possible. | ||
/// | ||
/// Note: Not possible for `X86`. | ||
fn exit_success(&self) -> !; | ||
|
||
/// Exit QEMU using `EXIT_FAILURE`, aka `1`. | ||
fn exit_failure(&self) -> !; | ||
} | ||
|
||
/// RISCV64 configuration | ||
pub struct RISCV64 { | ||
/// Address of the sifive_test mapped device. | ||
addr: u64, | ||
} | ||
|
||
/// Encode the exit code using EXIT_FAILURE_FLAG. | ||
const fn exit_code_encode(code: u32) -> u32 { | ||
(code << 16) | EXIT_FAILURE_FLAG | ||
} | ||
|
||
impl RISCV64 { | ||
/// Create an instance. | ||
pub const fn new(addr: u64) -> Self { | ||
RISCV64 { addr } | ||
} | ||
} | ||
|
||
impl QEMUExit for RISCV64 { | ||
/// Exit qemu with specified exit code. | ||
fn exit(&self, code: u32) -> ! { | ||
// If code is not a special value, we need to encode it with EXIT_FAILURE_FLAG. | ||
let code_new = match code { | ||
EXIT_SUCCESS | EXIT_FAILURE | EXIT_RESET => code, | ||
_ => exit_code_encode(code), | ||
}; | ||
|
||
unsafe { | ||
asm!( | ||
"sw {0}, 0({1})", | ||
in(reg)code_new, in(reg)self.addr | ||
); | ||
|
||
// For the case that the QEMU exit attempt did not work, transition into an infinite | ||
// loop. Calling `panic!()` here is unfeasible, since there is a good chance | ||
// this function here is the last expression in the `panic!()` handler | ||
// itself. This prevents a possible infinite loop. | ||
loop { | ||
asm!("wfi", options(nomem, nostack)); | ||
} | ||
} | ||
} | ||
|
||
fn exit_success(&self) -> ! { | ||
self.exit(EXIT_SUCCESS); | ||
} | ||
|
||
fn exit_failure(&self) -> ! { | ||
self.exit(EXIT_FAILURE); | ||
} | ||
} | ||
|
||
const VIRT_TEST: u64 = 0x100000; | ||
|
||
pub const QEMU_EXIT_HANDLE: RISCV64 = RISCV64::new(VIRT_TEST); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
//! SBI console driver, for text output | ||
use crate::sbi::console_putchar; | ||
use core::fmt::{self, Write}; | ||
|
||
struct Stdout; | ||
|
||
impl Write for Stdout { | ||
fn write_str(&mut self, s: &str) -> fmt::Result { | ||
for c in s.chars() { | ||
console_putchar(c as usize); | ||
} | ||
Ok(()) | ||
} | ||
} | ||
|
||
pub fn print(args: fmt::Arguments) { | ||
Stdout.write_fmt(args).unwrap(); | ||
} | ||
|
||
/// Print! to the host console using the format string and arguments. | ||
#[macro_export] | ||
macro_rules! print { | ||
($fmt: literal $(, $($arg: tt)+)?) => { | ||
$crate::console::print(format_args!($fmt $(, $($arg)+)?)) | ||
} | ||
} | ||
|
||
/// Println! to the host console using the format string and arguments. | ||
#[macro_export] | ||
macro_rules! println { | ||
($fmt: literal $(, $($arg: tt)+)?) => { | ||
$crate::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,18 @@ | ||
use core::panic::PanicInfo; | ||
use crate::sbi::shutdown; | ||
|
||
#[panic_handler] | ||
fn panic(_info: &PanicInfo) -> ! { | ||
loop {} | ||
/// panic handler | ||
fn panic(info: &PanicInfo) -> ! { | ||
if let Some(location) = info.location() { | ||
println!( | ||
"[kernel] Panicked at {}:{} {}", | ||
location.file(), | ||
location.line(), | ||
info.message().unwrap() | ||
); | ||
} else { | ||
println!("[kernel] Panicked: {}", info.message().unwrap()); | ||
} | ||
shutdown() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
//! Global logger | ||
|
||
use log::{Level, LevelFilter, Log, Metadata, Record}; | ||
|
||
/// a simple logger | ||
struct SimpleLogger; | ||
|
||
impl Log for SimpleLogger { | ||
fn enabled(&self, _metadata: &Metadata) -> bool { | ||
true | ||
} | ||
fn log(&self, record: &Record) { | ||
if !self.enabled(record.metadata()) { | ||
return; | ||
} | ||
let color = match record.level() { | ||
Level::Error => 31, // Red | ||
Level::Warn => 93, // BrightYellow | ||
Level::Info => 34, // Blue | ||
Level::Debug => 32, // Green | ||
Level::Trace => 90, // BrightBlack | ||
}; | ||
println!( | ||
"\u{1B}[{}m[{:>5}] {}\u{1B}[0m", | ||
color, | ||
record.level(), | ||
record.args(), | ||
); | ||
} | ||
fn flush(&self) {} | ||
} | ||
|
||
/// initiate logger | ||
pub fn init() { | ||
static LOGGER: SimpleLogger = SimpleLogger; | ||
log::set_logger(&LOGGER).unwrap(); | ||
log::set_max_level(match option_env!("LOG") { | ||
Some("ERROR") => LevelFilter::Error, | ||
Some("WARN") => LevelFilter::Warn, | ||
Some("INFO") => LevelFilter::Info, | ||
Some("DEBUG") => LevelFilter::Debug, | ||
Some("TRACE") => LevelFilter::Trace, | ||
_ => LevelFilter::Off, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters