1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-25 09:26:17 +04:00

Change target arch to RISCV32IMA. Recover some dependencies.

This commit is contained in:
WangRunji 2018-07-06 23:02:10 +08:00
parent bf2ad7c6a5
commit aa22fcabde
4 changed files with 46 additions and 8 deletions

View File

@ -9,21 +9,37 @@
## Rust-RISCV
### 目标指令集RISCV32IA
### 目标指令集RISCV32IMA
target: riscv32ia_unknown_none
target: riscv32ima_unknown_none
由于工具链二进制版本尚未内置`riscv32ia_unknown_none`的target因此需提供配置文件`riscv32-blog_os.json`。
由于工具链二进制版本尚未内置target因此需提供配置文件`riscv32-blog_os.json`。
为什么要用原子指令扩展?
理想情况下目标指令集应为RISCV32G即使用全部扩展。但考虑到要把它跑在我们自己实现的CPU上指令集应该尽量精简即最好是RISCV32I。此外
* 为什么用原子指令扩展?
RustOS依赖的库中大部分都使用了Rust核心库的原子操作core::sync::atomic
如果目标指令集不支持原子操作,会导致无法编译。
然而LLVM后端尚不完全支持原子指令扩展因此这条路可能走不通需要魔改Rust标准库。
* 为什么用乘除指令扩展?
Rust核心库中fmt模块会使用乘除运算若不使用乘除指令则会依赖LLVM提供的内置函数进行软计算导致链接错误。这一问题理论上可以通过在xargo中设置依赖compiler-builtin解决。但如此操作后仍有一个函数`__mulsi3`缺失32×32。经查compiler-builtin中实现了类似的`__muldi3`函数64×64),所以理论上可以用它手动实现前者。但如此操作后,还是不对,实验表明`__muldi3`本身也是不正确的。
总之没有成功配置不使用M扩展的编译环境不过日后解决这一问题并不困难。
## 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)。
bbl-ucore使用RISCV1.9的bblucore_os_lab使用RISCV1.10的bbl。后者相比前者去掉了对内核的内存映射因此需保证虚实地址一致。
事实上ucore_os_lab中的虚实地址并不一致且没有内存映射但依然能够运行应该是由于编译器生成的所有跳转都使用相对偏移。而Rust编译器会生成绝对地址跳转因此若虚实不一致会导致非法访存。

View File

@ -7,7 +7,7 @@
"os": "none",
"arch": "riscv",
"cpu": "generic-rv32",
"features": "+a",
"features": "+m,+a",
"max-atomic-width": "32",
"linker": "ld.lld",
"linker-flavor": "ld",

20
src/io/riscv_io.rs Normal file
View File

@ -0,0 +1,20 @@
// FIXME: merge to x86_64 io
use core::fmt;
macro_rules! print {
($($arg:tt)*) => ({
$crate::io::print(format_args!($($arg)*));
});
}
macro_rules! println {
($fmt:expr) => (print!(concat!($fmt, "\n")));
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
}
pub fn print(args: fmt::Arguments) {
use arch::serial::SerialPort;
use core::fmt::Write;
SerialPort.write_fmt(args).unwrap();
}

View File

@ -23,7 +23,9 @@ pub fn panic(info: &PanicInfo) -> ! {
#[cfg(target_arch = "riscv")]
#[lang = "panic_fmt"]
unsafe extern "C" fn panic_fmt(_fmt: ::core::fmt::Arguments, _file: &'static str, _line: u32, _col: u32) -> ! {
#[no_mangle]
pub fn panic_fmt(fmt: ::core::fmt::Arguments, file: &'static str, line: u32, col: u32) -> ! {
println!("\n\nPANIC in {} at {}:{}\n {}", file, line, col, fmt);
loop {}
}