-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathzeptux.zbuild
128 lines (113 loc) · 5.09 KB
/
zeptux.zbuild
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
# This option causes `cc` to automatically set -MD and causes build steps to use
# generated dependency files to determine whether build steps must take place.
option compute_dependencies
# We default to building `zeptux.img`.
set special default = zeptux.img
# Include files automatically added to `cc` and `c++` statements.
set special includes = include arch/x86_64/include .
# Force rebuild whenever these files are changed.
set special global_file_deps = zeptux.zbuild .clang-format
# Specify the flags to pass to gcc.
set var BOOT_CFLAGS = --std=gnu2x -fno-builtin -fno-stack-protector -nostdinc -Wall -Wextra -Werror -mno-sse -mno-sse2 -mno-mmx -mno-3dnow -mno-avx -Wno-stringop-overflow -fno-omit-frame-pointer -Wno-main -Wno-format-zero-length -D__ZEPTUX_KERNEL
set var CFLAGS = $BOOT_CFLAGS
set var CFLAGS += -g -O2
# We place the size of the ELF image at a certain offset into the final output
# image for the bootloader to read and provide to the kernel (yes the ELF
# standard is lacking!) It is set to 5 sectors into the boot image minus
# sizeof(uint32_t) = 512 * 5 - 4. NOTE: update if number of stage 2 bootsectors
# increases.
set var ELF_SIZE_OFFSET = 2556
# The BIOS ELF loader is loaded at 0x8600 and conventional memory ends at
# 0x80000. That leaves 0x77a00, but we want to leave 16 KiB for the kernel stack
# and 512 bytes for sector rounding up on boot.
set var MAX_KERNEL_ELF_SIZE = 473088
# Shared qemu options.
set var QEMU_OPT = -serial mon:stdio -smp 4 -m 1G -cpu Broadwell
# Options specific to release. We invoke intentional reset on early test exit so
# cannot have these debug options set.
set var QEMU_OPT_RELEASE = $QEMU_OPT -d int,cpu_reset -no-reboot
# Format source files when they change.
prehook [**.h,**.c,**.cpp] on change {
shell clang-format -style=file -i $source
}
# Generate boot.bin (initial boot image).
build [*.o] in arch/x86_64/boot from [*.S, *.c, *.ld] as boot_obj {
foreach source to output excluding *.ld {
cc $BOOT_CFLAGS -c $source -o $output
shell objcopy --remove-section .note.gnu.property $output
}
}
build boot.bin from boot_obj {
ld -T arch/x86_64/boot/boot1.ld -o boot1.bin boot1.o
ld -T arch/x86_64/boot/boot2.ld -o boot2.bin boot2.o loader.o
shell cat boot1.bin boot2.bin > boot.bin
}
# Generate kernel.elf (kernel ELF image).
build [*.o] from [lib/*.c, early/*.c, kernel/*.c, mm/*.c, arch/x86_64/kernel/*.c] excluding kernel/main.c as kernel_obj {
foreach source to output {
cc $CFLAGS -c $source -o $output
}
}
build kernel.elf from [kernel_obj, kernel/main.c, kernel/kernel.ld] {
cc $CFLAGS -c kernel/main.c -o main.o
ld -T kernel/kernel.ld -o kernel.elf $kernel_obj main.o
shell find kernel.elf -size -$(MAX_KERNEL_ELF_SIZE)c | grep -q . # Assert less than maximum size
}
# Generate zeptux.img, final image file combining boot image and kernel.elf.
build zeptux.img from [boot.bin, kernel.elf] {
# TODO: Implement zbuild feature to share this with test-early.img.
shell cp boot.bin zeptux.img
shell truncate -s 2560 zeptux.img # We reserve boot sector + 5 sectors for stage 2.
shell cat kernel.elf >> zeptux.img
shell truncate -s +512 zeptux.img # To avoid overrun on BIOS load
# Patch in the ELF image size for the bootloader.
shell scripts/patch_bin_int.py zeptux.img $ELF_SIZE_OFFSET $$shell{stat -c%s kernel.elf}
}
# Generate test-early.img for early kernel tests.
build [*.o] in test/early from [*.c] as test_early_obj {
foreach source to output {
cc $CFLAGS -Itest/include/ -c $source -o $output
}
}
build test-early.elf from [boot.bin, test_early_obj, kernel_obj, kernel/kernel.ld] {
ld -T kernel/kernel.ld -o test-early.elf $test_early_obj $kernel_obj
shell find test-early.elf -size -$(MAX_KERNEL_ELF_SIZE)c | grep -q . # Assert less than maximum size
}
build test-early.img from [boot.bin, test-early.elf] {
shell cp boot.bin test-early.img
shell truncate -s 2560 test-early.img # We reserve boot sector + 5 sectors for stage 2.
shell cat test-early.elf >> test-early.img
shell truncate -s +512 test-early.img # To avoid overrun on BIOS load
shell scripts/patch_bin_int.py test-early.img $ELF_SIZE_OFFSET $$shell{stat -c%s test-early.elf}
}
# Generate test-user-runner for running tests in userland.
build [*.o] in test/user from [*.cpp] as test_user_obj {
foreach source to output {
c++ -Wall -Werror --std=gnu++2a -g -lpthread -Itest/include/ -c $source -o $output
}
}
build test-user-runner from test_user_obj {
c++ -lpthread -o test-user-runner $test_user_obj
}
# Remove generated binaries and other output.
command clean {
shell rm -f *.o *.img *.bin *.elf test-user-runner .zbuild.* *.d
}
# QEMU execution commands.
command qemu needs zeptux.img {
shell qemu-system-x86_64 -nographic $QEMU_OPT_RELEASE -drive file=zeptux.img,format=raw
}
command qemu-vga needs zeptux.img {
shell qemu-system-x86_64 $QEMU_OPT_RELEASE -drive file=zeptux.img,format=raw
}
# Test commands.
command test-early needs test-early.img {
shell qemu-system-x86_64 -nographic $QEMU_OPT -drive file=test-early.img,format=raw
}
command test-user needs test-user-runner {
@shell ./test-user-runner
}
command test needs [test-early.img, test-user-runner] {
call test-early
call test-user
}