-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
243 lines (202 loc) · 7.91 KB
/
Copy pathMakefile
File metadata and controls
243 lines (202 loc) · 7.91 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
# Toolchain definition
CROSS_COMPILE ?= aarch64-none-elf-
CC = $(CROSS_COMPILE)gcc
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
OBJCOPY = $(CROSS_COMPILE)objcopy
STRIP = $(CROSS_COMPILE)strip
IMG_NAME ?= Image
# Project structure
BUILD_DIR ?= build
SRC_DIR = src
INCLUDES = -I$(SRC_DIR)/include
LINKER_LDS_SCRIPT = $(SRC_DIR)/include/linker/linker.lds
LINKER_LD_SCRIPT = $(LINKER_LDS_SCRIPT:%.lds=$(BUILD_DIR)/linker.ld)
LINKER_PRE_PROCESSOR_FLAGS = -E -P -x c
# Flags
# -Wall -Wextra: Enable common and extra warnings
# -ffreestanding: No hosted standard-library environment
# -nostdlib: Don't link system startup files or libc
# -mgeneral-regs-only: Use only general-purpose registers; no FP/SIMD.
# FP/SIMD is not enabled at EL1 (CPACR_EL1.FPEN), and the
# AArch64 variadic ABI otherwise spills v0-v7 in the
# prologue -- those stores trap when the FPU is off, which
# is why kprintf's printf fails without this. Standard for
# a kernel that doesn't save/restore FP/SIMD state.
# -fno-pic / -fno-pie: Generate position-dependent code. Symbol references are
# then direct PC-relative adrp/add instead of going through
# the GOT (whose slots hold absolute, low, link-time
# addresses). After the switch to the high half, PC-relative
# refs resolve to high VAs automatically; GOT indirection
# would keep them low and break va_to_pa.
# -mcmodel=small: AArch64 default, pinned defensively. small uses adrp+add
# (PC-relative, ~4GB reach), which resolves correctly at any high
# base because adrp encodes the relative page distance, not the
# absolute address. Avoids -mcmodel=large (absolute movz/movk
# immediates = low link-time address, breaks the high-half
# switch) and -mcmodel=tiny (1MB code+data cap).
CFLAGS = -c -Wall -Wextra -ffreestanding -nostdlib -mgeneral-regs-only \
-fno-pic -fno-pie -mcmodel=small
ASFLAGS = -c -x assembler-with-cpp
LDFLAGS = -T $(LINKER_LD_SCRIPT)
# Automatic header dependency tracking. -MMD writes a .d file next to each
# object listing the headers it includes; -MP adds a phony target for each of
# those headers so a later-deleted header doesn't break the build. The .d files
# are pulled in via -include at the bottom of this file so touching a header
# rebuilds exactly the objects that use it.
DEPFLAGS = -MMD -MP
DEBUG_FLAGS = -g
RELEASE_FLAGS = -O3
# build type: debug or release (default: release)
BUILD_TYPE = release
ifeq ($(DEBUG),1)
BUILD_TYPE = debug
else
BUILD_TYPE = release
endif
# Output binary name
TARGET_ELF = $(BUILD_DIR)/images/$(IMG_NAME).elf
TARGET = $(BUILD_DIR)/images/$(IMG_NAME)
# Source files
SRCS_C = $(SRC_DIR)/kernel/allocator/kalloc.c \
$(SRC_DIR)/kernel/allocator/page_allocator.c \
$(SRC_DIR)/kernel/exit/exit.c \
$(SRC_DIR)/kernel/main.c \
$(SRC_DIR)/kernel/drivers/arm_timer.c \
$(SRC_DIR)/kernel/drivers/gicv3.c \
$(SRC_DIR)/kernel/drivers/uart.c \
$(SRC_DIR)/kernel/error/panic.c \
$(SRC_DIR)/kernel/error/error_strings.c \
$(SRC_DIR)/kernel/exception_handling/handler.c \
$(SRC_DIR)/kernel/fdt/fdt.c \
$(SRC_DIR)/kernel/icu/icu.c \
$(SRC_DIR)/kernel/mem_layout/mem_layout.c \
$(SRC_DIR)/kernel/mmu/mmu.c \
$(SRC_DIR)/kernel/page_table/page_table.c \
$(SRC_DIR)/kernel/timer/timer.c \
$(SRC_DIR)/kernel/utils/kprintf.c \
$(SRC_DIR)/kernel/utils/string.c \
$(SRC_DIR)/kernel/utils/utils.c
SRCS_AS = $(SRC_DIR)/boot/boot.s \
$(SRC_DIR)/kernel/exception_handling/vector.s \
$(SRC_DIR)/kernel/mmu/trampoline.s
# only used for formatting and linting
SRCS_H = $(shell find $(SRC_DIR) -name '*.h')
OBJS_C = $(SRCS_C:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o)
OBJS_AS = $(SRCS_AS:$(SRC_DIR)/%.s=$(BUILD_DIR)/%.o)
OBJS = $(OBJS_C) $(OBJS_AS)
# --- Verbosity Control ---
# If V is not 1, we prefix commands with @ to hide them.
ifeq ($(V),1)
VERBOSE_PREFIX :=
else
VERBOSE_PREFIX := @
endif
ifeq ($(BUILD_TYPE),debug)
CFLAGS += $(DEBUG_FLAGS)
else
CFLAGS += $(RELEASE_FLAGS)
POST_BUILD = $(VERBOSE_PREFIX)$(STRIP) --strip-all $<
endif
ifeq ($(TEST),1)
CFLAGS += -DRUN_TESTS
TEST_SRCS = $(shell find tests/ -name '*.c')
TEST_OBJS = $(TEST_SRCS:tests/%.c=$(BUILD_DIR)/tests/%.o)
OBJS += $(TEST_OBJS)
endif
# --- libfdt ---
LIBFDT_DIR = ./external/dtc/libfdt
INCLUDES += "-I$(LIBFDT_DIR)"
LIBFDT_OBJS := fdt.o fdt_ro.o fdt_wip.o fdt_sw.o fdt_rw.o \
fdt_strerror.o fdt_empty_tree.o fdt_addresses.o \
fdt_overlay.o
LIBFDT_TARGETS := $(addprefix $(BUILD_DIR)/libfdt/, $(LIBFDT_OBJS))
# Dependency files generated by DEPFLAGS, one per object (incl. test/libfdt
# objects). Pulled in via -include at the bottom of this file.
DEPS = $(OBJS:.o=.d) $(LIBFDT_TARGETS:.o=.d)
.PHONY: all \
submodules \
clean \
docs \
clean-docs \
format \
clang-tidy \
clang-tidy-fix \
tools/register_decoder
all: $(TARGET) tools/register_decoder docs clang-tidy
submodules:
@echo "Ensuring git submodules are initialized..."
$(VERBOSE_PREFIX)git submodule update --init --recursive
# Convert ELF to raw Binary
$(TARGET): $(TARGET_ELF)
@mkdir -p $(dir $@)
$(POST_BUILD)
@echo "OBJCOPY $@"
$(VERBOSE_PREFIX)$(OBJCOPY) -O binary $< $@
# Compile C files
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
@mkdir -p $(dir $@)
@echo "CC $<"
$(VERBOSE_PREFIX)$(CC) $(CFLAGS) $(DEPFLAGS) $(INCLUDES) $< -o $@
# Compile assembly files
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.s
@mkdir -p $(dir $@)
@echo "CC $<"
$(VERBOSE_PREFIX)$(CC) $(ASFLAGS) $(DEPFLAGS) $(INCLUDES) $< -o $@
# Preprocess the linker script to resolve symbols and generate
# the final linker script used for linking
$(LINKER_LD_SCRIPT): $(LINKER_LDS_SCRIPT)
@mkdir -p $(dir $@)
@echo "Processing linker script..."
$(VERBOSE_PREFIX)$(CC) $(LINKER_PRE_PROCESSOR_FLAGS) $(INCLUDES) $< -o $@
# Link the kernel
$(TARGET_ELF): $(OBJS) $(LIBFDT_TARGETS) $(LINKER_LD_SCRIPT)
@mkdir -p $(dir $@)
@echo "LD $@"
$(VERBOSE_PREFIX)$(LD) $(LDFLAGS) $(OBJS) $(LIBFDT_TARGETS) -o $@
$(BUILD_DIR)/libfdt/%.o: $(LIBFDT_DIR)/%.c
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) $(DEPFLAGS) $(INCLUDES) $< -o $@
run: $(TARGET)
@echo "Running QEMU..."
$(VERBOSE_PREFIX)qemu-system-aarch64 -machine virt,gic-version=3 \
-cpu cortex-a57 -nographic -kernel $(TARGET) -no-reboot \
-semihosting
run-as-gdb-server: $(TARGET)
@echo "Running QEMU..."
$(VERBOSE_PREFIX)qemu-system-aarch64 -machine virt,gic-version=3 \
-cpu cortex-a57 -nographic -kernel $(TARGET) -no-reboot \
-semihosting -s -S &
kill-gdb-server:
@echo "Killing Qemu"
$(VERBOSE_PREFIX)sudo kill -9 $$(lsof -t -i :1234)
format: $(SRCS_C) $(SRCS_H) $(TEST_SRCS)
@echo "Formatting source files..."
$(VERBOSE_PREFIX)clang-format -i $^
$(VERBOSE_PREFIX)$(MAKE) -C tools/register_decoder BUILD_DIR=../../$(BUILD_DIR) format
clang-tidy: $(SRCS_C) $(TEST_SRCS)
@echo "Running clang-tidy..."
$(VERBOSE_PREFIX)clang-tidy $^ -- $(CFLAGS) $(INCLUDES) --target=aarch64-linux-gnu
clang-tidy-fix: $(SRCS_C) $(TEST_SRCS)
@echo "Running clang-tidy..."
$(VERBOSE_PREFIX)clang-tidy $^ --fix -- $(CFLAGS) $(INCLUDES) --target=aarch64-linux-gnu
docs:
@echo "Generating Doxygen documentation..."
@mkdir -p build/docs
@doxygen docs/Doxyfile
@echo "Documentation generated at build/docs/html/index.html"
clean-docs:
@echo "Cleaning documentation..."
@rm -rf build/docs
tools/register_decoder:
$(VERBOSE_PREFIX)$(MAKE) -C $@ BUILD_DIR=../../$(BUILD_DIR)
$(BUILD_DIR)/tests/%.o: tests/%.c
@mkdir -p $(dir $@)
@echo "CC $<"
$(VERBOSE_PREFIX)$(CC) $(CFLAGS) $(DEPFLAGS) $(INCLUDES) $< -o $@
clean: clean-docs
@echo "Cleaning build directory..."
$(VERBOSE_PREFIX)rm -rf $(BUILD_DIR) $(TARGET) $(TARGET_ELF)
# Pull in auto-generated header dependencies (see DEPFLAGS). The leading '-'
# ignores them when absent, e.g. on the first build before any object exists.
-include $(DEPS)