From b27b29d1df6b4c385539da4f3678df04fd464d2e Mon Sep 17 00:00:00 2001 From: zhangxinyu <840317537@qq.com> Date: Wed, 10 May 2023 18:50:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=85=E6=A0=B8=E7=9A=84=E7=AC=AC=E4=B8=80?= =?UTF-8?q?=E6=9D=A1=E6=8C=87=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ch1/Makefile | 26 ++++++++++++++++++++----- ch1/src/entry.asm | 5 +++++ ch1/src/linker.ld | 48 +++++++++++++++++++++++++++++++++++++++++++++++ ch1/src/main.rs | 2 ++ 4 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 ch1/src/entry.asm create mode 100644 ch1/src/linker.ld diff --git a/ch1/Makefile b/ch1/Makefile index 8781051..312c6ba 100644 --- a/ch1/Makefile +++ b/ch1/Makefile @@ -1,18 +1,34 @@ TARGET := riscv64gc-unknown-none-elf -KERNEL_START := 0x80200000 +KERNEL_ENTRY := 0x80200000 MODE := release +KERNEL_ELF := target/$(TARGET)/$(MODE)/os +KERNEL_BIN := $(KERNEL_ELF).bin +QEMU_CMD_PATH := /Users/zhangxinyu/Downloads/qemu-7.0.0/build/qemu-system-riscv64 +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: - cargo build --$(MODE) --target=$(TARGET) + CARGO_BUILD_RUSTFLAGS="$(RUST_FLAGS)" \ + cargo build --$(MODE) --target=$(TARGET) -run:build - qemu-system-riscv64 \ +# 丢弃内核可执行elf文件中的元数据得到内核镜像 +$(KERNEL_BIN): build + @$(OBJCOPY) $(KERNEL_ELF) --strip-all -O binary $@ + + +run:build $(KERNEL_BIN) + $(QEMU_CMD_PATH) \ -machine virt \ -nographic \ -bios ../bootloader/rustsbi-qemu.bin \ - -device loader,file=target/$(TARGET)/$(MODE)/os.bin,addr=$(KERNEL_START) + -device loader,file=$(KERNEL_ELF),addr=$(KERNEL_ENTRY) \ + -s -S diff --git a/ch1/src/entry.asm b/ch1/src/entry.asm new file mode 100644 index 0000000..0737fbf --- /dev/null +++ b/ch1/src/entry.asm @@ -0,0 +1,5 @@ +.section .text.entry +.globl _start // 声明_start是全局符号 +_start: + li x1, 100 + diff --git a/ch1/src/linker.ld b/ch1/src/linker.ld new file mode 100644 index 0000000..7fb5178 --- /dev/null +++ b/ch1/src/linker.ld @@ -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 = .; + *(.bss .bss.*) + *(.sbss .sbss.*) + } + + . = ALIGN(4K); + ebss = .; + ekernel = .; + + /DISCARD/ : { + *(.eh_frame) + } +} \ No newline at end of file diff --git a/ch1/src/main.rs b/ch1/src/main.rs index afa1a64..e883f38 100644 --- a/ch1/src/main.rs +++ b/ch1/src/main.rs @@ -2,7 +2,9 @@ #![no_main] mod lang_items; +use core::arch::global_asm; +global_asm!(include_str!("entry.asm")); // fn main() { // // // println!("Hello, world!");