Skip to content

ICS PA 0

Posted on:2022.01.01

TOC

Open TOC

ICS PA 0

环境配置

工具的使用及相关资源

主要修改一下配置文件,先进行备份:

Terminal window
$ cp /etc/vim/vimrc ~/.vimrc

然后回到家目录:

Terminal window
$ vi .vimrc

添加如下内容:

set tabstop=4
set softtabstop=4
set cindent
set shiftwidth=4

基本的操作如下:

Terminal window
$ vi hello.c
$ gcc hello.c -o hello
$ /hello

hello.c 所在目录下新建一个文件 Makefile,输入以下内容并保存:

hello:hello.c
gcc hello.c -o hello # 注意开头的 tab,而不是空格
.PHONY: clean
clean:
rm hello # 注意开头的 tab,而不是空格

返回命令行,键入 make,你会发现 make 程序调用了 gcc 进行编译。

若连续多次执行 make,会得到 make: 'hello' is up to date. 的提示信息。

其中 .PHONY: clean 这一行的作用是防止同目录下的 clean 文件影响 Makefile 的执行。

The workflow above shows how you will use branch in PAs:

  1. before starting a new PA, new a branch pa? and check out to it
  2. coding in the branch pa? (this will introduce lot of modifications)
  3. after finish the PA, merge the branch pa? into master, and check out back to master

Access GitHub

修改 /etc/hosts 文件如下:

127.0.0.1 localhost
127.0.1.1 vgalaxy-VirtualBox
10.0.2.15 github.com git
13.250.177.223 github.com
# github.com
192.30.253.112 github.com
192.30.253.119 gist.github.com
151.101.100.133 assets-cdn.github.com
151.101.100.133 raw.githubusercontent.com
151.101.100.133 gist.githubusercontent.com
151.101.100.133 cloud.githubusercontent.com
151.101.100.133 camo.githubusercontent.com
151.101.100.133 avatars0.githubusercontent.com
151.101.100.133 avatars1.githubusercontent.com
151.101.100.133 avatars2.githubusercontent.com
151.101.100.133 avatars3.githubusercontent.com
151.101.100.133 avatars4.githubusercontent.com
151.101.100.133 avatars5.githubusercontent.com
151.101.100.133 avatars6.githubusercontent.com
151.101.100.133 avatars7.githubusercontent.com
151.101.100.133 avatars8.githubusercontent.com
185.199.108.153 assets-cdn.github.com
185.199.109.153 assets-cdn.github.com
185.199.110.153 assets-cdn.github.com
185.199.111.153 assets-cdn.github.com
151.101.113.194 github.global.ssl.fastly.net
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

其中 10.0.2.15 通过 ifconfig 命令查看

Compiling and Running NEMU

nemu/ 文件夹中,我们需要进行 NEMU 项目中的配置系统和项目构建(更多内容详见 PA1 RTFSC)。

配置系统 make menuconfig

执行这一步前,需要先安装 bisonflex

NEMU 中的配置系统为于 nemu/tools/kconfig,它来源于 GNU / Linux 项目中的 kconfig。

kconfig 定义了一套简单的语言,开发者可以使用这套语言来编写“配置描述文件”。

在 NEMU 项目中,“配置描述文件”的文件名都为 Kconfig,如 nemu/Kconfig

当键入 make menuconfig 的时候,背后其实发生了如下事件:

项目构建 make

Terminal window
$ make
+ CC src/nemu-main.c
+ CC src/cpu/difftest/dut.c
+ CC src/cpu/cpu-exec.c
+ CC src/monitor/monitor.c
+ CC src/monitor/sdb/watchpoint.c
+ CC src/monitor/sdb/expr.c
+ CC src/monitor/sdb/sdb.c
+ CC src/utils/log.c
+ CC src/utils/timer.c
+ CC src/utils/state.c
+ CC src/utils/rand.c
+ CC src/memory/paddr.c
+ CC src/memory/vaddr.c
+ CC src/device/io/port-io.c
+ CC src/device/io/map.c
+ CC src/device/io/mmio.c
+ CC src/engine/interpreter/hostcall.c
+ CC src/engine/interpreter/init.c
+ CC src/isa/riscv32/system/intr.c
+ CC src/isa/riscv32/system/mmu.c
+ CC src/isa/riscv32/reg.c
+ CC src/isa/riscv32/difftest/dut.c
+ CC src/isa/riscv32/instr/decode.c
+ CC src/isa/riscv32/logo.c
+ CC src/isa/riscv32/init.c
+ LD /home/vgalaxy/ics2021/nemu/build/riscv32-nemu-interpreter

下面是 Makefile 文件的内容,我们对其进行解读:

# Sanity check
ifeq ($(wildcard $(NEMU_HOME)/src/nemu-main.c),)
$(error NEMU_HOME=$(NEMU_HOME) is not a NEMU repo)
endif
# Include variables and rules generated by menuconfig
-include $(NEMU_HOME)/include/config/auto.conf
-include $(NEMU_HOME)/include/config/auto.conf.cmd
remove_quote = $(patsubst "%",%,$(1))
# Extract variabls from menuconfig
GUEST_ISA ?= $(call remove_quote,$(CONFIG_ISA))
ENGINE ?= $(call remove_quote,$(CONFIG_ENGINE))
NAME = $(GUEST_ISA)-nemu-$(ENGINE)
# Include all filelist.mk to merge file lists
FILELIST_MK = $(shell find ./src -name "filelist.mk")
include $(FILELIST_MK)
# Filter out directories and files in blacklist to obtain the final set of source files
DIRS-BLACKLIST-y += $(DIRS-BLACKLIST)
SRCS-BLACKLIST-y += $(SRCS-BLACKLIST) $(shell find $(DIRS-BLACKLIST-y) -name "*.c")
SRCS-y += $(shell find $(DIRS-y) -name "*.c")
SRCS = $(filter-out $(SRCS-BLACKLIST-y),$(SRCS-y))
# Extract compiler and options from menuconfig
CC = $(call remove_quote,$(CONFIG_CC))
CFLAGS_BUILD += $(call remove_quote,$(CONFIG_CC_OPT))
CFLAGS_BUILD += $(if $(CONFIG_CC_LTO),-flto,)
CFLAGS_BUILD += $(if $(CONFIG_CC_DEBUG),-ggdb3,)
CFLAGS_BUILD += $(if $(CONFIG_CC_ASAN),-fsanitize=address,)
CFLAGS += $(CFLAGS_BUILD) -D__GUEST_ISA__=$(GUEST_ISA)
LDFLAGS += $(CFLAGS_BUILD)
# Include rules for menuconfig
include $(NEMU_HOME)/scripts/config.mk
ifdef CONFIG_TARGET_AM
include $(AM_HOME)/Makefile
LINKAGE += $(ARCHIVES)
else
# Include rules to build NEMU
include $(NEMU_HOME)/scripts/native.mk
endif

通过包含 nemu/include/config/auto.conf,与 kconfig 生成的变量进行关联。

nemu/src 及其子目录下存在一些名为 filelist.mk 的文件:

Terminal window
vgalaxy@vgalaxy-VirtualBox:/home/vgalaxy/ics2021/nemu$ find ./ -name filelist.mk
./src/filelist.mk
./src/device/filelist.mk
./src/engine/filelist.mk
./src/isa/filelist.mk

它们会根据 menuconfig 的配置对如下 4 个变量进行维护:

Makefile 会包含项目中的所有 filelist.mk 文件,对上述 4 个变量的追加定义进行汇总,最终会过滤出在 SRCS-y 中但不在 SRCS-BLACKLIST-y 中的源文件,来作为最终参与编译的源文件的集合。

Makefile 的编译规则在 nemu/scripts/build.mk 中定义,见 # Compilation patterns 后的部分:

.DEFAULT_GOAL = app
# Add necessary options if the target is a shared library
ifdef SHARE
SO = -so
CFLAGS += -fPIC
LDFLAGS += -rdynamic -shared -fPIC
endif
WORK_DIR = $(shell pwd)
BUILD_DIR = $(WORK_DIR)/build
INC_PATH := $(WORK_DIR)/include $(INC_PATH)
OBJ_DIR = $(BUILD_DIR)/obj-$(NAME)$(SO)
BINARY = $(BUILD_DIR)/$(NAME)$(SO)
CC ?= gcc
# Compilation flags
CC := $(CC)
LD := $(CC)
INCLUDES = $(addprefix -I, $(INC_PATH))
CFLAGS := -O2 -MMD -Wall -Werror $(INCLUDES) $(CFLAGS)
LDFLAGS := -O2 $(LDFLAGS)
OBJS = $(SRCS:%.c=$(OBJ_DIR)/%.o)
# Compilation patterns
$(OBJ_DIR)/%.o: %.c
@echo + CC $<
@mkdir -p $(dir $@)
@$(CC) $(CFLAGS) -c -o $@ $<
$(call call_fixdep, $(@:.o=.d), $@)
# Depencies
-include $(OBJS:.o=.d)
# Some convenient rules
.PHONY: app clean
app: $(BINARY)
$(BINARY): $(OBJS) $(ARCHIVES)
@echo + LD $@
@$(LD) -o $@ $(OBJS) $(LDFLAGS) $(ARCHIVES) $(LIBS)
clean:
-rm -rf $(BUILD_DIR)

$@ 表示所有参数列表,$< 表示第一个依赖文件,call_fixdep 的调用用于生成更合理的依赖关系(先忽略)。

可以通过输入 make -nBmake 程序以“只输出命令但不执行”的方式强制构建目标。

我们截取最开始的一段输出分析,中间用空行分隔开:

echo + CC src/nemu-main.c
mkdir -p /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/
gcc -O2 -MMD -Wall -Werror -I/home/vgalaxy/ics2021/nemu/include -I/home/vgalaxy/ics2021/nemu/src/engine/interpreter -I/home/vgalaxy/ics2021/nemu/src/isa/riscv32/include -O2 -D__GUEST_ISA__=riscv32 -c -o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/nemu-main.o src/nemu-main.c
/home/vgalaxy/ics2021/nemu/tools/fixdep/build/fixdep /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/nemu-main.d /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/nemu-main.o unused > /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/nemu-main.d.tmp
mv /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/nemu-main.d.tmp /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/nemu-main.d

对比可知,我们可以了解到 $<src/nemu-main.c$@/home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/nemu-main.o$(CC)gcc 等。

可以根据上述输出结果和 Makefile 反推 $(CFLAGS) 的值是如何形成的。

编译之后是一系列 git 操作,规则在 nemu/scripts/git.mk 中定义。下面是输出:

git add /home/vgalaxy/ics2021/nemu/.. -A --ignore-errors
while (test -e .git/index.lock); do sleep 0.1; done
(echo "> "compile"" && echo 201220000 && hostnamectl && uptime) | git commit -F - -q --author='tracer-ics2021 <tracer@njuics.org>' --no-verify --allow-empty
sync

最后是链接操作:

echo + LD /home/vgalaxy/ics2021/nemu/build/riscv32-nemu-interpreter
gcc -o /home/vgalaxy/ics2021/nemu/build/riscv32-nemu-interpreter /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/nemu-main.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/cpu/difftest/dut.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/cpu/cpu-exec.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/monitor/monitor.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/monitor/sdb/watchpoint.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/monitor/sdb/expr.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/monitor/sdb/sdb.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/utils/log.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/utils/timer.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/utils/state.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/utils/rand.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/memory/paddr.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/memory/vaddr.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/device/io/port-io.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/device/io/map.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/device/io/mmio.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/engine/interpreter/hostcall.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/engine/interpreter/init.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/isa/riscv32/system/intr.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/isa/riscv32/system/mmu.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/isa/riscv32/reg.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/isa/riscv32/difftest/dut.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/isa/riscv32/instr/decode.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/isa/riscv32/logo.o /home/vgalaxy/ics2021/nemu/build/obj-riscv32-nemu-interpreter/src/isa/riscv32/init.o -O2 -O2 -lreadline -ldl -pie

运行与调试

To run NEMU, type

Terminal window
$ make run

To debug NEMU with gdb, type

Terminal window
$ make gdb

submit

终于收到了 jyy 的 TOKEN。环境变量在 ~/.bashrc 中设置,另外还需要修改 nemu/scripts/git.mk 中的学号和姓名,并安装 curl 🤣。