初始化内核(其实就是把ch1的src复制过来)
parent
d8d5955b60
commit
4ebf1a742c
@ -0,0 +1,51 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
RUST_FLAGS := -Clink-arg=-Tsrc/linker.ld # 使用我们自己的链接脚本
|
||||||
|
RUST_FLAGS += -Cforce-frame-pointers=yes # 强制编译器生成帧指针
|
||||||
|
RUST_FLAGS:=$(strip ${RUST_FLAGS})
|
||||||
|
|
||||||
|
# 编译elf文件
|
||||||
|
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_elf
|
||||||
|
@$(OBJCOPY) $(KERNEL_ELF) --strip-all -O binary $@
|
||||||
|
|
||||||
|
|
||||||
|
debug:build_elf $(KERNEL_BIN) $(SYMBOL_MAP) kill
|
||||||
|
$(QEMU_CMD_PATH) \
|
||||||
|
-machine virt \
|
||||||
|
-display none \
|
||||||
|
-daemonize \
|
||||||
|
-bios ../bootloader/rustsbi-qemu.bin \
|
||||||
|
-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*
|
||||||
|
|
||||||
|
kill:
|
||||||
|
-kill -9 $(QEMU_PID)
|
||||||
|
|
@ -0,0 +1,15 @@
|
|||||||
|
.section .text.entry
|
||||||
|
.globl _start // 声明_start是全局符号
|
||||||
|
_start:
|
||||||
|
la sp, boot_stack_top_bound
|
||||||
|
call rust_main
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 声明栈空间 后续 .bss.stack 会被link脚本链接到 .bss段
|
||||||
|
.section .bss.stack
|
||||||
|
.globl boot_stack_lower_bound // 栈低地址公开为全局符号
|
||||||
|
.globl boot_stack_top_bound // 栈高地址公开为全局符号
|
||||||
|
boot_stack_lower_bound:
|
||||||
|
.space 4096 * 16
|
||||||
|
boot_stack_top_bound:
|
@ -0,0 +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)+)?));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
use core::panic::PanicInfo;
|
||||||
|
use crate::println;
|
||||||
|
use crate::sbi::shutdown;
|
||||||
|
|
||||||
|
#[panic_handler]
|
||||||
|
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();
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
OUTPUT_ARCH(riscv) /* 目标平台 */
|
||||||
|
ENTRY(_start) /* 设置程序入口点为entry.asm中定义的全局符号 */
|
||||||
|
BASE_ADDRESS = 0x80200000; /* 一个常量, 我们的kernel将来加载到这个物理地址 */
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = BASE_ADDRESS; /* 我们对 . 进行赋值, 调整接下来的段的开始位置放在我们定义的常量出 */
|
||||||
|
/* skernel = .;*/
|
||||||
|
|
||||||
|
stext = .; /* .text段的开始位置 */
|
||||||
|
.text : { /* 表示生成一个为 .text的段, 花括号内按照防止顺序表示将输入文件中的哪些段放在 当前.text段中 */
|
||||||
|
*(.text.entry) /* entry.asm中, 我们自己定义的.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 和 ebss 分别指向 .bss 段除 .bss.stack 以外的起始和终止地址(.bss.stack是我们在entry.asm中定义的栈) */
|
||||||
|
sbss = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(.sbss .sbss.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
. = ALIGN(4K);
|
||||||
|
ebss = .;
|
||||||
|
ekernel = .;
|
||||||
|
|
||||||
|
/DISCARD/ : {
|
||||||
|
*(.eh_frame)
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,41 @@
|
|||||||
fn main() {
|
#![feature(panic_info_message)]
|
||||||
println!("Hello, world!");
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
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"));
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn stext();
|
||||||
|
fn etext();
|
||||||
|
fn sbss();
|
||||||
|
fn ebss();
|
||||||
|
fn boot_stack_top_bound();
|
||||||
|
fn boot_stack_lower_bound();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn rust_main(){
|
||||||
|
init_bss();
|
||||||
|
|
||||||
|
println!("stext: {:#x}, etext: {:#x}", stext as usize, etext as usize);
|
||||||
|
println!("sbss: {:#x}, ebss: {:#x}", sbss as usize, ebss as usize);
|
||||||
|
println!("boot_stack_top_bound: {:#x}, boot_stack_lower_bound: {:#x}", boot_stack_top_bound as usize, boot_stack_lower_bound as usize);
|
||||||
|
|
||||||
|
panic!("my panic");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ## 初始化bss段
|
||||||
|
///
|
||||||
|
fn init_bss() {
|
||||||
|
unsafe {
|
||||||
|
(sbss as usize..ebss as usize).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…
Reference in New Issue