summaryrefslogtreecommitdiff
path: root/Makefile
blob: 03b85a2d1ec6da5e9b2f44f6c7c868292af16fdb (plain)
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)