-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathMakefile
More file actions
267 lines (236 loc) · 10.9 KB
/
Copy pathMakefile
File metadata and controls
267 lines (236 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
DOCKER_TAG ?= comix:latest
# 架构选择: riscv (默认) 或 loongarch
ARCH ?= riscv
# 根据架构设置 target 和运行命令
ifeq ($(ARCH),loongarch)
TARGET := loongarch64-unknown-none
TARGET_DIR := target/loongarch64-unknown-none/debug
PROJECT_DIR := $(TARGET_DIR)/os
RUN_SCRIPT := cargo run --target $(TARGET)
GDB_SCRIPT := cargo run --target $(TARGET) -- gdb
else
TARGET := riscv64gc-unknown-none-elf
RUN_SCRIPT := cargo run
GDB_SCRIPT := cargo run -- --gdb
endif
# ============================================================
# 评测提交目标(根 Makefile)
# ============================================================
# 评测机在仓库根执行 `make all`,要求产出 ELF 内核:kernel-rv、kernel-la。
# 评测机 clone 时会过滤隐藏目录(含 os/.cargo),故构建前重建 os/.cargo/config.toml。
RV_TARGET := riscv64gc-unknown-none-elf
LA_TARGET := loongarch64-unknown-none
OS_DIR := os
OS_BIN := os
VFAT_MB ?= 64
VFAT_IMG := $(OS_DIR)/vfat.img
MKFS_VFAT ?= mkfs.vfat
ASSEMBLE_DISK := scripts/assemble_partitioned_disk.sh
COMMA := ,
# Local test images can be large (LTP in particular), so keep them outside this
# worktree and attach them directly as writable QEMU block devices. Override with
# `make run-la TESTIMG_LA=/path/to/sdcard-la.img` when needed.
LOCAL_TESTIMG_DIR ?= ../CCYOS
TESTIMG_RV ?= $(firstword $(wildcard $(LOCAL_TESTIMG_DIR)/sdcard-rv.img sdcard-rv.img))
TESTIMG_LA ?= $(firstword $(wildcard $(LOCAL_TESTIMG_DIR)/sdcard-la.img sdcard-la.img))
RV_TEST_DRIVE := -drive file=$(TESTIMG_RV)$(COMMA)if=none$(COMMA)format=raw$(COMMA)id=test0 -device virtio-blk-device$(COMMA)drive=test0$(COMMA)bus=virtio-mmio-bus.0
LA_TEST_DRIVE := -drive file=$(TESTIMG_LA)$(COMMA)if=none$(COMMA)format=raw$(COMMA)id=x0 -device virtio-blk-pci$(COMMA)drive=x0
# 评测构建 profile:默认 release(提交用)。本地调试可 `make all PROFILE=debug`。
PROFILE ?= release
ifeq ($(PROFILE),debug)
CARGO_PROFILE_FLAG :=
PROFILE_DIR := debug
else
CARGO_PROFILE_FLAG := --release
PROFILE_DIR := release
endif
# 本地运行评测镜像用 QEMU 参数(可在命令行覆盖,如 `make run-rv RV_MEM=2G`)。
RV_MEM ?= 4G
RV_SMP ?= 1
LA_MEM ?= 4G
LA_SMP ?= 1
.PHONY: docker build_docker fmt run build clean clean-all gdb
.PHONY: all kernel-rv kernel-la os-cargo-config
.PHONY: run-rv run-la run-rv-glibc-basic run-rv-glibc-basic-direct run-rv-glibc-basic-one
docker:
docker run --rm -it -v ${PWD}:/mnt -w /mnt --name comix ${DOCKER_TAG} bash
build_docker:
docker build -t ${DOCKER_TAG} --target build .
fmt:
cd os && cargo fmt
# 构建内核(build.rs 会自动编译 user 并打包镜像)
build:
cd os && cargo build --target $(TARGET)
# 运行内核(build.rs 会自动编译 user 并打包镜像)
run:
cd os && $(RUN_SCRIPT)
# GDB 调试模式
gdb:
cd os && $(GDB_SCRIPT)
# ------------------------------------------------------------
# 评测入口:make all → kernel-rv kernel-la (+ disk 镜像)
# ------------------------------------------------------------
# 重建 os/.cargo/config.toml(评测机 clone 时过滤隐藏目录,构建前恢复链接脚本 rustflags)。
# - 有 os/cargo-vendor-config.toml(评测/镜像离线场景):生成最小 config 并追加 vendored 源;
# - 或 .cargo/config.toml 缺失:生成最小 config;
# - 否则(本地开发,config 已存在):保留现有 config,不破坏 runner/测试设置。
# 注意:不写 build-std——两架构预编译 std 已自带 weak mem*,写了反而拖慢构建并破坏 cargo test。
os-cargo-config:
@if [ -f "$(OS_DIR)/cargo-vendor-config.toml" ] || [ ! -f "$(OS_DIR)/.cargo/config.toml" ]; then \
echo "[Build] 重建 $(OS_DIR)/.cargo/config.toml"; \
mkdir -p $(OS_DIR)/.cargo; \
printf '%s\n' \
'[target.riscv64gc-unknown-none-elf]' \
'rustflags = ["-Clink-arg=-Tsrc/linker.ld", "-Cforce-frame-pointers=yes"]' \
'' \
'[target.loongarch64-unknown-none]' \
'rustflags = ["-Clink-arg=-Tsrc/loongarch_linker.ld", "-Cforce-frame-pointers=yes"]' \
> $(OS_DIR)/.cargo/config.toml; \
if [ -f "$(OS_DIR)/cargo-vendor-config.toml" ]; then \
printf '\n' >> $(OS_DIR)/.cargo/config.toml; \
cat "$(OS_DIR)/cargo-vendor-config.toml" >> $(OS_DIR)/.cargo/config.toml; \
echo "[Build] 已追加 vendored 源(离线构建)"; \
echo "[Build] 重建 vendor 校验和(评测机过滤删除了 .cargo-checksum.json)"; \
python3 scripts/restore_vendor_checksums.py $(OS_DIR); \
fi; \
else \
echo "[Build] 保留现有 $(OS_DIR)/.cargo/config.toml(本地开发)"; \
fi
all: os-cargo-config kernel-rv kernel-la disk.img disk-la.img
@echo "[Build] 完成:kernel-rv kernel-la disk.img disk-la.img"
kernel-rv: os-cargo-config
@echo "[Build] 构建 RISC-V 内核 (ELF, $(PROFILE_DIR)): kernel-rv"
cd $(OS_DIR) && ARCH=riscv cargo build $(CARGO_PROFILE_FLAG) --target $(RV_TARGET)
cp -f $(OS_DIR)/target/$(RV_TARGET)/$(PROFILE_DIR)/$(OS_BIN) kernel-rv
kernel-la: os-cargo-config
@echo "[Build] 构建 LoongArch 内核 (ELF, $(PROFILE_DIR)): kernel-la"
cd $(OS_DIR) && ARCH=loongarch cargo build $(CARGO_PROFILE_FLAG) --target $(LA_TARGET)
cp -f $(OS_DIR)/target/$(LA_TARGET)/$(PROFILE_DIR)/$(OS_BIN) kernel-la
$(VFAT_IMG):
@echo "[Disk] 创建 $(VFAT_MB)MiB FAT32/VFAT 镜像: $@"
rm -f $@
truncate -s $(VFAT_MB)M $@
$(MKFS_VFAT) -F 32 -n CCYOSVFAT $@
# rootfs 裸 ext4 镜像由 os/build.rs 在对应内核构建时生成(os/fs-{arch}.img)。
# 根目录 disk 镜像是 MBR 分区盘:第一分区为我们的 rootfs,第二分区为 VFAT。
disk.img: kernel-rv $(VFAT_IMG) $(ASSEMBLE_DISK)
@echo "[Disk] 产出 MBR 分区盘镜像: disk.img"
@$(ASSEMBLE_DISK) $(OS_DIR)/fs-riscv.img $(VFAT_IMG) $@
disk-la.img: kernel-la $(VFAT_IMG) $(ASSEMBLE_DISK)
@echo "[Disk] 产出 MBR 分区盘镜像: disk-la.img"
@$(ASSEMBLE_DISK) $(OS_DIR)/fs-loongarch.img $(VFAT_IMG) $@
# ------------------------------------------------------------
# 本地运行评测形态:官方测试盘作为额外裸 ext4 块设备,由 rcS 挂载到 /tests。
# RISC-V virtio-mmio 设备树按高地址先探测,因此我们的分区盘放 bus.1,
# 官方测试盘放 bus.0,注册出来才是 vda=disk、vdb=sdcard。
# LoongArch 评测命令先挂官方测试盘、后挂 disk-la.img,因此 la 下是
# vda=sdcard-la.img、vdb=disk-la.img、vdb1=rootfs。
# ------------------------------------------------------------
run-rv: kernel-rv disk.img
@if [ -z "$(TESTIMG_RV)" ]; then \
echo "Error: no RISC-V test image found. Set TESTIMG_RV=/path/to/sdcard-rv.img" >&2; \
exit 1; \
fi
@echo "[Run] 运行 RISC-V QEMU(内核盘:vda1 rootfs,vda2 VFAT;测试盘:vdb)"
qemu-system-riscv64 -machine virt -kernel kernel-rv -m $(RV_MEM) -nographic \
-smp $(RV_SMP) -bios default -no-reboot -rtc base=utc \
-drive file=disk.img,if=none,format=raw,id=x0 \
-device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.1 \
$(RV_TEST_DRIVE) \
-device virtio-net-device,netdev=net -netdev user,id=net
run-rv-glibc-basic: kernel-rv disk.img
@if [ -z "$(TESTIMG_RV)" ]; then \
echo "Error: no RISC-V test image found. Set TESTIMG_RV=/path/to/sdcard-rv.img" >&2; \
exit 1; \
fi
@echo "[Run] 运行 RISC-V QEMU glibc basic(内核盘:vda1 rootfs,vda2 VFAT;测试盘:vdb)"
qemu-system-riscv64 -machine virt -kernel kernel-rv -m $(RV_MEM) -nographic \
-smp $(RV_SMP) -bios default -no-reboot -rtc base=utc \
-append "oscomp.test=glibc-basic" \
-drive file=disk.img,if=none,format=raw,id=x0 \
-device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.1 \
$(RV_TEST_DRIVE) \
-device virtio-net-device,netdev=net -netdev user,id=net
run-rv-glibc-basic-direct: kernel-rv disk.img
@if [ -z "$(TESTIMG_RV)" ]; then \
echo "Error: no RISC-V test image found. Set TESTIMG_RV=/path/to/sdcard-rv.img" >&2; \
exit 1; \
fi
@echo "[Run] 运行 RISC-V QEMU glibc basic direct(内核盘:vda1 rootfs,vda2 VFAT;测试盘:vdb)"
qemu-system-riscv64 -machine virt -kernel kernel-rv -m $(RV_MEM) -nographic \
-smp $(RV_SMP) -bios default -no-reboot -rtc base=utc \
-append "oscomp.test=glibc-basic-direct" \
-drive file=disk.img,if=none,format=raw,id=x0 \
-device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.1 \
$(RV_TEST_DRIVE) \
-device virtio-net-device,netdev=net -netdev user,id=net
GLIBC_CASE ?= getdents
run-rv-glibc-basic-one: kernel-rv disk.img
@if [ -z "$(TESTIMG_RV)" ]; then \
echo "Error: no RISC-V test image found. Set TESTIMG_RV=/path/to/sdcard-rv.img" >&2; \
exit 1; \
fi
@echo "[Run] 运行 RISC-V QEMU glibc basic single case: $(GLIBC_CASE)"
qemu-system-riscv64 -machine virt -kernel kernel-rv -m $(RV_MEM) -nographic \
-smp $(RV_SMP) -bios default -no-reboot -rtc base=utc \
-append "oscomp.test=glibc-basic-one oscomp.case=$(GLIBC_CASE)" \
-drive file=disk.img,if=none,format=raw,id=x0 \
-device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.1 \
$(RV_TEST_DRIVE) \
-device virtio-net-device,netdev=net -netdev user,id=net
run-la: kernel-la disk-la.img
@if [ -z "$(TESTIMG_LA)" ]; then \
echo "Error: no LoongArch test image found. Set TESTIMG_LA=/path/to/sdcard-la.img" >&2; \
exit 1; \
fi
@echo "[Run] 运行 LoongArch QEMU(测试盘:vda;内核盘:vdb1 rootfs,vdb2 VFAT)"
qemu-system-loongarch64 -machine virt -kernel kernel-la -m $(LA_MEM) -nographic \
-smp $(LA_SMP) -no-reboot -rtc base=utc \
$(LA_TEST_DRIVE) \
-drive file=disk-la.img,if=none,format=raw,id=x1 \
-device virtio-blk-pci,drive=x1 \
-device virtio-net-pci,netdev=net0 \
-netdev user,id=net0,hostfwd=tcp::5555-:5555,hostfwd=udp::5555-:5555
# 清理 OS 构建产物
clean:
cd os && cargo clean
# 清理所有构建产物(包括 user)
clean-all: clean
cd user && make clean
# 手动编译用户程序(调试用;评测构建不会自动编译 user/)
build-user:
cd user && make
# 手动打包 simple_fs 镜像(调试用;评测 rootfs 不依赖 user/)
pack-simple-fs: build-user
@echo "Packing simple_fs..."
python3 scripts/make_init_simple_fs.py user/bin os/simple_fs.img
# 检查镜像内容
inspect-simple-fs:
@IMG=$$(find os/target -name "simple_fs.img" -type f -print -quit 2>/dev/null); \
if [ -z "$$IMG" ]; then \
echo "Error: simple_fs.img not found. Run 'make build' first." >&2; \
exit 1; \
else \
python3 scripts/make_init_simple_fs.py --inspect "$$IMG"; \
fi
# 帮助信息
help:
@echo "ComixOS Makefile"
@echo ""
@echo "Usage: make [target] ARCH=[riscv|loongarch]"
@echo ""
@echo "Architectures:"
@echo " riscv - RISC-V 64-bit (default)"
@echo " loongarch - LoongArch 64-bit"
@echo ""
@echo "Targets:"
@echo " build - Build the kernel"
@echo " run - Run the kernel in QEMU"
@echo " gdb - Run with GDB debugging"
@echo " clean - Clean build artifacts"
@echo " help - Show this help message"
@echo ""
@echo "Examples:"
@echo " make build # Build for RISC-V"
@echo " make build ARCH=loongarch # Build for LoongArch"
@echo " make run ARCH=loongarch # Run LoongArch kernel"