在这门课中我们需要一个具有图形界面的Linux系统来运行NEMU这个模拟器
一般我们选择Ubuntu作为Linux系统。
之前我已经通过WSL2安装了Ubuntu系统,就直接使用,这里不再赘述。(除了WSL2安装外,还可以通过安装双系统和安装虚拟机来在Windows系统上安装Linux系统)
(通过wsl -l -v来看安装了哪些)
安装工具
在GNU/Linux中,我们可以通过一个命令下载和安装软件(这在Windows中就可能很难做到)。这是由包管理器实现的,在不同的GNU/Linux发行版中有不同的包管理器。在Ubuntu中,包管理器称为apt.
检查网络状态(确认联网正常)
打开WSL2终端,输入以下命令测试网络:
1 | ping mirrors.tuna.tsinghua.edu.cn -c 4 |
如果你能看到 64 bytes from... 的输出,说明你的 WSL Ubuntu 可以联网,支持 IPv6(最好)。
若失败,可以试IPv4测试:
1 | ping www.baidu.com -c 4 |
确认当前系统版本
输入以下命令查看当前系统版本:
1 | lsb_release -a |

例如我的就是24.04(noble)版本
换源(修改APT源文件)
在这里选择和你的Ubuntu版本相同的合适的源
**清华源**是完全兼容Ubuntu 24.04(noble)系统的,不会造成版本冲突,所以我选择使用清华源。
%% 只要使用与系统版本匹配的codename(如24.04用noble),就不会发生版本冲突【清华源提供了所有主线版本的完整安装包,包括:
- noble(24.04)
- jammy(22.04)
- focal(20.04)】%%
从 Ubuntu 23.10+(包括 24.04) 起,APT 默认采用 DEB822 格式 管理软件源,配置文件路径为:在WSL中运行以下代码,打开.source文件1
/etc/apt/sources.list.d/ubuntu.sources
%% 这里需要输入密码 %%1
sudo nano /etc/apt/sources.list.d/ubuntu.sources
会看到:

其中最下面会有如下内容(示例):
1 | Types: deb |
把URIs: http://archive.ubuntu.com/ubuntu换成URIs: http://mirrors.tuna.tsinghua.edu.cn/ubuntu
把URIs: http://security.ubuntu.com/ubuntu换成URIs: http://mirrors.tuna.tsinghua.edu.cn/ubuntu
如图:
修改完成之后保存并退出编辑器
- Ctrl + O 保存
- Enter 确认文件名
- Ctrl + X 退出
之后运行以下代码进行更新索引:1
sudo apt update
1
sudo apt upgrade
图形化设置
正常情况下安装 WSL 时已经自动完成了图形界面的配置。可以在 WSL 中安装x11-apps来测试图形界面是否正常工作。
运行以下命令:
1 | sudo apt install x11-apps |
安装完成后,运行xclock命令,如果弹出了一个时钟窗口,说明图形界面配置成功。如图:
或者运行xeyes命令,如果看到一个小窗口显示两个跟随鼠标动的眼睛,也说明成功了
安装 PA 工具
通过以下命令安装PA需要的工具:
1 | apt-get install build-essential # build-essential packages, include binary utilities, gcc, make, and so on |
安装中文输入法
(这部分好久之前实操的了,当时是按照gpt的步骤一步一步进行的,下面的大概率就是当时的做法,没有再次实操报一丝)
安装Fctix框架和中文输入法引擎
运行以下命令:
1 | sudo apt install fcitx fcitx-googlepinyin fcitx-config-gtk |
配置环境变量
执行以下命令:
1 | echo "export GTK_IM_MODULE=fcitx" >> ~/.bashrc |
刷新环境变量
执行以下命令,让当前shell会话立即生效:
1 | source ~/.bashrc |
启动输入法(首次)
在终端输入:(首先要确保图形界面转发成功,比如我用的是 MobaXterm)
1 | fcitx-autostart & # 启动 Fcitx 框架 |
等待几秒钟,会弹出一个图形窗口(Fcitx 配置中心)。
启动 Fcitx 后,再打开配置工具,图形界面下你可以:添加「Google Pinyin」输入法 ; 设置「Ctrl+Space」作为切换热键 ; 修改输入法顺序
在配置界面中添加 Google 拼音输入法
- 在窗口左下角点击
+号,打开添加输入法界面 - 搜索或从列表中找到
Google Pinyin - 选中它,点击 确定 添加
- 可选:调整输入法顺序,把
Google Pinyin放在最前面
默认情况下,**Ctrl+Space** 是中英文切换快捷键。在 Fcitx 配置窗口的上方栏中,点击Global Config→Trigger Input Method。更改为你想要的快捷键,例如Shift+Space

测试中文输入是否可用
可以运行一个图形程序来测试:
1 | gedit& |
(如果没有安装的话,按照提示安装即可)
在打开的窗口中应该会看到一个候选词框,输入拼音,可看到中文即为可以正常使用 。
检查关键工具
1 | gcc --version |
🔑 ✅🧾
配置vim
安装:vim-编辑器之神
1 | sudo apt update |
如何判断自己是否在WSL2的Ubuntu系统中安装了vim:
方法一
运行:
1 | which vim |
如果输出类似:
1 | /usr/bin/vim |
则表明系统中已经安装vim并且可以使用
如果什么都不输出,表示未安装
方法二
运行
1 | vim --version |
如果已经安装,会显示vim的版本信息如 VIM - Vi IMproved 9.0 等)
如果没有安装,会提示:
1 | Command 'vim' not found, but can be installed with: |
获取PA的源代码
在github上添加ssh key
在获取框架代码之前, 首先需要在github上添加一个ssh key
在WSL2 Ubuntu 中生成SSH密钥并copy公钥内容
(我之前没有生成过SSH密钥,所以这一步必须要进行,如果之前生成过则可以跳过)
运行:
1 | ssh-keygen -t ed25519 -C "your_email@example.com" |
然后会提示你保存路径(默认即可),然后按3次回车即可(可以不设置密码)。
公钥默认保存在:~/.ssh/id_ed25519.pub
运行:
1 | cat ~/.ssh/id_ed25519.pub |
然后复制整行内容,例如:
1 | ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMDk...... your_email@example.com |
登录 GitHub 添加 SSH key
登录GitHub,点击右上角头像 → Settings,进入左侧菜单:SSH and GPG keys,点击 New SSH key
- Title: 任意填写(如:
WSL2 Ubuntu) - Key: 粘贴你刚才复制的公钥内容
点击 Add SSH key
测试是否配置成功
在WSL2中运行:
1 | ssh -T git@github.com |
首次连接会提示:
1 | The authenticity of host 'github.com (IP)' can't be established. |
输入:yes
成功输出应为:
1 | Hi your_username! You've successfully authenticated, but GitHub does not provide shell access. |
🎉 表示 SSH 配置完成!
判断自己是否已经在 WSL2 的 Ubuntu 中生成了 SSH 密钥
在WSL2终端运行:
1 | ls -l ~/.ssh/ |
常见输出(表示已生成密钥):
1 | -rw------- 1 ffffff ffffff 464 Jul 23 id_ed25519 |
| 文件名 | 说明 |
|---|---|
id_ed25519 |
私钥(不要泄露) |
id_ed25519.pub |
公钥(可添加到 GitHub) |
获取源代码
运行以下命令来获得实验源代码:
1 | cd ~ # 回到主目录 |

~是 Linux/Unix 系统中当前用户的主目录,比如/home/yourname或/Users/yourname。**==主目录是最安全、最推荐放置个人项目的地方。==** 不应该在系统级目录(如/usr,/bin,/etc,/root)下开发实验项目,因为可能会不小心修改或破坏系统文件。所有实验开发应在用户主目录下进行,避免误伤系统。- 关于
git clone -b 2024 git@github.com:NJU-ProjectN/ics-pa.git ics2024的解释:git clone: 这是 Git 命令中用来克隆(下载)远程仓库到本地的操作。b 2024: 这是一个选项,表示在克隆仓库时,指定克隆特定的分支。-b后面跟的是分支名,这里指定了2024分支。如果该分支存在,Git 会克隆这个分支的内容,而不是默认的main或master分支。git@github.com:NJU-ProjectN/ics-pa.git: 这是远程 Git 仓库的 SSH 地址。通过 SSH 协议访问该仓库,而不是使用 HTTPS。此地址中的git@github.com指明通过 GitHub 的 SSH 服务进行访问,后面的NJU-ProjectN/ics-pa.git是仓库的用户名和仓库名。ics2024: 这是克隆下来的仓库在本地保存的目录名。在执行该命令后,仓库的文件将被下载到本地的ics2024文件夹中。
git branch -m master:==将当前分支改名为master(PA 的默认开发分支)==- 另:删除在 Windows 中使用 Git Bash 克隆的仓库,只需要删除对应的文件夹即可,不需要任何额外的 Git 操作。
Git 使用
查看当前有哪些分支
在ics2024文件夹下执行以下命令列出所有分支:
1 | git branch |
会看到现在只有一个分支叫做“master”
1 | * master |
创建并转到新分支
要创建并转到新分支newbranch,使用命令:git checkout -b newbranch
(如果转到已有分支xxbranch,使用命令:git checkout xxbranch)
我们首先==创建一个pa0分支(在ics2024下进行)==:
1 | git checkout -b pa0 |
再次运行git branch命令列出所有分支会看到:
1 | master |
在现在这种情况下,项目中所有文件的修改都将记录在pa0分支中。
修改项目文件
1 | # 打开文件: ics2024/Makefile |
查看修改状态并提交修改
查看修改状态:
1
git status
输出类似:
1
2
3On branch pa0
Changes not staged for commit:
modified: Makefile说明你修改了文件,但还没
add到 Git 暂存区。查看修改内容的具体差异:
1
git diff
输出会像这样:
1
2
3
4-STUID = 231220000
-STUNAME = 张三
+STUID = 231221234
+STUNAME = 李四表示修改了
Makefile中这两行。添加并提交修改
1
2git add . # 把当前目录下所有修改添加到暂存区。
git commit # 这会打开我们之前配置的编辑器(如vim或者nano或者vscode),让我们填写提交说明。第一行输入:
1
modified my info
然后==保存退出,在vim中是:==
==Esc → 输入:wq→ 回车==
==保存退出,在nano中是:==
==Ctrl + O(保存) → Ctrl + X (退出编辑器)==
- 查看提交历史会看到如下格式的提交历史:
1
git log
说明你已经成功提交一次记录。1
2
3
4
5commit 3f82bcd...
Author: 231221234-李四 <email@example.com>
Date: ...
modified my info
小结与术语对照
| Git 命令 | 含义 |
|---|---|
git branch |
查看分支 |
git checkout -b xxx |
创建并切换到新分支 |
git status |
查看工作区修改 |
git diff |
查看文件内容改动 |
git add . |
把修改加入暂存区 |
git commit |
提交更改,记录日志 |
git log |
查看提交历史 |
git checkout master |
回到主分支 |
git checkout xxx |
切换分支 |
分支工作流总结(非常重要!)
| 操作 | 命令 |
|---|---|
| 开始一个新的 PA | git checkout -b pa1(或 pa2, pa3 等) |
| 在新分支中编码和调试 | 你可以随意提交、修改、实验 |
| 完成 PA 后 | 使用 git checkout master 切换回主分支 |
| 把分支合并到 master | 使用 git merge pa1(等你学到合并章节) |
编译和运行 NEMU
进入 NEMU 目录&第一次编译前运行(出错)
执行:
1 | cd $NEMU_HOME |
$NEMU_HOME是环境变量,指向ics2024/nemu目录,之前我们运行init.sh nemu后已自动配置。也可以手动进入:
1 | cd ~/ics2024/nemu |
然后运行:
1 | make menuconfig |
大概率会遇到错误,如图:
原因是缺少依赖项,修复方法(我暂时增加了这些依赖,因为增加这些依赖后就能正常运行了):
1 | sudo apt update |
- 我们可以在任何目录下运行
sudo apt update和sudo apt install xxx。目录位置不会影响安装效果。因为apt 是一个系统级包管理器,用于管理整个操作系统的工具包和依赖。和我们当前在哪个工作目录(、/ics2024/nemu、/tmp等)没有关系,这个命令安装的包会被放在/usr/bin/bison等系统路径中,全局可用。 - 查找某个安装包可以用以下命令来进行验证(以bison包为例):如果能看到路径和版本号就说明安装成功了,例如:
1
2which bison
bison --vision

第一次编译前运行 make menuconfig(成功)
再次运行:
1 | make menuconfig |
%%这个命令会调用 menuconfig,这是一个配置 NEMU 的工具(借鉴自 Linux 内核的配置系统)。%%
这个命令会弹出一个基于终端的 图形化菜单,如图:
不需要修改内容,直接选择:Exit,然后选择Yes保存配置(配置结果保存在.config文件中,将影响后续make编译行为)
关闭之后可以看到如图运行结果:
编译&运行 NEMU
编译nemu:
1 | make |
这一步会读取你配置好的.config,执行多层Makefile(终端会有一长串),编译整个NEMU工程。
如果想要重新编译或者修改配置后进行编译,需要先清理旧的编译结果:
1 | make clean |
运行nemu:
1 | make run |
其中有一行:riscv32-nemu-interpreter: src/monitor/monitor.c:36: welcome: Assertion `0' failed.
这是故意加的断言,暂时不需要修复
另外可以运行:
1 | make gdb |
启动调试。
另:**==输入q或者quit即可退出调试==**
发展追踪&本地提交
==完整流程如下:==
进入仓库&创建分支(每个PA开始时创建即可)
PA0:
1 | cd ~/ics2024 |
后面的PA:
1 | git commit --allow-empty -am "before starting pa1" |
然后进行开发即可。
在
pa0、pa1等专属实验分支中开发和提交。
运行&本地提交(开发过程中不断循环进行)
编码:
1 | vim xxx.c |
编译:
1 | make |
运行:
1 | make run |
每完成一个小模块(如译码、执行、调试通过等)如果一切正常,就做一次手动提交!记录当下的状态!(虽然有自动追踪进行记录,但是手动commit更加清晰)
1 | git add . |
注:
- 每次commit 后面都要加上“ – allow-empty”因为通常更改已经由开发跟踪系统提交,如果没有这个选项,将拒绝没有进行更改的提交。
- 说明可以完善一点:
【PAx】<简要说明> - <修改了哪些模块/文件> - <解决了什么问题/添加了什么功能> - <测试情况:xxx通过/xxx未通过>
如果需要写多行说明,最好在编辑器中进行(在终端不写-m):然后保存并退出后提交就完成了。1
git commit --allow-empty
查看完整开发日志
1 | git log --oneine |
示例输出:
1 | fbc88d5 【PA0】完成 load/store 指令实现,版本稳定 ✅ |
如果想要过滤,只看我自己手动提交的记录:
1 | git log --author="王若璠" # ""中填写你的名字 |
撰写报告
必须描述的内容
- **==实验进度==**。简单明描述即可,例如“我完成了所有内容”,“我只完成了xxx”
- ==必答题==
鼓励描述的内容
- 在实验中遇到的问题和对这些问题的思考
- 对讲义中蓝框思考题的看法
- 或者其他想法,如实验心得,对提供帮助的同学的感谢。
==认真描述实验心得和想法的报告==将会获得分数的奖励; 蓝框题为选做, 完成了也不会得到分数的奖励, 但它们是经过精心准备的, 可以加深你对某些知识的理解和认识.
因此当你发现编写实验报告的时间所剩无几时, 你==应该选择描述实验心得和想法==. 如果你实在没有想法, 你可以提交一份不包含任何想法的报告, 我们不会强求.但请不要 - 大量粘贴讲义内容
- 大量粘贴代码和贴图, 却没有相应的详细解释(让我们明显看出来是凑字数的)
来让你的报告看起来十分丰富, 编写和阅读这样的报告毫无任何意义, 你也不会因此获得更多的分数, 同时还可能带来扣分的可能.
提交
完成各个实验之后,需要把项目提交到网站(具体方式因课程老师而定)
要确保最终的项目目录结构是这样的:
1 | ics2024/ |
注:
✅ 报告必须是 PDF 格式,并命名为 学号.pdf(比如:231220000.pdf)
✅ 报告必须放在ics2024根目录中,不要放到子目录里
❌ 不要上传.docx、.pages、.md或截图形式的报告
✅ 保留.git文件夹(不能清除开发历史)
==实验提交只需要运行make submit命令。==(暂定,不清楚具体方法)
SSH远程连接(VS Code)
在Ubuntu中安装SSH
安装SSH:
1 | sudo apt install openssh-server |
启动SSH服务:
1 | sudo service ssh start |
用以下命令启动SSH服务:
1 | sudo service ssh status |
如果一切正常的话会看到active(running)的提示。如下图:
在Windows系统上通过SSH远程连接WSL2的Ubuntu系统==必须首先在Ubuntu中启动SSH服务==
Loaded: loaded (/usr/lib/systemd/system/ssh.service; disabled; preset: enabled)说明:
✅ 你的系统中安装了 SSH 服务(openssh-server),并加载成功;
❗ 但是它 不会自动启动(disabled),你必须手动运行sudo service ssh start或sudo systemctl start ssh来启动它;
关闭SSH服务:
1 | sudo service ssh stop |
电脑关机 / WSL 关闭时,SSH 服务也会关闭
SSH 服务会随 WSL 实例关闭而自动终止:
| 操作 | 是否会关闭 SSH 服务 |
|---|---|
| 关闭 Windows 电脑 | ✅ 会(WSL 随系统关闭) |
| 手动关闭 WSL | ✅ 会(例如 wsl --shutdown) |
| 重启 WSL | ✅ 会中断并重启 SSH 服务(需要重新启动它,除非设置了自启) |
| 关闭 VS Code、终端窗口 | ⚠️ 仅关闭窗口不会关闭 SSH 服务,除非 WSL 整个关闭 |
当前WSL2网络状态分析&端口转发
查看Linux系统的IP地址
1 | ifconfig |
输出如下:
在这里我们选择eth0后面的IP地址(有的时候可能是eth2等):
1 | inet 192.168.21.137 |
这个IP是WSL2中的Linux自己的IP地址,而不是Windows主机的地址。
问题是:==我们无法直接从Windows(的VS Code)连接到这个IP地址==,这是因为:
- WSL2 本质上是一个虚拟机,运行在 Windows 上
- WSL2使用 Hyper-V 的虚拟网络适配器(NAT 模式)
- 所以 WSL2 拥有自己的“内部网络 IP”(如你看到的
192.168.21.137) - 这个 IP 是 在 WSL2 虚拟网卡内部可见的,但从 Windows 主机无法访问
- 我的宿主机(WIndows系统)和WSL2虽然在同一台电脑上,但是二者彼此IP不互通
- 所以不能直接在VS Code中使用ssh ffffff@192.168.21.137
📦 类比理解
WSL2 就像你电脑里的一个“局域网里的小电脑”,你看到它的 IP 是
192.168.xx.xx,但你(Windows)自己 不是它那个小局域网里的成员,所以无法直接访问。
❗❗❗**==解决方法:端口转发==**❗❗❗
端口转发(待定)
首先确保WSL2中SSH服务已经启动:
1 | sudo service ssh start |
应该看到 active (running)。
然后以管理员身份运行PowerShell,执行:
1 | netsh interface portproxy add v4tov4 listenport=2222 listenaddress=127.0.0.1 connectport=22 connectaddress=127.0.0.1 |
⏩ 把 Windows 本机的
127.0.0.1:2222→ 转发给 WSL2 内的127.0.0.1:22
然后再Windows中的~/.ssh/config(完整路径是C:\Users\ffffff\.ssh\config)文件中添加如下配置:
1 | Host my-wsl # my-wsl可以是其他名称 |
然后测试是否连接成功:
1 | ssh ffffff@127.0.0.1 -p 2222 |
如果能成功进入Ubuntu的Shell,就说明连接成功,也就能在VS Code中连接了。
在VS Code中配置SSH
首先安装并启用Remote-SSH插件
然后Ctrl+Shift+P →Remote-SSH: Connect to Host...
选择my-wsl
在上方框中输入密码后Enter
看到左下角出现SSH:my-wsl即为连接成功
重启 WSL 后需要做的事情
- 打开WSL
- 启动SSH服务
sudo service ssh start并检查sudo service ssh status- Windows连接/VS Code连接
转发图形界面
PA 的后半部分需要运行图形化界面程序,因此我们需要将图形界面转发到本地。
下载安装打开==MobaXterm==后,输入 IP 地址和用户名连接。
为了能转发图像界面,需要在 Advanced SSH Settings 中勾选X11-Forwarding选项。
在连接成功后,我们可以在 MobaXterm 中运行xclock命令来测试图形界面是否正常工作。