rCore-Tutorial-Book-v3
rCore-Tutorial-Book-v3 copied to clipboard
rCore-Tutorial-Book-v3/chapter1/4first-instruction-in-kernel2
内核第一条指令(实践篇) — rCore-Tutorial-Book-v3 3.6.0-alpha.1 文档
https://rcore-os.github.io/rCore-Tutorial-Book-v3/chapter1/4first-instruction-in-kernel2.html
虽然老师提供了连接脚本,但是该怎么获知写的程序都有哪些段需要被链接呢?
开篇提供的 vm 镜像似乎并没安装 objcopy,需要使用如下语句来安装
$ cargo install cargo-binutils
$ rustup component add llvm-tools-preview
否则可能出如下的错误
Failed to execute tool: objcopy No such file or directory (error 2)
回翻了一下开篇,发现原来是自己漏掉工具链安装那一步了 ORZ
请问 这里的 0x100c: ld t0,24(t0) 。 ld是什么意思?
请问 这里的 0x100c: ld t0,24(t0) 。 ld是什么意思?
代表是 load 指令
那请问 load指令 是指 汇编指令吗?
请问 ld t0,24(t0) 这个是什么意思呢?
请问一下为什么在终端输入cargo build后会遇到这种问题呢,把main.rs中的use core::arch::global_asm换成use core::global_asm还是不行,下面的github链接有没有找到方案
error[E0658]: use of unstable library feature 'global_asm': global_asm!
is not stable enough for use and is subject to change
--> src/main.rs:8:1
|
8 | global_asm!(include_str!("entry.asm"));
| ^^^^^^^^^^
|
= note: see issue #35119 https://github.com/rust-lang/rust/issues/35119 for more information
error[E0432]: unresolved import core::arch::global_asm
--> src/main.rs:7:5
|
7 | use core::arch::global_asm;
| ^^^^^^^^^^^^^^^^^^^^^^ no global_asm
in arch
|
= note: this could be because a macro annotated with #[macro_export]
will be exported at the root of the crate instead of the module where it is defined
help: a macro with this name exists at the root of the crate
|
7 | use core::global_asm;
| ^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0432, E0658.
For more information about an error, try rustc --explain E0432
.
error: could not compile os
To learn more, run the command again with --verbose.
@Lu-Yidan 请将Rust升级到最新版本,可以在os
目录下创建一个rust-toolchain
文件,内容为nightly-2022-01-01
。
虚拟磁盘文件未安装riscv64-unknown-elf-gdb,该怎么安装呢?
关于执行riscv64-unknown-elf-gdb后
riscv64-unknown-elf-gdb: command not found
gdb工具链下载链接已在开发环境配置中,我将其下载解压在目录:
/home/oslab/.riscv64-unknown-elf-gcc-8.3.0-2020.04.1-x86_64-linux-ubuntu14/ 具体目录根据你的情况而定
对于gdb这样一个可执行二进制文件,如何将其路径添加直环境变量中呢?
终端中输入
gedit .bashrc
添加一行
export PATH=$PATH:/home/oslab/.riscv64-unknown-elf-gcc-8.3.0-2020.04.1-x86_64-linux-ubuntu14/bin
大功告成,这样就可以直接使用该命令啦
------------------ 原始邮件 ------------------ 发件人: @.>; 发送时间: 2022年1月16日(星期天) 晚上8:05 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [rcore-os/rCore-Tutorial-Book-v3] rCore-Tutorial-Book-v3/chapter1/4first-instruction-in-kernel2 (Issue #96)
虚拟磁盘文件未安装riscv64-unknown-elf-gdb,该怎么安装呢?
— Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android. You are receiving this because you were mentioned.Message ID: @.***>
关于内核的加载这里有一个疑问,如果说按照这里内核是直接进行从文件中进行拷贝过去,那么是否会出现文件中相应片段大小小于实际在内存中占用大小的情况?(因为传统elf文件是有可能出现片段在文件中占用大小小于实际内存中大小的)
@ZENOTME 据我所知,这种情况一般只出现在零初始化的.bss
段,在ELF中可能有元数据记录该段的位置而不会真的有一个全零的数据段。可以看到我们在链接脚本中将.bss
段置于最后,在加载的时候并不会拷贝一个全零数据段,而在内核中我们会通过clear_bss
将其清零。
根据文档riscv-spec-20191213.pdf中Ch2和Ch25
0x1000: auipc t0,0x0
Add Upper Immediate PC: rd = pc + imm[31:12]
U型指令
把当前指令的地址加上立即数这里的立即数对应的是寄存器中的高20位,相对于imm<<12,然后保存到寄存器t0
0x1004: addi a2,t0,40
ADD Immeiate: rd = rs1 + imm[11:0]
执行后 a2 = 0x1028
I型指令
0x1008: csrr a0,mhartid
伪指令
Control State Register Read: a0 = mhartid
mhartid寄存器,当前hart的id#0
0x100c: ld a1,32(t0)
Load Double-word: rd = rs1 + imm[11:0]
I型号指令
从地址rs1+imm[11:0]出加载4个字节的数据到寄存器rd
$a1 = [4bytes@0x1020]
0x1010: ld t0,24(t0)
$t0 = [4bytes@1018] 这里是1018出开始加载4个字节,小端内存序,所以寄存器中的数据应该是0x0080_0000
0x1014: jr t0
伪指令,jr rs <=> jalr x0, 0(rs),Jump register
意思是跳转到t0位置
注意这里寄存器的名字,
1.开头的t代表temporary,一般用于临时变量,t0~6
2.开头的a代表argument,表示是用于函数调用传入的参数,a0~7
3这里用到了a0,a1,a2,a0是hartid,a1和a2代表了个啥不是很确定
jr应该像个函数调用传的参数是hartid : a0,unknown: a1,unkown : a2,
4.没有用到堆栈,目测是8个以内参数和7个以内临时变量的函数吧
汇编我不熟,有错误请指正
@konpoe 很棒!大体上正确,帮你修改了一下格式。有一个问题是0x1010
的指令执行完毕后t0
应该是0x8000_0000
而不是0x0080_0000
,这个在前面讲解Qemu启动流程的时候有提到过。可能是小端序理解有误,从Qemu上可以看到以0x101a
开头两字节的数据是0x8000
,按照字节分开看,0x101a
和0x101b
的数据分别是0x00
和0x80
。然后0x1018
和0x1019
的数据都是0x00
。这样ld
后的结果就是0x8000_0000
。
谢谢指正
我仔细检查了一下,ld加载双字(8字节),所以$a1 应该是[8bytes@0x1020]后面的t0应该是[8bytes@0x1018]。
应该是这8个字节的数据:
0x1018: unimp 0x101a: 0x8000 0x101c: unimp 0x101e: unimp
按照之前的教程,t0的值应该是0x0000_0000_8000_0000, 小端序是没问题的,就是gdb显示的问题。其他的好像问题不大。
我马虎过头了。
弱弱问一下,为什么我使用objcopy strip之后的文件为什么会是0size呢……Orz? 错误信息如下:
llvm-objcopy --strip-all target/riscv64gc-unknown-none-elf/release/os -O binary target/riscv64gc-unknown-none-elf/release/os.bin
stat /home/senki/Documents/xv6-rust/os/target/riscv64gc-unknown-none-elf/release/os.bin
File: /home/senki/Documents/xv6-rust/os/target/riscv64gc-unknown-none-elf/release/os.bin
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 8,3 Inode: 17961165 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 1000/ senki) Gid: ( 1000/ senki)
Access: 2022-01-30 00:08:19.840070679 +0800
Modify: 2022-01-30 00:08:19.130054408 +0800
Change: 2022-01-30 00:08:19.130054408 +0800
Birth: 2022-01-30 00:08:19.130054408 +0800
我使用rust-objcopy无法运行,所以使用了llvm-objcopy(虽然说cargo-binutils也只是对这些工具做了封装)。 所有的依赖项也是安装好了的。
但是生成的os文件 大小是正常的(1000左右)
我搞清楚了!原来是: stext = .; 11 .text : { 12 *(.text.entry) 13 (.text .text.) 14 } 15 16 . = ALIGN(4K); 17 etext = .;
12行与13行没有缩进(我以为不缩进功能也是一样的) 想问一下,这里是为什么需要缩进呢?
演示代码
$ (gdb) si
0x0000000000001004 in ?? ()
$ (gdb) si
0x0000000000001008 in ?? ()
$ (gdb) si
0x000000000000100c in ?? ()
$ (gdb) si
0x0000000000001010 in ?? ()
$ (gdb) p/x $t0
$1 = 0x80000000
$ (gdb) si
0x0000000080000000 in ?? ()
应该是五次si后才能得到
$ (gdb) p/x $t0
$1 = 0x80000000
实机演示:
(gdb) x/10i $pc
=> 0x1000: auipc t0,0x0
0x1004: addi a2,t0,40
0x1008: csrr a0,mhartid
0x100c: ld a1,32(t0)
0x1010: ld t0,24(t0)
0x1014: jr t0
0x1018: unimp
0x101a: 0x8000
0x101c: unimp
0x101e: unimp
(gdb) si
0x0000000000001004 in ?? ()
(gdb)
0x0000000000001008 in ?? ()
(gdb)
0x000000000000100c in ?? ()
(gdb)
0x0000000000001010 in ?? ()
(gdb) p/x $t0
$1 = 0x1000
(gdb) si
0x0000000000001014 in ?? ()
(gdb) p/x $t0
$2 = 0x80000000
Mac OS 执行 riscv64-unknown-elf-gdb 命令报:
riscv64-unknown-elf-gdb: command not found
解决办法:
- 安装 homebrew 2.执行 sudo xcode-select --install 3.执行 brew tap riscv/riscv 3.执行 brew install riscv-tools
@Lu-Yidan 的方法有用,不过得注意:
1、gedit .bashrc
的前要先cd ~
让终端回到home位置。
2、export PATH=$PATH:/home/oslab/.riscv64-unknown-elf-gcc-8.3.0-2020.04.1-x86_64-linux-ubuntu14/bin
可能在文件浏览器中不会显示.../oslab/...
但实际是要加上的。
3、添加export PATH=$PATH:/home/osla...x-ubuntu14/bin
时,要添加在最后一行。
4、编辑完.bashrc并保存后,需要重启terminal,才会生效。
关于riscv64-unknown-elf-gdb,对于我而言除了@Lu-Yidan 的方法,还要对riscv64-unknown-elf-gcc-8.3.0-2020.04.1-x86_64-linux-ubuntu14 chmod -R 777 一下
麻烦请问启动 Qemu 并加载 RustSBI 和内核镜像出现以下报错可能是什么原因呢?
qemu-system-riscv64 \
-machine virt
-nographic
-bios ../bootloader/rustsbi-qemu.bin
-device loader,file=target/riscv64gc-unknown-none-elf/release/os.bin,addr=0x80200000
-s -S qemu-system-riscv64: Unable to load the RISC-V firmware "../bootloader/rustsbi-qemu.bin"
麻烦请问启动 Qemu 并加载 RustSBI 和内核镜像出现以下报错可能是什么原因呢?
qemu-system-riscv64 \
-machine virt -nographic -bios ../bootloader/rustsbi-qemu.bin -device loader,file=target/riscv64gc-unknown-none-elf/release/os.bin,addr=0x80200000 -s -S qemu-system-riscv64: Unable to load the RISC-V firmware "../bootloader/rustsbi-qemu.bin"
可能是目录下没有bootloader文件,可以从ch1分支的代码中复制一份
ch1 ..为什么我没看到有 ch1 的分支。。
原来我down错仓库了。。把 python 文档的那个仓库下载了。。。抱歉,找到了
stat target/riscv64gc-unknown-none-elf/release/os File: target/riscv64gc-unknown-none-elf/release/os Size: 1016 Blocks: 8 IO Block: 4096 regular file
为什么我的是 Size: 5240
,而课件里的是 Size: 1016
...
$ stat target/riscv64gc-unknown-none-elf/release/os
File: target/riscv64gc-unknown-none-elf/release/os
Size: 5240 Blocks: 16 IO Block: 4096 regular file
Device: a5h/165d Inode: 1187295 Links: 2
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2022-03-28 13:02:28.913213000 +0000
Modify: 2022-03-27 15:00:03.103959000 +0000
Change: 2022-03-27 15:00:03.112959000 +0000
Birth: -
wsl2环境遇到riscv64-unknown-elf-gdb缺失问题,可以按如下方法解决,具体思路是下载与编译工具链,并添加到环境变量中。
# 下载预编译文件
wget https://static.dev.sifive.com/dev-tools/freedom-tools/v2020.12/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz
后面是解压和添加环境变量,最后需要source ~/.bashrc
。