Skip to content

常见问题及解答

首先需要明确的是,本次实验中的所有操作都不应该经由 Windows 中的文件系统,请直接在虚拟机或 Linux 物理机中直接完成。

禁止直接 fork 本课程的 github 仓库

本课程要求同学们严格遵循诚信守则,禁止同学之间互相抄袭实验代码。如需建立私人 github 仓库,请将本课程仓库 clone 到本地之后,上传到自己的 private repo。禁止直接 fork 本课程的 github 仓库或直接将本课程实验相关内容上传到任何 public repo

实验提交要求

实验提交时需要同时提交代码压缩包和实验报告两个文件。

实验报告要求上传 pdf 文件,其中需要包含以下内容:

  • 实验内容及简要原理介绍
  • 实验具体过程与代码实现
  • 实验结果与分析
  • 实验中遇到的问题及解决方法
  • 思考题与心得体会
  • 对实验指导的建议(可选)

Tip

  • 在代码实现部分重点展示设计思路和核心部分代码即可,不需要大段粘贴代码
    • 如要展示代码,需以非纯文本的形式展示(需要使用代码块)
  • 思考题占有一定的分值,需要认真回答
  • 请保持实验报告清晰、简洁

为什么我把 Linux 源码放在共享文件夹或 wsl2 /mnt 下编译不出来?

这种情况下,Linux 在使用 Windows 上的文件系统。请使用 wget 等工具将 Linux 源码下载至容器内目录而非共享目录或 /mnt 目录下的任何位置,然后执行编译。

为什么 QEMU & GDB 使用 si 单指令调试遇到模式切换时无法正常执行?

在遇到诸如mret , sret等指令造成的模式切换时,si 指令会失效,可能表现为程序开始不停跑,影响对程序运行行为的判断。

一个解决方法是在程序预期跳转的位置打上断点,断点不会受到模式切换的影响,比如:

(gdb) i r sepc    
sepc        0x8000babe
(gdb) b * 0x8000babe
Breakpoint 1 at 0x8000babe
(gdb) si    # 或者使用 c
Breakpoint 1, 0x000000008000babe in _never_gonna_give_you_up ()
...

这样就可以看到断点被触发,可以继续调试了。

为什么我不能在 GDB 中使用 next 或者finish ?

这两条命令都依赖在内核中添加的调试信息,可以通过 menuconfig 进行配置添加。我们在实验中没有对这部分内容作要求,可以自行 Google 探索。

为什么我在内核中添加了 debug 信息,但是还是没法使用 next 或者finish ?

可能你在配置内核时已经添加了调试信息,但是并没有在QEMU 运行的其他部分添加。例如 SRAM 中对 march 进行配置的过程,以及 opensbi 中的所有部分,都缺少调试信息。所以才无法按照函数的层级进行调试。我们在实验中没有对这部分内容作要求,可以自行 Google 探索。

为什么 Lab1 中我的 C 语言函数的参数无法正确传入?

确认自己是否在 head.S 里的 _start 函数中正确设置了 sp,正常情况下它的值应该是 0x8020XXXX。未设置或设置错 sp 会使栈上的值不正确且无法写入。

Tip

注意检查是否将 head.S 里的 .section 改为 .text.init,如果不改的话 _traps_start 都在 .text.entry 段,此时 _traps 会被放置到 0x80200000 处,导致其先于 _start 执行;而此时还未设置 sp,故传参时会出现混乱(具体表现为 trap_handler 的所有参数均显示 2^64-1

不会找 Lab1 syscall table 怎么办?

主要有两种方法,一种是安装该架构的交叉编译工具链并编译得到预处理产物,另一种则是在某些文件中直接就有现成的 syscall table. 无论选用哪种方法都要善用搜索,查找系统调用具体放在哪个文件中。可以参考这篇文章

Tip

或许可以直接去 arch 对应架构文件夹下搜索关键词?

如何升级到 Ubuntu 24.04

请按照 How to upgrade - Ubuntu DebianUpgrade - Debian Wiki 的说明进行升级,所需命令概括如下(使用两种方式之一即可

  • 使用 Ubuntu 特有的 do-release-upgrade 命令:

    sudo apt update
    sudo apt upgrade
    sudo apt full-upgrade
    sudo do-release-upgrade
    
  • 使用 Debian 标准的升级流程:

    sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get full-upgrade
    # 修改 APT 源
    sudo apt-get clean
    sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get full-upgrade
    sudo apt-get autoremove
    

升级完成后,务必尽快重启,不论是物理机还是虚拟机(WSL、Docker

不知道如何计算 Lab3 建立映射时所需的虚拟地址 va 和大小 sz

vmlinux.lds 中有_stext , _srodata等符号,可以在代码里这样来声明它:extern char _stext[],这样就可以通过 _stext 获得其所在虚拟地址 va,并且可以通过两个段的开头符号做减法获得段的大小 sz