Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
suoyuan666 committed Nov 27, 2024
1 parent ec0e432 commit fbc8ae2
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 25 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
public/
public/
suoyuan666.github.io.code-workspace
64 changes: 42 additions & 22 deletions content/posts/xv6_riscv_read_intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ series:
- xv6-riscv_源码阅读
tags:
- Xv6_RISC-V
description: "尝试把 xv6-riscv 项目读一遍,这是前言,不包括实际代码部分"
summary: "尝试把 xv6-riscv 项目读一遍,这是前言,不包括实际代码部分"
description: "尝试把 xv6-riscv 读一遍,这是前言,不包括实际代码部分"
summary: "尝试把 xv6-riscv 读一遍,这是前言,不包括实际代码部分"
---

# xv6-riscv 源码阅读 —— 前言
Expand All @@ -22,14 +22,32 @@ summary: "尝试把 xv6-riscv 项目读一遍,这是前言,不包括实际

作为我第一个接触到的操作系统内核项目(虽然我一直使用 Gentoo Linux,但 linux kernel 的代码我又没看过),我对 xv6-riscv 还是有很多兴趣的,本身我对这些系统软件就还算感兴趣。所以有了这个系列,希望可以完整的写完,并且尽量做到适合新手。

### xv6-riscv

[xv6-riscv](https://github.com/mit-pdos/xv6-riscv) 是一个基于 RISC-V 架构的教学操作系统内核。xv6 是一个简化版的 Unix v6 操作系统,原本基于 x86 架构,xv6-riscv 则是将其移植到 RISC-V 架构上。

xv6-riscv 包含以下部分:

- 内核态
- 进程管理:实现了基本的进程调度、创建、终止和上下文切换
- 同步机制:提供了锁(spinlock)来实现进程同步
- 系统调用:提供了用户程序可以调用的系统接口,如文件操作、进程管理、内存管理等
- 中断和异常处理:包括 RISC-V 特有的异常和中断机制,处理外部设备中断、软件中断等
- 内存管理:实现了简单的虚拟内存管理和分页机制
- 文件系统:包括一个简单的文件系统,支持文件的创建、读取、写入和删除等基本操作
- 设备驱动:驱动了一些基本的硬件设备,如控制台输出(串口)、磁盘、定时器等
- 客户态
- libc:实现了一个简单的 libc,包含常见的库函数
- 用户程序:包含一些简单的用户程序,用于测试内核功能,如 init、sh、ls、cat 等

## 开发环境搭建

对于 Debian/Ubuntu or Arch Linux or WSL 大可以参考 [官方网站的命令](https://pdos.csail.mit.edu/6.1810/2024/tools.html) 安装相关软件。如果和我一样是 Gentoo Linux 的话,则是使用 [crossdev](https://wiki.gentoo.org/wiki/Crossdev) 安装这种 RISC-V 架构的编译工具链
对于 Debian/Ubuntu Arch Linux WSL 可以参考[官方网站的命令](https://pdos.csail.mit.edu/6.1810/2024/tools.html)安装相关软件。如果是 Gentoo Linux 的话,则是使用 [crossdev](https://wiki.gentoo.org/wiki/Crossdev) 安装 RISC-V 架构的编译工具

```bash
$ emerge --ask sys-devel/Crossdev
$ eselect repository create crossdev
$ crossdev -s1 --target riscv64-unknown-linux-gnu --ex-gdb
$ sudo emerge --ask sys-devel/Crossdev
$ sudo eselect repository create crossdev
$ sudo crossdev -s1 --target riscv64-unknown-linux-gnu --ex-gdb
```

这里的 `-s1` 是选择安装的级别,根据 `crossdev --help`:
Expand All @@ -53,10 +71,20 @@ Stage Options:
app-emulation/qemu virgl virtfs usbredir spice usbredirspice qemu_softmmu_targets_x86_64 qemu_softmmu_targets_riscv64
```

这里有些 USE 变量对于 xv6-riscv 没那么必要,我是因为本身日常需要装图形化的虚拟机,所以才会开这些。
这里有些 USE 变量对于 xv6-riscv 没那么必要,我是因为本身日常有虚拟机的需求,所以才会开这些。

重新编译一编就可以模拟 RISC-V 64 架构了。

如果你是 Fedora Linux,那么可以输入下面的命令安装相关工具:

```bash
$ sudo dnf install qemu-system-riscv gcc-riscv64-linux-gnu
```

## 其他

### 编译 xv6-riscv

使用下面的命令下载和编译项目:

```bash
Expand All @@ -83,7 +111,7 @@ $

输入 `Ctrl + a` 之后再输入 `x` 就可以退出 qemu,如果输入的是 `c` 而不是 `x` 则是进入 qemu 的 monitor 模式。

可以使用 `make qemu-gdb` 开启一个用于给 gdb 调试的端口,之后新开一个终端并进入这个目录执行 `riscv64-unknown-linux-gnu-gdb`(可能你的发行版的 RISC-V 64 架构的 gdb 不叫这个名字)就可以开始调试了,不过可能一开始提示这个目录的 gdbinit 脚本不能执行,你需要在 **.config/gdb** 下信任这个脚本。
可以使用 `make qemu-gdb` 开启一个用于给 gdb 调试的端口,之后新开一个终端并进入这个目录执行 `riscv64-unknown-linux-gnu-gdb`(可能你的发行版的 RISC-V 64 架构的 gdb 不叫这个名字)就可以开始调试了,不过可能一开始提示这个目录的 **.gdbinit** 脚本不能执行,你需要在 **.config/gdb** 下信任这个脚本。

这个脚本内容很简单

Expand All @@ -100,21 +128,13 @@ set riscv use-compressed-breakpoints yes

执行 `make clean` 可以清理掉编译产生的文件,只留下那些源文件。

我使用的是 neovim,所以需要用 clangd 提供更多有关 C 语言的支持。
我使用的是 `neovim`,所以需要用 `clangd` 提供更多有关 C 语言的支持。

clangd 需要 **compile_commands.json** 文件解析项目的依赖关系,所以需要安装 bear,之后执行 `bear -- make` 重新跑一遍编译,让 bear 产生这个文件,从而让 clangd 解析。
`clangd` 需要 **compile_commands.json** 文件解析项目的依赖关系,所以需要安装 bear,之后执行 `bear -- make` 重新跑一遍编译,让 bear 产生这个文件,从而让 `clangd` 解析。

如果你使用的是 Visual Studio Code,我更推荐安装 C/C++ 插件,因为需要用到 gdb 调试。

---

如果你是 Fedora Linux,那么可以输入下面的命令安装相关工具:

```bash
$ sudo dnf install qemu-system-riscv gcc-riscv64-linux-gnu
```

## make 介绍
### make 介绍

> GNU Make is a tool which controls the generation of executables and other non-source files of a program from the program's source files.
>
Expand All @@ -140,7 +160,7 @@ $K/kernel: $(OBJS) $K/kernel.ld $U/initcode

这里描述了 `$K/kernel` 这个目标的编译过程以及依赖关系。`:` 后面的就是以来关系,需要等这些文件或者是这些目标以及完成后才能开始该目标的构建。而下面缩进四个空格的则是具体的构建时候的命令了。

为什么我们启动时候是输入 `make qemu`,调试的时候是用 `make qemu-gdb`,就是因为这是 Makefile 写好的。
为什么启动虚拟机是输入 `make qemu`,调试的时候是用 `make qemu-gdb`,就是因为这是 Makefile 写好的。

```makefile
qemu: $K/kernel fs.img
Expand All @@ -154,13 +174,13 @@ qemu-gdb: $K/kernel .gdbinit fs.img
$(QEMU) $(QEMUOPTS) -S $(QEMUGDB)
```

## gdb 介绍
### gdb 介绍

> GDB, the GNU Project debugger, allows you to see what is going on `inside' another program while it executes -- or what another program was doing at the moment it crashed.
>
> GDB,GNU Project 调试器,允许您查看另一个程序在执行时的“内部”发生了什么,或者另一个程序在崩溃的时候正在做什么。

总的来说,gdb 是一个命令行版本的调试器,和大家编程中使用的调试器没什么两样。图形化的工具大多是 F5 开始调试,F7/F8 还是 F10/F11 用于步进和跳进之类的。命令行的工具把这些都用指令代替,可以更加专业全面的观察程序运行的行为。
总的来说,gdb 是一个命令行版本的调试器,和大家编程学习中使用的调试器没什么两样。图形化的工具大多是 F5 开始调试,F7/F8 还是 F10/F11 用于步进和跳进之类的。命令行的工具把这些都用指令代替,可以更加专业全面的观察程序运行的行为。

上面这段话的后者是在说 core dump,在 Linux 发行版的环境中变成经常会遇到 Segmentation fault,这时候下面可能还会附带依据 core dumped,这就意味着系统已经为这次 crash 生成了一份“核心转储”文件,可以用 gdb 打开这个文件,软件会直接在发生 crash 的指令的地方打开,方便调试。可以使用 `coredumpctl` 查看生成的核心转储文件。

Expand Down
4 changes: 2 additions & 2 deletions content/posts/xv6_riscv_read_user-sh.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ series:
- xv6-riscv_源码阅读
tags:
- Xv6_RISC-V
description: "尝试把 xv6-riscv 项目读一遍,这是用户态的 sh 的源码阅读"
summary: "尝试把 xv6-riscv 项目读一遍,这是用户态的 sh 的源码阅读"
description: "尝试把 xv6-riscv 读一遍,这是用户态的 sh 的源码阅读"
summary: "尝试把 xv6-riscv 读一遍,这是用户态的 sh 的源码阅读"
---

## 概述
Expand Down

0 comments on commit fbc8ae2

Please sign in to comment.