ICS-PA0(开发环境配置)

Uncategorized
12k words

在这门课中我们需要一个具有图形界面的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 格式 管理软件源,配置文件路径为:
    1
    /etc/apt/sources.list.d/ubuntu.sources
    在WSL中运行以下代码,打开.source文件
    1
    sudo nano /etc/apt/sources.list.d/ubuntu.sources
    %% 这里需要输入密码 %%

会看到:


其中最下面会有如下内容(示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Types: deb
URIs: http://archive.ubuntu.com/ubuntu
Suites: noble noble-updates noble-backports noble-security
Components: main universe restricted multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

##
##

Types: deb
URIs: http://security.ubuntu.com/ubuntu
Suites: noble-security
Components: main universe restricted multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

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
2
3
4
5
6
7
apt-get install build-essential    # build-essential packages, include binary utilities, gcc, make, and so on
apt-get install man # on-line reference manual
apt-get install gcc-doc # on-line reference manual for gcc
apt-get install gdb # GNU debugger
apt-get install git # revision control system
apt-get install libreadline-dev # a library used later
apt-get install libsdl2-dev # a library used later

安装中文输入法

(这部分好久之前实操的了,当时是按照gpt的步骤一步一步进行的,下面的大概率就是当时的做法,没有再次实操报一丝)

安装Fctix框架和中文输入法引擎

运行以下命令:

1
2
3
4
5
6
sudo apt install fcitx fcitx-googlepinyin fcitx-config-gtk
# `fcitx`:输入法框架
# `fcitx-googlepinyin`:Google 拼音引擎,轻量、准确
# `fcitx-config-gtk`:图形配置工具(方便添加/排序输入法)
sudo apt install fonts-wqy-zenhei fonts-wqy-microhei
# 扩展安装中文字体,否则部分程序中中文会显示方块

配置环境变量

执行以下命令:

1
2
3
4
echo "export GTK_IM_MODULE=fcitx" >> ~/.bashrc
echo "export QT_IM_MODULE=fcitx" >> ~/.bashrc
echo "export XMODIFIERS=@im=fcitx" >> ~/.bashrc
# 确保所有图形应用(GTK/Qt/X11)能正确调用 `fcitx` 作为输入法。

刷新环境变量

执行以下命令,让当前shell会话立即生效:

1
source ~/.bashrc

启动输入法(首次)

在终端输入:(首先要确保图形界面转发成功,比如我用的是 MobaXterm)

1
2
fcitx-autostart &  # 启动 Fcitx 框架
fcitx-config-gtk3 & # 打开图形配置界面

等待几秒钟,会弹出一个图形窗口(Fcitx 配置中心)。
启动 Fcitx 后,再打开配置工具,图形界面下你可以:添加「Google Pinyin」输入法 ; 设置「Ctrl+Space」作为切换热键 ; 修改输入法顺序

在配置界面中添加 Google 拼音输入法

  • 在窗口左下角点击 + 号,打开添加输入法界面
  • 搜索或从列表中找到 Google Pinyin
  • 选中它,点击 确定 添加
  • 可选:调整输入法顺序,把 Google Pinyin 放在最前面
    默认情况下,**Ctrl+Space** 是中英文切换快捷键。在 Fcitx 配置窗口的上方栏中,点击 Global ConfigTrigger Input Method。更改为你想要的快捷键,例如 Shift+Space

测试中文输入是否可用

可以运行一个图形程序来测试:

1
gedit&

(如果没有安装的话,按照提示安装即可)
在打开的窗口中应该会看到一个候选词框,输入拼音,可看到中文即为可以正常使用 。

检查关键工具

1
2
3
gcc --version
gdb --version
git --version

🔑 ✅🧾

配置vim

安装:vim-编辑器之神

1
2
sudo apt update
sudo apt install vim

如何判断自己是否在WSL2的Ubuntu系统中安装了vim:

方法一

运行:

1
which vim

如果输出类似:

1
/usr/bin/vim

则表明系统中已经安装vim并且可以使用
如果什么都不输出,表示未安装

方法二

运行

1
vim --version

如果已经安装,会显示vim的版本信息如 VIM - Vi IMproved 9.0 等)
如果没有安装,会提示:

1
2
Command 'vim' not found, but can be installed with:
sudo apt install vim

获取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
2
The authenticity of host 'github.com (IP)' can't be established.
Are you sure you want to continue connecting (yes/no)?

输入: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
2
-rw------- 1 ffffff ffffff  464 Jul 23  id_ed25519
-rw-r--r-- 1 ffffff ffffff 100 Jul 23 id_ed25519.pub
文件名 说明
id_ed25519 私钥(不要泄露)
id_ed25519.pub 公钥(可添加到 GitHub)

获取源代码

运行以下命令来获得实验源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cd ~                                      # 回到主目录

git clone -b 2024 git@github.com:NJU-ProjectN/ics-pa.git ics2024


# 设置Git环境
git config --global user.name "231220000-Zhang San" # 可以有中文
git config --global user.email "zhangsan@foo.com"
git config --global core.editor vim
git config --global color.ui true

# 初始化子模块
cd ics2024
git branch -m master # 将当前分支改名为 `master`(PA 的默认开发分支)
bash init.sh nemu
bash init.sh abstract-machine

source ~/.bashrc # 使环境变量生效

echo $NEMU_HOME # 检查环境变量
echo $AM_HOME
cd $NEMU_HOME
cd $AM_HOME

  • ~ 是 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 会克隆这个分支的内容,而不是默认的 mainmaster 分支。
    • 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
2
master
* pa0

在现在这种情况下,项目中所有文件的修改都将记录在pa0分支中。

修改项目文件

1
2
3
4
5
# 打开文件: ics2024/Makefile
# 修改以下变量为你的真实信息:

STUID = 231221234 # 你的学号
STUNAME = 李四 # 你的中文姓名

查看修改状态并提交修改

  • 查看修改状态:

    1
    git status

    输出类似:

    1
    2
    3
    On 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
    2
    git 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
    5
    commit 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
2
3
4
sudo apt update
sudo apt install libncurses-dev build-essential
sudo apt install bison
sudo apt install flex
  • 我们可以在任何目录下运行sudo apt updatesudo apt install xxx。目录位置不会影响安装效果。因为apt 是一个系统级包管理器,用于管理整个操作系统的工具包和依赖。和我们当前在哪个工作目录(/ics2024/nemu、/tmp等)没有关系,这个命令安装的包会被放在 /usr/bin/bison等系统路径中,全局可用。
  • 查找某个安装包可以用以下命令来进行验证(以bison包为例):
    1
    2
    which 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
2
cd ~/ics2024
git checkout -b pa0 # 如果还没有创建pa0分支

后面的PA:

1
2
3
4
git commit --allow-empty -am "before starting pa1"
git checkout master
git merge pa0
git checkout -b pa1

然后进行开发即可。

pa0pa1 等专属实验分支中开发和提交。

运行&本地提交(开发过程中不断循环进行)

编码:

1
vim xxx.c

编译:

1
make

运行:

1
make run

每完成一个小模块(如译码、执行、调试通过等)如果一切正常,就做一次手动提交!记录当下的状态!(虽然有自动追踪进行记录,但是手动commit更加清晰)

1
2
git add .
git commit --allow-empty -m "阶段或总结性说明"

注:

  • 每次commit 后面都要加上“ – allow-empty”因为通常更改已经由开发跟踪系统提交,如果没有这个选项,将拒绝没有进行更改的提交。
  • 说明可以完善一点:
    【PAx】<简要说明> - <修改了哪些模块/文件> - <解决了什么问题/添加了什么功能> - <测试情况:xxx通过/xxx未通过>
    如果需要写多行说明,最好在编辑器中进行(在终端不写-m):
    1
    git commit --allow-empty
    然后保存并退出后提交就完成了。

查看完整开发日志

1
git log --oneine

示例输出:

1
2
3
4
fbc88d5 【PA0】完成 load/store 指令实现,版本稳定 ✅
6d332ea 【PA0】修复 MMU 地址转换 bug,load/store 通过 riscv-tests
38a81b0 【PA0】实现所有 load/store 指令(lb/lh/lbu/lhu/sb/sh/sw)
e4f23da 【PA0】初步添加 lw/sw 指令执行结构(未测试)

如果想要过滤,只看我自己手动提交的记录:

1
git log --author="王若璠" # ""中填写你的名字

撰写报告

必须描述的内容

  • **==实验进度==**。简单明描述即可,例如“我完成了所有内容”,“我只完成了xxx”
  • ==必答题==

鼓励描述的内容

  • 在实验中遇到的问题和对这些问题的思考
  • 对讲义中蓝框思考题的看法
  • 或者其他想法,如实验心得,对提供帮助的同学的感谢。
    ==认真描述实验心得和想法的报告==将会获得分数的奖励; 蓝框题为选做, 完成了也不会得到分数的奖励, 但它们是经过精心准备的, 可以加深你对某些知识的理解和认识.
    因此当你发现编写实验报告的时间所剩无几时, 你==应该选择描述实验心得和想法==. 如果你实在没有想法, 你可以提交一份不包含任何想法的报告, 我们不会强求.但请不要
  • 大量粘贴讲义内容
  • 大量粘贴代码和贴图, 却没有相应的详细解释(让我们明显看出来是凑字数的)
    来让你的报告看起来十分丰富, 编写和阅读这样的报告毫无任何意义, 你也不会因此获得更多的分数, 同时还可能带来扣分的可能.

提交

完成各个实验之后,需要把项目提交到网站(具体方式因课程老师而定)

要确保最终的项目目录结构是这样的:

1
2
3
4
5
6
7
8
9
ics2024/
├── 231220000.pdf ✅ ← 实验报告(PDF 格式)
├── abstract-machine/ ✅ ← 框架子模块之一
├── fceux-am/ ✅ ← 另一个子模块(部分 PA 会用到)
├── init.sh ✅ ← 初始化脚本
├── Makefile ✅ ← 工程入口文件
├── nemu/ ✅ ← NEMU 框架
└── README.md

注:
✅ 报告必须是 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 startsudo 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
2
sudo service ssh start
sudo service ssh status

应该看到 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
2
3
4
Host my-wsl   # my-wsl可以是其他名称
HostName 127.0.0.1
Port 2222
User ffffff # ← 这里用你的 WSL 中的用户名

然后测试是否连接成功:

1
ssh ffffff@127.0.0.1 -p 2222

如果能成功进入Ubuntu的Shell,就说明连接成功,也就能在VS Code中连接了。

在VS Code中配置SSH

首先安装并启用Remote-SSH插件
然后Ctrl+Shift+PRemote-SSH: Connect to Host...
选择my-wsl
在上方框中输入密码后Enter
看到左下角出现SSH:my-wsl即为连接成功

重启 WSL 后需要做的事情

  1. 打开WSL
  2. 启动SSH服务sudo service ssh start并检查sudo service ssh status
  3. Windows连接/VS Code连接

转发图形界面

PA 的后半部分需要运行图形化界面程序,因此我们需要将图形界面转发到本地。
下载安装打开==MobaXterm==后,输入 IP 地址和用户名连接。
为了能转发图像界面,需要在 Advanced SSH Settings 中勾选X11-Forwarding选项。
在连接成功后,我们可以在 MobaXterm 中运行
xclock命令来测试图形界面是否正常工作。

Comments