From ea750a1d1fa373eb649b273e49df83c67e577a1b Mon Sep 17 00:00:00 2001 From: Programmer Date: Wed, 30 Oct 2024 12:43:26 +0800 Subject: [PATCH] =?UTF-8?q?chore(os):=20=E5=88=A0=E9=99=A4=20ch1=20?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E7=9A=84=20os=20=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 进度更新:构建用户态执行环境,准备切换到 Linux 环境。 --- .DS_Store | Bin 0 -> 6148 bytes bootloader/.DS_Store | Bin 0 -> 6148 bytes os/.cargo/config.toml | 8 ++--- os/Cargo.toml | 6 ---- os/Makefile | 75 --------------------------------------- os/src/boards/qemu.rs | 79 ------------------------------------------ os/src/console.rs | 34 ------------------ os/src/entry.asm | 12 ------- os/src/lang_items.rs | 18 ++-------- os/src/linker.ld | 48 ------------------------- os/src/logging.rs | 45 ------------------------ os/src/main.rs | 76 ++-------------------------------------- os/src/sbi.rs | 33 ------------------ 13 files changed, 7 insertions(+), 427 deletions(-) create mode 100644 .DS_Store create mode 100644 bootloader/.DS_Store delete mode 100644 os/Makefile delete mode 100644 os/src/boards/qemu.rs delete mode 100644 os/src/console.rs delete mode 100644 os/src/entry.asm delete mode 100644 os/src/linker.ld delete mode 100644 os/src/logging.rs delete mode 100644 os/src/sbi.rs diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..62796f80ffadc75a40fecfae79f81867bec1e556 GIT binary patch literal 6148 zcmeHK&2G~`5S~o~aatiFQKVjwEOAYP3n>!f;-<-=5^$&y8~_EocBxgzTg6Fph$7_- z@4zc?u!lVB8%#ziL_e&E(yDYNLR9!BrdWYTYJ zAIf|brg<_{4r!dg`bR^uibR_y}en}oxXVLHQn~J z=d)SedHDFr%j5oeHpt~ywR#fBS4!>~yn=72+*cXwl6H~Da$-z@r(mc>1B#cJ`2mkI zGhJAo(7DQjr|``vDf@^=OFlJvMMrcIE-rDcv9q@f&2RuNIA5(!{vkT?@li{n+urg+=rTPYxmFFd9YcUF% zR&Iy^a|WEP8=BuvYZ?E1C()#&+#djmjxstO1vNi#3Q!;&oOoQHj?aei14I-kXeiKFvS-)v z>?%{lF#ucbZ_a=Yz>@BWR}XXZ=k7B*sEiTmJmVPy?r?%f+|H`MPdK;36ZYi3O!)WA zoyK_&m)qU-u-y$&3v7tzZ(&@?q<|EV0#ZNpiAO-%F0=8IRtyg@d>aDYv^IqHN8~TT_ oHp&^I6%(TsbK|Y}_)A^$HJ|r|V`9*m4?0ml0"] edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] -log = "0.4" -[profile.release] -debug = true diff --git a/os/Makefile b/os/Makefile deleted file mode 100644 index d97b21c8..00000000 --- a/os/Makefile +++ /dev/null @@ -1,75 +0,0 @@ -# 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 diff --git a/os/src/boards/qemu.rs b/os/src/boards/qemu.rs deleted file mode 100644 index 285be40f..00000000 --- a/os/src/boards/qemu.rs +++ /dev/null @@ -1,79 +0,0 @@ -//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); diff --git a/os/src/console.rs b/os/src/console.rs deleted file mode 100644 index f7d13ac8..00000000 --- a/os/src/console.rs +++ /dev/null @@ -1,34 +0,0 @@ -//! 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)+)?)) - } -} diff --git a/os/src/entry.asm b/os/src/entry.asm deleted file mode 100644 index 3a9990f9..00000000 --- a/os/src/entry.asm +++ /dev/null @@ -1,12 +0,0 @@ - .section .text.entry - .globl _start -_start: - la sp, boot_stack_top - call rust_main - - .section .bss.stack - .globl boot_stack_lower_bound -boot_stack_lower_bound: - .space 4096 * 16 - .globl boot_stack_top -boot_stack_top: \ No newline at end of file diff --git a/os/src/lang_items.rs b/os/src/lang_items.rs index e8cf681a..c03b9538 100644 --- a/os/src/lang_items.rs +++ b/os/src/lang_items.rs @@ -1,20 +1,6 @@ -//! The panic handler - -use crate::sbi::shutdown; use core::panic::PanicInfo; #[panic_handler] -/// 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() +fn panic(_info: &PanicInfo) -> ! { + loop {} } diff --git a/os/src/linker.ld b/os/src/linker.ld deleted file mode 100644 index 8bcce1a7..00000000 --- a/os/src/linker.ld +++ /dev/null @@ -1,48 +0,0 @@ -OUTPUT_ARCH(riscv) -ENTRY(_start) -BASE_ADDRESS = 0x80200000; - -SECTIONS -{ - . = BASE_ADDRESS; - skernel = .; - - stext = .; - .text : { - *(.text.entry) - *(.text .text.*) - } - - . = ALIGN(4K); - etext = .; - srodata = .; - .rodata : { - *(.rodata .rodata.*) - *(.srodata .srodata.*) - } - - . = ALIGN(4K); - erodata = .; - sdata = .; - .data : { - *(.data .data.*) - *(.sdata .sdata.*) - } - - . = ALIGN(4K); - edata = .; - .bss : { - *(.bss.stack) - sbss = .; - *(.bss .bss.*) - *(.sbss .sbss.*) - } - - . = ALIGN(4K); - ebss = .; - ekernel = .; - - /DISCARD/ : { - *(.eh_frame) - } -} \ No newline at end of file diff --git a/os/src/logging.rs b/os/src/logging.rs deleted file mode 100644 index f6f0b696..00000000 --- a/os/src/logging.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! 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, - }); -} diff --git a/os/src/main.rs b/os/src/main.rs index a5619b53..c841033e 100644 --- a/os/src/main.rs +++ b/os/src/main.rs @@ -1,79 +1,9 @@ -//! The main module and entrypoint -//! -//! The operating system and app also starts in this module. Kernel code starts -//! executing from `entry.asm`, after which [`rust_main()`] is called to -//! initialize various pieces of functionality [`clear_bss()`]. (See its source code for -//! details.) -//! -//! We then call [`println!`] to display `Hello, world!`. - -#![deny(missing_docs)] -#![deny(warnings)] #![no_std] #![no_main] -#![feature(panic_info_message)] - -use core::arch::global_asm; -use log::*; - -#[macro_use] -mod console; mod lang_items; -mod logging; -mod sbi; - -#[path = "boards/qemu.rs"] -mod board; +// println!("Hello, world!"); -global_asm!(include_str!("entry.asm")); - -/// clear BSS segment -pub fn clear_bss() { - extern "C" { - fn sbss(); - fn ebss(); - } - (sbss as usize..ebss as usize).for_each(|a| unsafe { (a as *mut u8).write_volatile(0) }); -} - -/// the rust entry-point of os #[no_mangle] -pub fn rust_main() -> ! { - extern "C" { - fn stext(); // begin addr of text segment - fn etext(); // end addr of text segment - fn srodata(); // start addr of Read-Only data segment - fn erodata(); // end addr of Read-Only data ssegment - fn sdata(); // start addr of data segment - fn edata(); // end addr of data segment - fn sbss(); // start addr of BSS segment - fn ebss(); // end addr of BSS segment - fn boot_stack_lower_bound(); // stack lower bound - fn boot_stack_top(); // stack top - } - clear_bss(); - logging::init(); - println!("[kernel] Hello, world!"); - trace!( - "[kernel] .text [{:#x}, {:#x})", - stext as usize, - etext as usize - ); - debug!( - "[kernel] .rodata [{:#x}, {:#x})", - srodata as usize, erodata as usize - ); - info!( - "[kernel] .data [{:#x}, {:#x})", - sdata as usize, edata as usize - ); - warn!( - "[kernel] boot_stack top=bottom={:#x}, lower_bound={:#x}", - boot_stack_top as usize, boot_stack_lower_bound as usize - ); - error!("[kernel] .bss [{:#x}, {:#x})", sbss as usize, ebss as usize); - - use crate::board::QEMUExit; - crate::board::QEMU_EXIT_HANDLE.exit_success(); // CI autotest success - //crate::board::QEMU_EXIT_HANDLE.exit_failure(); // CI autoest failed +extern "C" fn _start() { + // loop {} } diff --git a/os/src/sbi.rs b/os/src/sbi.rs deleted file mode 100644 index 35702f0e..00000000 --- a/os/src/sbi.rs +++ /dev/null @@ -1,33 +0,0 @@ -//! SBI call wrappers - -use core::arch::asm; - -const SBI_CONSOLE_PUTCHAR: usize = 1; - -/// general sbi call -#[inline(always)] -fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize { - let mut ret; - unsafe { - asm!( - "li x16, 0", - "ecall", - inlateout("x10") arg0 => ret, - in("x11") arg1, - in("x12") arg2, - in("x17") which, - ); - } - ret -} - -/// use sbi call to putchar in console (qemu uart handler) -pub fn console_putchar(c: usize) { - sbi_call(SBI_CONSOLE_PUTCHAR, c, 0, 0); -} - -use crate::board::QEMUExit; -/// use sbi call to shutdown the kernel -pub fn shutdown() -> ! { - crate::board::QEMU_EXIT_HANDLE.exit_failure(); -}