基于sbi服务的输出和关机, Makefile文件的整理

ch1
zhangxinyu 2 years ago
parent b27b29d1df
commit ed66d2b399

@ -6,3 +6,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
# 设置release模式下保存调试信息
[profile.release]
debug=true

@ -1,10 +1,11 @@
TARGET := riscv64gc-unknown-none-elf
KERNEL_ENTRY := 0x80200000
MODE := release
KERNEL_ELF := target/$(TARGET)/$(MODE)/os
KERNEL_BIN := $(KERNEL_ELF).bin
SYMBOL_MAP := target/system.map
QEMU_CMD_PATH := /Users/zhangxinyu/Downloads/qemu-7.0.0/build/qemu-system-riscv64
QEMU_PID = $(shell ps aux | grep "[q]emu-system' | awk '{print $$2}")
OBJDUMP := rust-objdump --arch-name=riscv64
OBJCOPY := rust-objcopy --binary-architecture=riscv64
@ -13,24 +14,38 @@ RUST_FLAGS += -Cforce-frame-pointers=yes # 强制编译器生成帧指针
RUST_FLAGS:=$(strip ${RUST_FLAGS})
# 编译elf文件
build:
build_elf: clean
CARGO_BUILD_RUSTFLAGS="$(RUST_FLAGS)" \
cargo build --$(MODE) --target=$(TARGET)
# 导出一个符号表, 供我们查看
$(SYMBOL_MAP):build_elf
nm $(KERNEL_ELF) | sort > $(SYMBOL_MAP)
# 丢弃内核可执行elf文件中的元数据得到内核镜像
$(KERNEL_BIN): build
$(KERNEL_BIN): build_elf
@$(OBJCOPY) $(KERNEL_ELF) --strip-all -O binary $@
run:build $(KERNEL_BIN)
debug:build_elf $(KERNEL_BIN) $(SYMBOL_MAP) kill
$(QEMU_CMD_PATH) \
-machine virt \
-nographic \
-display none \
-daemonize \
-bios ../bootloader/rustsbi-qemu.bin \
-device loader,file=$(KERNEL_ELF),addr=$(KERNEL_ENTRY) \
-device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY) \
-s -S
run:build_elf $(KERNEL_BIN) $(SYMBOL_MAP) kill
$(QEMU_CMD_PATH) \
-machine virt \
-nographic \
-bios ../bootloader/rustsbi-qemu.bin \
-device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY)
clean:
rm -rf ./target
rm -rf ./target*
kill:
-kill -9 $(QEMU_PID)

@ -1,5 +1,15 @@
.section .text.entry
.globl _start // _start
_start:
li x1, 100
la sp, boot_stack_top
call rust_main
// .bss.stack link .bss
.section .bss.stack
.globl boot_stack_lower_bound //
.globl boot_stack_top //
boot_stack_lower_bound:
.space 4096 * 16
boot_stack_top:

@ -1 +1,2 @@
pub mod panic;
pub mod console;

@ -0,0 +1,33 @@
use crate::sbi::console_put_char;
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_put_char(c as usize);
}
Ok(())
}
}
// 用函数包装一下, 表示传进来的参数满足Arguments trait, 然后供宏调用
pub fn print(args: fmt::Arguments) {
Stdout.write_fmt(args).unwrap();
}
#[macro_export] // 导入这个文件即可使用这些宏
macro_rules! print {
($fmt: literal $(, $($arg: tt)+)?) => {
$crate::console::print(format_args!($fmt $(, $($arg)+)?));
}
}
#[macro_export]
macro_rules! println {
($fmt: literal $(, $($arg: tt)+)?) => {
$crate::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?));
}
}

@ -1,8 +1,21 @@
use core::panic::PanicInfo;
use crate::println;
use crate::sbi::shutdown;
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
fn panic(info: &PanicInfo) -> ! {
if let Some(location) = info.location() {
println!(
"Panicked at {}:{} {}",
location.file(),
location.line(),
info.message().unwrap()
);
} else {
println!("Panicked: {}", info.message().unwrap());
}
shutdown();
loop {
}
}

@ -32,7 +32,7 @@ SECTIONS
. = ALIGN(4K);
edata = .;
.bss : {
*(.bss.stack)
*(.bss.stack) /* 全局符号 sbss 和 ebss 分别指向 .bss 段除 .bss.stack 以外的起始和终止地址(.bss.stack是我们在entry.asm中定义的栈) */
sbss = .;
*(.bss .bss.*)
*(.sbss .sbss.*)

@ -1,11 +1,39 @@
#![feature(panic_info_message)]
#![no_std]
#![no_main]
mod lang_items;
use core::arch::global_asm;
use sbi::{console_put_char, shutdown};
use lang_items::console;
mod lang_items;
mod sbi;
// 汇编脚本引入, 调整内核的内存布局之后, 会跳入到 rust_main中执行
global_asm!(include_str!("entry.asm"));
// fn main() {
//
// // println!("Hello, world!");
// }
#[no_mangle]
pub fn rust_main(){
init_bss();
println!("hello world");
let mut a = 123;
a = 234;
a = 345;
println!("hello world {:?}", a);
panic!("my panic");
}
/// ## 初始化bss段
///
fn init_bss() {
extern "C" {
static mut sbss: u64;
static mut ebss: u64;
}
unsafe {
(sbss..ebss).for_each(|p| (p as *mut u8).write_unaligned(0))
}
}

@ -0,0 +1,40 @@
use core::arch::asm;
// legacy extensions: ignore fid
const SBI_SET_TIMER: usize = 0;
const SBI_CONSOLE_PUTCHAR: usize = 1;
const SBI_CONSOLE_GETCHAR: usize = 2;
const SBI_CLEAR_IPI: usize = 3;
const SBI_SEND_IPI: usize = 4;
const SBI_REMOTE_FENCE_I: usize = 5;
const SBI_REMOTE_SFENCE_VMA: usize = 6;
const SBI_REMOTE_SFENCE_VMA_ASID: usize = 7;
// system reset extension
const SRST_EXTENSION: usize = 0x53525354;
const SBI_SHUTDOWN: usize = 0;
#[inline(always)]
fn sbi_call(eid: usize, fid: usize, arg0: usize, arg1: usize, arg2: usize) -> usize {
let mut ret;
unsafe {
asm!(
"ecall",
inlateout("x10") arg0 => ret,
in("x11") arg1,
in("x12") arg2,
in("x16") fid,
in("x17") eid,
);
}
ret
}
pub fn console_put_char(c: usize) {
sbi_call(SBI_CONSOLE_PUTCHAR, 0, c, 0, 0);
}
pub fn shutdown() -> ! {
sbi_call(SRST_EXTENSION, SBI_SHUTDOWN, 0, 0, 0);
panic!("It should shutdown!")
}
Loading…
Cancel
Save