rCore-Tutorial-Book-v3 icon indicating copy to clipboard operation
rCore-Tutorial-Book-v3 copied to clipboard

rCore-Tutorial-Book-v3/chapter1/4first-instruction-in-kernel2

Open utterances-bot opened this issue 3 years ago • 92 comments

内核第一条指令(实践篇) — rCore-Tutorial-Book-v3 3.6.0-alpha.1 文档

https://rcore-os.github.io/rCore-Tutorial-Book-v3/chapter1/4first-instruction-in-kernel2.html

utterances-bot avatar Jan 05 '22 08:01 utterances-bot

虽然老师提供了连接脚本,但是该怎么获知写的程序都有哪些段需要被链接呢?

CENZONGJUN avatar Jan 05 '22 08:01 CENZONGJUN

开篇提供的 vm 镜像似乎并没安装 objcopy,需要使用如下语句来安装 $ cargo install cargo-binutils $ rustup component add llvm-tools-preview 否则可能出如下的错误 Failed to execute tool: objcopy No such file or directory (error 2)

bswaterb avatar Jan 05 '22 13:01 bswaterb

回翻了一下开篇,发现原来是自己漏掉工具链安装那一步了 ORZ

bswaterb avatar Jan 05 '22 13:01 bswaterb

请问 这里的 0x100c: ld t0,24(t0) 。 ld是什么意思?

river-art avatar Jan 07 '22 08:01 river-art

请问 这里的 0x100c: ld t0,24(t0) 。 ld是什么意思?

代表是 load 指令

bswaterb avatar Jan 07 '22 08:01 bswaterb

那请问 load指令 是指 汇编指令吗?

river-art avatar Jan 07 '22 09:01 river-art

请问 ld t0,24(t0) 这个是什么意思呢?

river-art avatar Jan 07 '22 10:01 river-art

请问一下为什么在终端输入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 avatar Jan 07 '22 15:01 lu-yidan

@Lu-Yidan 请将Rust升级到最新版本,可以在os目录下创建一个rust-toolchain文件,内容为nightly-2022-01-01

wyfcyx avatar Jan 07 '22 16:01 wyfcyx

虚拟磁盘文件未安装riscv64-unknown-elf-gdb,该怎么安装呢?

Tshiyao avatar Jan 16 '22 12:01 Tshiyao

关于执行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: @.***>

lu-yidan avatar Jan 16 '22 12:01 lu-yidan

关于内核的加载这里有一个疑问,如果说按照这里内核是直接进行从文件中进行拷贝过去,那么是否会出现文件中相应片段大小小于实际在内存中占用大小的情况?(因为传统elf文件是有可能出现片段在文件中占用大小小于实际内存中大小的)

ZENOTME avatar Jan 21 '22 03:01 ZENOTME

@ZENOTME 据我所知,这种情况一般只出现在零初始化的.bss段,在ELF中可能有元数据记录该段的位置而不会真的有一个全零的数据段。可以看到我们在链接脚本中将.bss段置于最后,在加载的时候并不会拷贝一个全零数据段,而在内核中我们会通过clear_bss将其清零。

wyfcyx avatar Jan 21 '22 06:01 wyfcyx

根据文档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 avatar Jan 22 '22 02:01 konpoe

@konpoe 很棒!大体上正确,帮你修改了一下格式。有一个问题是0x1010的指令执行完毕后t0应该是0x8000_0000而不是0x0080_0000,这个在前面讲解Qemu启动流程的时候有提到过。可能是小端序理解有误,从Qemu上可以看到以0x101a开头两字节的数据是0x8000,按照字节分开看,0x101a0x101b的数据分别是0x000x80。然后0x10180x1019的数据都是0x00。这样ld后的结果就是0x8000_0000

wyfcyx avatar Jan 22 '22 06:01 wyfcyx

谢谢指正

konpoe avatar Jan 22 '22 08:01 konpoe

我仔细检查了一下,ld加载双字(8字节),所以$a1 应该是[8bytes@0x1020]后面的t0应该是[8bytes@0x1018]。
应该是这8个字节的数据: 0x1018: unimp 0x101a: 0x8000 0x101c: unimp 0x101e: unimp 按照之前的教程,t0的值应该是0x0000_0000_8000_0000, 小端序是没问题的,就是gdb显示的问题。其他的好像问题不大。 我马虎过头了。

konpoe avatar Jan 22 '22 09:01 konpoe

弱弱问一下,为什么我使用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也只是对这些工具做了封装)。 所有的依赖项也是安装好了的。

SenkiTK avatar Jan 29 '22 16:01 SenkiTK

但是生成的os文件 大小是正常的(1000左右)

SenkiTK avatar Jan 29 '22 16:01 SenkiTK

我搞清楚了!原来是: stext = .; 11 .text : { 12 *(.text.entry) 13 (.text .text.) 14 } 15 16 . = ALIGN(4K); 17 etext = .;

12行与13行没有缩进(我以为不缩进功能也是一样的) 想问一下,这里是为什么需要缩进呢?

SenkiTK avatar Jan 29 '22 16:01 SenkiTK

演示代码

$ (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

MrZLeo avatar Jan 30 '22 10:01 MrZLeo

Mac OS 执行 riscv64-unknown-elf-gdb 命令报:

riscv64-unknown-elf-gdb: command not found

解决办法:

  1. 安装 homebrew 2.执行 sudo xcode-select --install 3.执行 brew tap riscv/riscv 3.执行 brew install riscv-tools

zhangzhaoliuqun avatar Feb 24 '22 02:02 zhangzhaoliuqun

@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,才会生效。

iruhh avatar Feb 28 '22 09:02 iruhh

关于riscv64-unknown-elf-gdb,对于我而言除了@Lu-Yidan 的方法,还要对riscv64-unknown-elf-gcc-8.3.0-2020.04.1-x86_64-linux-ubuntu14 chmod -R 777 一下

wuyuesong avatar Mar 05 '22 10:03 wuyuesong

麻烦请问启动 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"

brisa7444 avatar Mar 08 '22 02:03 brisa7444

麻烦请问启动 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分支的代码中复制一份

wuyuesong avatar Mar 08 '22 02:03 wuyuesong

ch1 ..为什么我没看到有 ch1 的分支。。

kaixinbaba avatar Mar 27 '22 07:03 kaixinbaba

原来我down错仓库了。。把 python 文档的那个仓库下载了。。。抱歉,找到了

kaixinbaba avatar Mar 27 '22 07:03 kaixinbaba

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: -

kaixinbaba avatar Mar 28 '22 13:03 kaixinbaba

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

qi-xmu avatar Apr 04 '22 10:04 qi-xmu