-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGNUmakefile
More file actions
185 lines (152 loc) · 5.76 KB
/
GNUmakefile
File metadata and controls
185 lines (152 loc) · 5.76 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
# Nuke built-in rules and variables.
# Auto-detect CPU cores for parallel compilation (override with: make JOBS=4)
JOBS ?= $(shell nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)
override MAKEFLAGS += -rR -j $(JOBS)
override IMAGE_NAME := cottage
# set to true to use the nightly OVMF image
OVMF_USE_NIGHTLY := false
# Convenience macro to reliably declare user overridable variables.
define DEFAULT_VAR =
ifeq ($(origin $1),default)
override $(1) := $(2)
endif
ifeq ($(origin $1),undefined)
override $(1) := $(2)
endif
endef
OVMF_IMAGE := /usr/share/ovmf/OVMF.fd
ifeq ($(OVMF_USE_NIGHTLY),true)
OVMF_IMAGE := ovmf/OVMF.fd
endif
# Toolchain for building the 'limine' executable for the host.
override DEFAULT_HOST_CC := cc
$(eval $(call DEFAULT_VAR,HOST_CC,$(DEFAULT_HOST_CC)))
override DEFAULT_HOST_CFLAGS := -g -O2 -pipe
$(eval $(call DEFAULT_VAR,HOST_CFLAGS,$(DEFAULT_HOST_CFLAGS)))
override DEFAULT_HOST_CPPFLAGS :=
$(eval $(call DEFAULT_VAR,HOST_CPPFLAGS,$(DEFAULT_HOST_CPPFLAGS)))
override DEFAULT_HOST_LDFLAGS :=
$(eval $(call DEFAULT_VAR,HOST_LDFLAGS,$(DEFAULT_HOST_LDFLAGS)))
override DEFAULT_HOST_LIBS :=
$(eval $(call DEFAULT_VAR,HOST_LIBS,$(DEFAULT_HOST_LIBS)))
.PHONY: all
all: $(IMAGE_NAME).iso
.PHONY: all-hdd
all-hdd: $(IMAGE_NAME).hdd
# alias test=run-uefi (cuts down on keystrokes)
.PHONY: test
test: run-uefi
# stress test target - builds with stress tests enabled and runs multiple iterations
# Usage: make stress-test ITERATIONS=10 TIMEOUT=30
.PHONY: stress-test
stress-test:
./scripts/stress-test.sh $(ITERATIONS) $(TIMEOUT)
# parallel boot test for race condition debugging
# Usage: make test-parallel RUNS=50 CPUS=2 PARALLEL=6
# If PARALLEL not specified, auto-detects based on host CPUs / CPUS per VM
.PHONY: test-parallel
test-parallel: ovmf $(IMAGE_NAME).iso
ifdef PARALLEL
./scripts/test-parallel.sh -n $(or $(RUNS),20) -c $(or $(CPUS),2) -j $(PARALLEL)
else
./scripts/test-parallel.sh -n $(or $(RUNS),20) -c $(or $(CPUS),2)
endif
# headless test for CI/automated testing (no GUI window)
# Usage: make test-headless TIMEOUT=30 (runs for 30 seconds then exits)
# Without TIMEOUT, runs until crash or manual termination
.PHONY: test-headless
test-headless: ovmf $(IMAGE_NAME).iso
ifdef TIMEOUT
timeout $(TIMEOUT) qemu-system-x86_64 $(QEMU_FLAGS) -display none -bios $(OVMF_IMAGE) -cdrom $(IMAGE_NAME).iso -boot d || true
else
qemu-system-x86_64 $(QEMU_FLAGS) -display none -bios $(OVMF_IMAGE) -cdrom $(IMAGE_NAME).iso -boot d
endif
QEMU_FLAGS := -d cpu_reset -smp cpus=1 -M q35 -m 2G -serial stdio -action panic=none
# Networking: e1000e NIC (e1000e supports MSI)
# Use TAP=1 for host-to-guest connectivity (requires: sudo ./scripts/setup-tap.sh)
# Default is user-mode networking (guest can reach out, but host can't ping in)
ifdef TAP
QEMU_FLAGS += -netdev tap,id=net0,ifname=tap0,script=no,downscript=no -device e1000e,netdev=net0
else
QEMU_FLAGS += -netdev user,id=net0 -device e1000e,netdev=net0
endif
# Packet capture: use PCAP=1 to dump packets to packets.pcap
# Usage: make run-uefi PCAP=1
ifdef PCAP
QEMU_FLAGS += -object filter-dump,id=dump0,netdev=net0,file=packets.pcap
endif
# For stress testing, use multiple CPUs to maximize race condition detection
QEMU_STRESS_FLAGS := -d cpu_reset -smp cpus=4 -M q35 -m 2G -serial stdio -action panic=none
# uncomment to start gdbserver and freeze on launch
# QEMU_FLAGS += -S -s
.PHONY: run
run: $(IMAGE_NAME).iso
qemu-system-x86_64 $(QEMU_FLAGS) -cdrom $(IMAGE_NAME).iso -boot d
.PHONY: run-uefi
run-uefi: ovmf $(IMAGE_NAME).iso
qemu-system-x86_64 $(QEMU_FLAGS) -bios $(OVMF_IMAGE) -cdrom $(IMAGE_NAME).iso -boot d
.PHONY: run-hdd
run-hdd: $(IMAGE_NAME).hdd
qemu-system-x86_64 $(QEMU_FLAGS) -hda $(IMAGE_NAME).hdd
.PHONY: run-hdd-uefi
run-hdd-uefi: ovmf $(IMAGE_NAME).hdd
qemu-system-x86_64 $(QEMU_FLAGS) -bios ovmf/OVMF.fd -hda $(IMAGE_NAME).hdd
ovmf:
mkdir -p ovmf
cd ovmf && curl -Lo OVMF.fd https://retrage.github.io/edk2-nightly/bin/RELEASEX64_OVMF.fd
limine:
git clone https://github.com/limine-bootloader/limine.git --branch=v5.x-branch-binary --depth=1
$(MAKE) -C limine \
CC="$(HOST_CC)" \
CFLAGS="$(HOST_CFLAGS)" \
CPPFLAGS="$(HOST_CPPFLAGS)" \
LDFLAGS="$(HOST_LDFLAGS)" \
LIBS="$(HOST_LIBS)"
ifdef COTTAGE_DEBUG
KERNEL_MAKEFLAGS := COTTAGE_DEBUG=1
else
KERNEL_MAKEFLAGS :=
endif
ifdef COTTAGE_STRESS_TEST
KERNEL_MAKEFLAGS += COTTAGE_STRESS_TEST=1
endif
.PHONY: kernel
kernel:
$(MAKE) -C kernel $(KERNEL_MAKEFLAGS)
.PHONY: init
init:
$(MAKE) -C init
$(IMAGE_NAME).iso: limine kernel init
rm -rf iso_root
mkdir -p iso_root
cp -v kernel/bin/kernel init/bin/initramfs.tar \
limine.cfg limine/limine-bios.sys limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/
mkdir -p iso_root/EFI/BOOT
cp -v limine/BOOTX64.EFI iso_root/EFI/BOOT/
cp -v limine/BOOTIA32.EFI iso_root/EFI/BOOT/
xorriso -as mkisofs -b limine-bios-cd.bin \
-no-emul-boot -boot-load-size 4 -boot-info-table \
--efi-boot limine-uefi-cd.bin \
-efi-boot-part --efi-boot-image --protective-msdos-label \
iso_root -o $(IMAGE_NAME).iso
./limine/limine bios-install $(IMAGE_NAME).iso
rm -rf iso_root
$(IMAGE_NAME).hdd: limine kernel init
rm -f $(IMAGE_NAME).hdd
dd if=/dev/zero bs=1M count=0 seek=64 of=$(IMAGE_NAME).hdd
sgdisk $(IMAGE_NAME).hdd -n 1:2048 -t 1:ef00
./limine/limine bios-install $(IMAGE_NAME).hdd
mformat -i $(IMAGE_NAME).hdd@@1M
mmd -i $(IMAGE_NAME).hdd@@1M ::/EFI ::/EFI/BOOT
mcopy -i $(IMAGE_NAME).hdd@@1M kernel/bin/kernel limine.cfg limine/limine-bios.sys ::/
mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTX64.EFI ::/EFI/BOOT
mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTIA32.EFI ::/EFI/BOOT
.PHONY: clean
clean:
rm -rf iso_root $(IMAGE_NAME).iso $(IMAGE_NAME).hdd
$(MAKE) -C kernel clean
$(MAKE) -C init clean
.PHONY: distclean
distclean: clean
rm -rf limine ovmf
$(MAKE) -C kernel distclean