-
Notifications
You must be signed in to change notification settings - Fork 378
/
Makefile
382 lines (329 loc) · 9.86 KB
/
Makefile
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
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
# Commands:
# make build Build
# make run Build and run in QEMU
# make justrun Run the last build
# make test Build and run in QEMU with specified program
# make justtest Run the last build with specified program
# make doc Generate docs
# make asm Open the deassemble file of the last build
# make header Open 'objdump -h' of the last build
# make addr2line Use addr2line to recover line info in backtrace
# make clean Clean
#
# Options:
# ARCH = x86_64 | riscv32 | riscv64 | aarch64 | mipsel
# D = int | in_asm | ... QEMU debug info
# MODE = debug | release
# LOG = off | error | warn | info | debug | trace
# USER_IMG = <sfsimg> Image path of user programs
# SMP = 1 | 2 | ... SMP core number
# GRAPHIC = on | off | console Enable/disable qemu graphical output, or print console to graphic output
# BOARD = qemu Run on QEMU
# | pc [ x86_64 only] Run on real pc
# | u540 [riscv64 only] Run on HiFive U540, use Sv39
# | raspi3 [aarch64 only] Run on Raspberry Pi 3 Model B/B+
# | rcore_vmm_guest [riscv64 only] Run on rust-rvm-vmm/RVM. Requires variable GUEST_USER_IMG to be specified.
# NET = on | off [ x86_64 only] Enable NIC
# PCI_PASSTHRU = 0000:00:00.1 [ x86_64 only] Passthrough the specified PCI device
# INIT = /bin/ls [riscv64 only] Run specified program instead of user shell
# EXTRA_NIC = on | off [ x86_64 only] Add an additional e1000 nic
# ACCEL = on | off [ x86_64 only] Enable/disable kvm/hvf acceleration
# HYPERVISOR = on | off [ x86_64 and riscv64 only] Enable/disable the RVM hypervisor, and set ACCEL to on under x86_64
# UART2 = on | off [riscv64 only] Add an extra virtio-driven UART port on unix domain socket /tmp/rcore_uart2
# GUEST_USER_IMG = <sfsimg> Image path of user programs. Specially taken out to allow out-of-tree user image.
# FEATURES = profile | ... Add additional features
ARCH ?= riscv64
MODE ?= release
LOG ?=
GRAPHIC ?= off
SMP ?= 4
PCI_PASSTHRU ?=
INIT ?=
EXTRA_NIC ?= off
ACCEL ?= off
HYPERVISOR ?= off
UART2 ?= off
qemu := qemu-system-$(ARCH)
target := $(ARCH)
build_path := target/$(target)/$(MODE)
kernel := $(build_path)/rcore
kernel_img := $(build_path)/kernel.img
ESP := $(build_path)/esp
OVMF := ../rboot/OVMF.fd
user_dir := ../user
### export environments ###
ifeq ($(BOARD), rcore_vmm_guest)
ifeq ($(GUEST_USER_IMG), )
$(error For building guest rCore image you have to specify the variable GUEST_USER_IMG .)
endif
export USER_IMG = $(GUEST_USER_IMG)
else
export USER_IMG = $(user_dir)/build/$(ARCH).img
endif
export USER_QCOW2 = $(user_dir)/build/$(ARCH).qcow2
ifeq ($(ARCH), aarch64)
BOARD ?= raspi3
else ifeq ($(ARCH), mipsel)
BOARD ?= malta
else
BOARD ?= qemu
endif
# currently only mipsel architecture need DTB linked to the kernel
ifeq ($(ARCH), mipsel)
DTB := src/arch/$(ARCH)/board/$(BOARD)/device.dtb
endif
### qemu options ###
qemu_opts := \
-smp cores=$(SMP)
qemu_net_opts :=
ifeq ($(ARCH), x86_64)
qemu_opts += \
-drive if=pflash,format=raw,readonly,file=$(OVMF) \
-drive format=raw,file=fat:rw:$(ESP) \
-serial mon:stdio \
-m 4G \
-device isa-debug-exit
ifeq ($(BOARD), qemu)
qemu_opts += \
-drive format=qcow2,file=$(USER_QCOW2),media=disk,cache=writeback,id=sfsimg,if=none \
-device ahci,id=ahci0 \
-device ide-hd,drive=sfsimg,bus=ahci0.0
endif
ifeq ($(PCI_PASSTHRU), )
qemu_net_opts += \
-netdev type=tap,id=net0,script=no,downscript=no \
-device e1000e,netdev=net0
else
qemu_net_opts += \
-device vfio-pci,host=$(PCI_PASSTHRU)
qemu_ui_opts += \
-vga std
endif
ifeq ($(EXTRA_NIC), on)
qemu_net_opts += \
-netdev type=tap,id=net1,script=no,downscript=no \
-device e1000e,netdev=net1
endif
else ifeq ($(ARCH), riscv32)
qemu_opts += \
-machine virt \
-serial mon:stdio \
-bios default \
-device loader,addr=0x80400000,file=$(kernel_img) \
-drive file=$(USER_QCOW2),format=qcow2,id=sfs \
-device virtio-blk-device,drive=sfs \
-device virtio-gpu-device \
-device virtio-mouse-device
qemu_net_opts += \
-netdev type=tap,id=net0,script=no,downscript=no \
-device virtio-net-device,netdev=net0
else ifeq ($(ARCH), riscv64)
ifeq ($(BOARD), u540)
qemu_opts += \
-machine virt \
-serial mon:stdio \
-bios ../tools/opensbi/fu540.elf \
-device loader,addr=0x80200000,file=$(kernel_img)
else ifeq ($(BOARD), rcore_vmm_guest)
qemu_opts += \
-machine virt \
-cpu rv64,x-h=true \
-serial mon:stdio \
-bios ../tools/opensbi/fw_jump.elf \
-m 1G\
-kernel $(kernel_img)
else
qemu_opts += \
-machine virt \
-cpu rv64,x-h=true \
-m 2G \
-serial mon:stdio
ifeq ($(UART2), on)
qemu_opts += \
-chardev socket,path=/tmp/rcore_uart2,server=on,wait=off,id=uart2 \
-device virtio-serial-device,id=uart2-bus \
-device virtconsole,chardev=uart2
endif
qemu_opts += \
-bios ../tools/opensbi/fw_jump.elf \
-device loader,addr=0x80200000,file=$(kernel_img) \
-drive file=$(USER_QCOW2),format=qcow2,id=sfs \
-device virtio-blk-device,drive=sfs \
-device virtio-gpu-device \
-device virtio-mouse-device
endif
qemu_net_opts += \
-netdev type=tap,id=net0,script=no,downscript=no \
-device virtio-net-device,netdev=net0
else ifeq ($(ARCH), aarch64)
# raspi must have at least 4 cpus
qemu_opts += \
-machine $(BOARD) \
-smp 4 \
-serial null -serial mon:stdio \
-kernel $(kernel_img) \
-drive file=$(USER_QCOW2),if=sd,format=qcow2,id=sfs
else ifeq ($(ARCH), mipsel)
ifeq ($(BOARD), malta)
qemu_opts += \
-machine $(BOARD) -device VGA \
-hda $(USER_QCOW2) \
-serial null -serial null -serial mon:stdio \
-kernel $(kernel_img)
endif
endif
ifdef D
qemu_opts += -d $(D)
endif
ifeq ($(GRAPHIC), off)
qemu_opts += -nographic
endif
ifeq ($(NET), on)
qemu_opts += $(qemu_net_opts)
qemu := sudo $(qemu)
endif
ifeq ($(HYPERVISOR), on)
FEATURES += hypervisor
ifeq ($(ARCH), x86_64)
ACCEL = on
endif
endif
ifeq ($(ACCEL), on)
ifeq ($(shell uname), Darwin)
qemu_opts += -accel hvf
else
qemu_opts += -accel kvm -cpu host
endif
endif
### build args ###
ifeq ($(GRAPHIC), off)
FEATURES += nographic
endif
ifeq ($(GRAPHIC), console)
FEATURES += consolegraphic
endif
ifneq ($(INIT), )
FEATURES += run_cmdline
endif
FEATURES += board_$(BOARD)
build_args := \
-Z build-std=core,alloc \
--target targets/$(target).json \
--features "$(FEATURES)"
ifeq ($(MODE), release)
build_args += --release
endif
### prefix ###
ifeq ($(ARCH), x86_64)
ifeq ($(shell uname), Darwin)
prefix := x86_64-linux-musl-
endif
else ifeq ($(ARCH), riscv32)
prefix := riscv64-linux-musl-
else ifeq ($(ARCH), riscv64)
prefix := riscv64-linux-musl-
else ifeq ($(ARCH), mipsel)
prefix ?= mipsel-linux-musln32-
else ifeq ($(ARCH), aarch64)
prefix ?= aarch64-linux-musl-
endif
gdb := gdb
sysroot := $(shell rustc --print sysroot)
objdump := $(shell find $(sysroot) -name llvm-objdump) -print-imm-hex
objcopy := $(shell find $(sysroot) -name llvm-objcopy)
strip := $(shell find $(sysroot) -name llvm-strip)
dtc := dtc
hostcc := gcc
.PHONY: all clean build asm doc debug kernel sfsimg install run justrun test justtest
all: kernel
clean:
@cargo clean
@cd $(user_dir) && make clean
doc:
@cargo doc $(build_args) --no-deps --document-private-items
run: build justrun
test: build justtest
justrun:
@$(qemu) $(qemu_opts)
justtest:
# unavailable now
@#$(qemu) $(filter-out -serial mon:stdio, $(qemu_opts)) --append $(INIT) -serial file:../tests/stdout -monitor null
debug: $(kernel) $(kernel_img)
@$(qemu) $(qemu_opts) -s -S &
@sleep 1
@$(gdb) $(kernel) -x ../tools/gdbinit
justdebug:
@$(qemu) $(qemu_opts) -s -S
build: $(kernel_img)
asm:
@$(objdump) -d $(kernel) | less
header:
@$(objdump) -h $(kernel)
sym:
@$(objdump) -t $(kernel) | less
### device tree process ###
%.dtb: %.dts
@echo Generating device tree file $@
@$(dtc) -I dts -O dtb -o $@ $<
@rm -rf src/arch/${arch}/boot/dtb.gen.s
### bootloader and kernel image ###
bootloader: $(kernel)
ifeq ($(ARCH), x86_64)
@cd ../rboot && make build
endif
$(kernel_img): kernel bootloader
ifeq ($(ARCH), x86_64)
mkdir -p $(ESP)/EFI/rCore $(ESP)/EFI/Boot
@cp ../rboot/target/x86_64-unknown-uefi/$(MODE)/rboot.efi $(ESP)/EFI/Boot/BootX64.efi
@cp ../rboot/rboot.conf $(ESP)/EFI/Boot/rboot.conf
@cp $(kernel) $(ESP)/EFI/rCore/kernel.elf
else ifeq ($(ARCH), $(filter $(ARCH), riscv32 riscv64))
@$(objcopy) $(kernel) --strip-all -O binary $@
else ifeq ($(ARCH), aarch64)
@$(objcopy) $(kernel) --strip-all -O binary $@
else ifeq ($(ARCH), mipsel)
# qemu-system-mipsel accepts ELF file only, so objcopy is not needed
@$(strip) $(kernel) -o $@
endif
kernel: $(DTB)
@echo Building $(ARCH) kernel
ifeq ($(ARCH), $(filter $(ARCH), riscv32 riscv64))
@cp src/arch/riscv/board/u540/linker.ld src/arch/riscv/boot/linker64.ld
@-patch -p0 -N -b \
$(sysroot)/lib/rustlib/src/rust/src/libcore/sync/atomic.rs \
src/arch/riscv/atomic.patch
else ifeq ($(ARCH), mipsel)
@for file in entry ; do \
$(hostcc) -Dboard_$(BOARD) -E src/arch/$(ARCH)/boot/$${file}.S -o src/arch/$(ARCH)/boot/$${file}.gen.s ; \
done
$(hostcc) -Dboard_$(BOARD) -E src/arch/$(ARCH)/boot/linker.ld.S -o src/arch/$(ARCH)/boot/linker.ld
endif
@cargo build $(build_args)
### user programs ###
sfsimg:
@cd $(user_dir) && make sfsimg
### install ###
ifeq ($(BOARD), raspi3)
sd_card ?=
ifeq ($(shell uname), Darwin)
sd_card := /Volumes/boot
else ifeq ($(shell uname), Linux)
sd_card := /media/$(shell whoami)/boot
endif
ifdef sd_card
.PHONY:
install: $(kernel_img)
cp $(kernel_img) $(sd_card)/kernel8.img
sudo umount $(sd_card)
endif
endif
ifeq ($(BOARD), u540)
.PHONY:
install: $(kernel_img)
@$(objcopy) -S -O binary ../tools/opensbi/fu540.elf $(build_path)/bin
@dd if=$< of=$(build_path)/bin bs=0x20000 seek=16
@../tools/u540/mkimg.sh $(build_path)/bin $(build_path)/u540.img
endif
.PHONY:
addr2line:
@python3 ../tools/addr2line.py $(prefix)addr2line $(ARCH) $(MODE)