From 211aeff8418daf026bafd0a3226ea9556117beb4 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Wed, 4 Jul 2018 16:23:11 +0800 Subject: [PATCH] Add bbl as bootloader --- Cargo.toml | 3 ++ Makefile | 46 ++++++++++++++++++++-------- README.md | 10 +++++++ build.rs | 14 +++++---- docs/RISCV.md | 15 ++++++++++ src/arch/riscv32/boot/entry.S | 18 +++++++++++ src/arch/riscv32/boot/linker.ld | 53 +++++++++++++++++++++++++++++++++ src/arch/riscv32/mod.rs | 3 ++ src/lib.rs | 11 +++++++ 9 files changed, 154 insertions(+), 19 deletions(-) create mode 100644 docs/RISCV.md create mode 100644 src/arch/riscv32/boot/entry.S create mode 100644 src/arch/riscv32/boot/linker.ld create mode 100644 src/arch/riscv32/mod.rs diff --git a/Cargo.toml b/Cargo.toml index 8f11e94..a23d0e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,5 +38,8 @@ simple-filesystem = { git = "https://github.com/wangrunji0408/SimpleFileSystem-R bit-allocator = { path = "crate/bit-allocator" } ucore-memory = { path = "crate/memory" } +[target.riscv32i-unknown-none.dependencies] +riscv = { git = "https://github.com/riscv-rust/riscv" } + [build-dependencies] cc = "1.0" diff --git a/Makefile b/Makefile index 283cb01..6a8343d 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ # Examples: # make run Run in debug +# make justrun Run in debug without build # make run int=1 Run with interrupt info by QEMU # make run mode=release Run in release # make run LOG=error Run with log level: error @@ -8,15 +9,15 @@ # make asm Open the deassemble file of the last build # make clean Clean -arch ?= riscv +arch ?= riscv32 kernel := build/kernel-$(arch).bin iso := build/os-$(arch).iso target ?= $(arch)-blog_os -ifeq ($(arch), riscv) +ifeq ($(arch), riscv32) target := riscv32i-unknown-none endif mode ?= debug -rust_os := target/$(target)/$(mode)/librust_ucore.a +rust_lib := target/$(target)/$(mode)/librust_ucore.a boot_src := src/arch/$(arch)/boot linker_script := $(boot_src)/linker.ld @@ -28,6 +29,9 @@ user_image_files := $(wildcard user/*.img) user_object_files := $(patsubst user/%.img, build/user/%.o, $(user_image_files)) SFSIMG := user/ucore32.img qemu_opts := -cdrom $(iso) -smp 4 -serial mon:stdio -drive file=$(SFSIMG),media=disk,cache=writeback +ifeq ($(arch), riscv32) +qemu_opts := -machine virt -kernel $(iso) -nographic +endif features := use_apic LOG ?= debug @@ -65,17 +69,18 @@ else uname := $(shell uname) endif -ifeq ($(uname), Linux) -prefix := -else +ifeq ($(uname), Darwin) prefix := x86_64-elf- endif +ifeq ($(arch), riscv32) +prefix := riscv32-unknown-elf- +endif ld := $(prefix)ld objdump := $(prefix)objdump cc := $(prefix)gcc -.PHONY: all clean run iso kernel build asm doc +.PHONY: all clean run iso build asm doc justrun all: $(kernel) @@ -85,7 +90,9 @@ clean: doc: @cargo rustdoc -- --document-private-items -run: $(iso) +run: $(iso) justrun + +justrun: @qemu-system-$(arch) $(qemu_opts) || [ $$? -eq 11 ] # run qemu and assert it exit 11 debug: $(iso) @@ -98,22 +105,35 @@ build: iso asm: @$(objdump) -dS $(kernel) | less -$(iso): $(kernel) $(grub_cfg) +build/os-x86_64.iso: $(kernel) $(grub_cfg) @mkdir -p build/isofiles/boot/grub @cp $(kernel) build/isofiles/boot/kernel.bin @cp $(grub_cfg) build/isofiles/boot/grub @grub-mkrescue -o $(iso) build/isofiles 2> /dev/null @rm -r build/isofiles -$(kernel): kernel $(rust_os) $(assembly_object_files) $(linker_script) +build/os-riscv32.iso: $(kernel) + @cd riscv-pk && \ + mkdir -p build && \ + cd build && \ + ../configure \ + --enable-logo \ + --prefix=$(RISCV) \ + --disable-fp-emulation \ + --host=riscv32-unknown-elf \ + --with-payload=../../build/kernel-riscv32.bin && \ + make && \ + cp bbl ../../$@ + +$(kernel): $(rust_lib) $(assembly_object_files) $(linker_script) @$(ld) -n --gc-sections -T $(linker_script) -o $(kernel) \ - $(assembly_object_files) $(rust_os) + $(assembly_object_files) $(rust_lib) -kernel: +$(rust_lib): @RUST_TARGET_PATH=$(shell pwd) CC=$(cc) xargo build $(build_args) # compile assembly files -build/arch/$(arch)/boot/%.o: $(boot_src)/%.asm +build/arch/x86_64/boot/%.o: $(boot_src)/%.asm @mkdir -p $(shell dirname $@) @nasm -felf64 $< -o $@ diff --git a/README.md b/README.md index 543c508..52b1b1a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,15 @@ # RustOS for x86_64 SMP +## Port to RISCV (WIP) + +2018年计算机系统综合实验 + +[Project Wiki](http://os.cs.tsinghua.edu.cn/oscourse/csproject2018/group05) + +[Documents](./docs/RISCV.md) + +## Summary + [![Build Status](https://travis-ci.org/wangrunji0408/RustOS.svg?branch=master)](https://travis-ci.org/wangrunji0408/RustOS) A project of THU OS2018 spring. diff --git a/build.rs b/build.rs index 763d733..00b9309 100644 --- a/build.rs +++ b/build.rs @@ -4,12 +4,14 @@ use std::fs::File; use std::io::{Write, Result}; fn main() { - cc::Build::new() - .file("src/arch/x86_64/driver/apic/lapic.c") - .file("src/arch/x86_64/driver/keyboard/keyboard.c") - .flag("-mcmodel=large") - .compile("cobj"); - gen_vector_asm().unwrap(); + if std::env::var("TARGET").unwrap().starts_with("x86_64") { + cc::Build::new() + .file("src/arch/x86_64/driver/apic/lapic.c") + .file("src/arch/x86_64/driver/keyboard/keyboard.c") + .flag("-mcmodel=large") + .compile("cobj"); + gen_vector_asm().unwrap(); + } } fn gen_vector_asm() -> Result<()> { diff --git a/docs/RISCV.md b/docs/RISCV.md new file mode 100644 index 0000000..f24810a --- /dev/null +++ b/docs/RISCV.md @@ -0,0 +1,15 @@ +# RISCV 移植记录 + +## 开发环境 + +* [riscv-rust/rust](https://github.com/riscv-rust/rust):使用[官方发布的二进制版本+源码](https://github.com/riscv-rust/rust/releases/tag/riscv-rust-1.26.0-1-dev) +* [riscv-gnu-toolchain](https://github.com/riscv/riscv-gnu-toolchain):使用OS2018腾讯云中使用的预编译版本 + +具体配置过程详见[Dockerfile](../riscv-env/Dockerfile) + +## BootLoader + +参考[bbl-ucore](https://github.com/ring00/bbl-ucore)及后续的[ucore_os_lab for RISCV32](https://github.com/chyyuu/ucore_os_lab/tree/riscv32-priv-1.10),使用[bbl](https://github.com/riscv/riscv-pk.git)作为BootLoader。 + +然而官方版本和bbl-ucore中的fork版本都无法正常编译,使用的是[ucore_os_lab中的修改版本](https://github.com/chyyuu/ucore_os_lab/tree/riscv32-priv-1.10/riscv-pk)。 + diff --git a/src/arch/riscv32/boot/entry.S b/src/arch/riscv32/boot/entry.S new file mode 100644 index 0000000..55da8e4 --- /dev/null +++ b/src/arch/riscv32/boot/entry.S @@ -0,0 +1,18 @@ + .section .text,"ax",%progbits + .globl kern_entry +kern_entry: + # la sp, bootstacktop + auipc sp, %hi(bootstacktop) + addi sp, sp, %lo(bootstacktop) + + # tail rust_main + auipc t1, %hi(rust_main) + jalr zero, t1, %lo(rust_main) + +.section .data + .align 12 #PGSHIFT + .global bootstack +bootstack: + .space 4096 * 8 #KSTACKSIZE + .global bootstacktop +bootstacktop: diff --git a/src/arch/riscv32/boot/linker.ld b/src/arch/riscv32/boot/linker.ld new file mode 100644 index 0000000..0fa7490 --- /dev/null +++ b/src/arch/riscv32/boot/linker.ld @@ -0,0 +1,53 @@ +/* Copy from bbl-ucore : https://ring00.github.io/bbl-ucore */ + +/* Simple linker script for the ucore kernel. + See the GNU ld 'info' manual ("info ld") to learn the syntax. */ + +OUTPUT_ARCH(riscv) +ENTRY(kern_entry) + +BASE_ADDRESS = 0xC0000000; + +SECTIONS +{ + /* Load the kernel at this address: "." means the current address */ + . = BASE_ADDRESS; + + .text : { + *(.text.kern_entry .text .stub .text.* .gnu.linkonce.t.*) + } + + PROVIDE(etext = .); /* Define the 'etext' symbol to this value */ + + .rodata : { + *(.rodata .rodata.* .gnu.linkonce.r.*) + } + + /* Adjust the address for the data segment to the next page */ + . = ALIGN(0x1000); + + /* The data segment */ + .data : { + *(.data) + *(.data.*) + } + + .sdata : { + *(.sdata) + *(.sdata.*) + } + + PROVIDE(edata = .); + + .bss : { + *(.bss) + *(.bss.*) + *(.sbss*) + } + + PROVIDE(end = .); + + /DISCARD/ : { + *(.eh_frame .note.GNU-stack) + } +} diff --git a/src/arch/riscv32/mod.rs b/src/arch/riscv32/mod.rs new file mode 100644 index 0000000..6de00ec --- /dev/null +++ b/src/arch/riscv32/mod.rs @@ -0,0 +1,3 @@ +global_asm!(include_str!("boot/entry.S")); + +extern crate riscv; \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 9c22321..9c6a1fd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,7 @@ #![feature(panic_implementation)] #![feature(panic_info_message)] #![feature(universal_impl_trait)] +#![feature(global_asm)] #![no_std] @@ -94,6 +95,16 @@ mod sync; #[path = "arch/x86_64/mod.rs"] mod arch; +#[cfg(target_arch = "riscv")] +#[path = "arch/riscv32/mod.rs"] +mod arch; + +#[no_mangle] +#[cfg(target_arch = "riscv")] +pub extern fn rust_main() -> ! { + loop {} +} + /// The entry point of Rust kernel #[no_mangle] #[cfg(target_arch = "x86_64")]