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
|
CC = clang
LD = ld.lld
OBJCOPY = llvm-objcopy
ARCH_FLAG = \
--target=riscv32-unknown-elf \
-march=rv32im \
-mabi=ilp32 \
-D__SYS_LITTLE_ENDIAN__
COMMON_FLAGS = \
-ffreestanding \
-fno-builtin \
-fno-stack-protector \
-fno-exceptions \
-fno-rtti \
-fno-unwind-tables \
-fno-asynchronous-unwind-tables \
-nostdlib \
-nostdinc \
-nodefaultlibs \
KERNEL_FLAG = $(COMMON_FLAGS) -static
MODULE_FLAG = $(COMMON_FLAGS) -fPIC -fpie
SECTION_FLAG = \
-ffunction-sections \
-fdata-sections \
-fno-common
INCLUDE_FLAG = -Iinclude -Ikernel
OPT_FLAG = -O2 -g3
WARN_FLAG = -Wall -Wextra -Werror -Wundef
KERNEL_LD_FLAG = -T linker.ld -nostdlib -m elf32lriscv --gc-sections
MODULE_LD_FLAG = -nostdlib -shared -m elf32lriscv --gc-sections
KERNEL_OBJCOPY_FLAG = -O binary \
--strip-all \
--remove-section=.comment \
--remove-section=.debug* \
--remove-section=.note* \
--remove-section=.eh_frame \
--remove-section=.eh_frame_ptr \
--remove-section=.eh_frame_hdr
MODULE_OBJCOPY_FLAG = \
--strip-debug \
--remove-section=.comment \
--remove-section=.note*
KERNEL_CFLAGS = $(ARCH_FLAG) $(KERNEL_FLAG) $(SECTION_FLAG) $(INCLUDE_FLAG) $(OPT_FLAG) $(WARN_FLAG)
MODULE_CFLAGS = $(ARCH_FLAG) $(MODULE_FLAG) $(SECTION_FLAG) $(INCLUDE_FLAG) $(OPT_FLAG) $(WARN_FLAG) -D__KERNEL_MODULE__
MODULES = $(wildcard $(shell grep '^modules:' BuildConfig | sed 's/^modules://' | awk '{$$1=$$1; print}'))
MODULE_OBJECTS = $(foreach m,$(MODULES),$m/$m.ko)
define module_template
$(1)_SRCS = $$(wildcard $$(shell grep '^$(1):' BuildConfig | sed 's/^$(1)://' | awk '{$$$$1=$$$$1; print}'))
$(1)_ELF = $(1)/$(1).elf
$(1)_BIN = $(1)/$(1).ko
$(1)_C_SRCS = $$(filter %.c,$$($(1)_SRCS))
$(1)_S_SRCS = $$(filter %.S,$$($(1)_SRCS))
$(1)_C_OBJS = $$($(1)_C_SRCS:.c=.o)
$(1)_S_OBJS = $$($(1)_S_SRCS:.S=.o)
$(1)_OBJS = $$($(1)_C_OBJS) $$($(1)_S_OBJS)
$$($(1)_C_OBJS): %.o: %.c
@echo " CC [MOD] $$<"
$$(CC) $$(MODULE_CFLAGS) -c $$< -o $$@
$$($(1)_S_OBJS): %.o: %.S
@echo " AS [MOD] $$<"
$$(CC) $$(MODULE_CFLAGS) -c $$< -o $$@
$$($(1)_ELF): $$($(1)_OBJS)
@echo " LD [MOD] $$@"
$$(LD) $$(MODULE_LD_FLAG) $$^ -o $$@
$$($(1)_BIN): $$($(1)_ELF)
@echo " OBJCOPY [MOD] $$@"
$$(OBJCOPY) $$(MODULE_OBJCOPY_FLAG) $$^ $$@
endef
$(foreach module,$(MODULES),$(eval $(call module_template,$(module))))
KERNEL_SRCS = $(wildcard $(shell grep '^kernel:' BuildConfig | sed 's/^kernel://' | awk '{$$1=$$1; print}'))
KERNEL_OBJS = $(KERNEL_SRCS:.c=.o)
KERNEL_OBJS := $(KERNEL_OBJS:.S=.o)
KERNEL_BIN = kernel/kernel.bin
KERNEL_ELF = kernel/kernel.elf
GENERATED = \
$(KERNEL_OBJS) \
$(KERNEL_ELF) \
$(KERNEL_BIN) \
$(foreach m,$(MODULES),$(m)/$(m).elf) \
$(foreach m,$(MODULES),$(m)/$(m).ko) \
$(foreach m,$(MODULES),$($(m)_OBJS))
.PHONY: all kernel clean modules $(MODULES)
.SILENT:
all: kernel modules
kernel: $(KERNEL_BIN)
modules: $(MODULES)
$(MODULES): $(MODULE_OBJECTS)
%.o: %.c
@echo " CC $<"
$(CC) $(KERNEL_CFLAGS) -c $< -o $@
%.o: %.S
@echo " AS $<"
$(CC) $(KERNEL_CFLAGS) -c $< -o $@
$(KERNEL_ELF): $(KERNEL_OBJS) linker.ld | $(KERNEL_OUTDIR)/
@echo " LD $@"
$(LD) $(KERNEL_LD_FLAG) $(KERNEL_OBJS) -o $@
$(KERNEL_BIN): $(KERNEL_ELF) | $(KERNEL_OUTDIR)/
@echo " OBJCOPY $@"
$(OBJCOPY) $(KERNEL_OBJCOPY_FLAG) $(KERNEL_ELF) $(KERNEL_BIN)
clean:
@echo " CLEAN"
$(RM) $(GENERATED)
|