-
Notifications
You must be signed in to change notification settings - Fork 1
/
Makefile
207 lines (166 loc) · 7.16 KB
/
Makefile
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
CFILES=$(shell ls *.c | grep -v boot32.c )
O32FILES=$(CFILES:.c=.o32)
O64FILES=$(CFILES:.c=.o64)
HFILES=$(shell ls *.h)
ASMFILES=$(shell ls *.asm)
OPT=2
CFLAGS=-c -O$(OPT) -std=c99
# -O - basic optimization
CFLAGS+=-Wall -Wextra -Wno-main -Wno-unused-function -Wno-pragmas
# -Wall - give warnings (on most checks)
# -Wextra - give even more warnings (on all checks)
# -Wno-main - suppress warning on main and its parameters (this is a kernel!)
# -Wno-unused-function - suppress warning about unused function (during development...)
# -Wno-pragmas - don't warn about unknown parameters to #pragmas (GCC 4.5 does not know -Wunused-but-set-variable )
CFLAGS+=-fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -fno-zero-initialized-in-bss
# -fstrengh-reduce
# -fomit-frame-pointer
# -finline-functions
# -fnostdinc - don't include standards libs
# -no-builtin - don't use builtin functions for libc (memcpy etc.), we have our own implementations.
# -no-zero-initialized-in-bss
# - don't move variables, that are initialized with 0 (zero) to the .bss segment
# because that will not be filled with zeros (the kernel is not loaded by ld.so)
CFLAGS+=-I .
# -I . - add include directory '.'
# default nbr of CPUs for QEMU smp
SMP=2
# default command line for QEMU
CMDLINE=test
C32FLAGS=$(CFLAGS)
C64FLAGS=$(CFLAGS) -ffreestanding -mcmodel=large -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow
# extra Parameters for 64 bit C code
# -ffreestanding
# -mcmodel=large
# -mno-red-zone - do not assume a red-zone (reserved space on stack)
# -mno-mmx
# -mno-sse
# -mno-sse2
# -mno-sse3
# -mno-3dnow
CC32=gcc -m32
CC64=gcc -m64
# symbols from 64 bit kernel (kernel64.elf64) to be transferred to kernel64.bin
KERNEL64_SYMBOLS="Realm32 Realm64 main hw_info isr0 idt"
default : tags kernel32.bin kernel64.bin
help :
@echo 'Makefile for Multiboot kernel'
@echo 'available targets:'
@echo ' default default target is: tags kernel32 kernel64'
@echo ' debug show internal variables (for debug purposes)'
@echo ' tags create ctags table'
@echo ' depend recreate dependencies (is done automatically when needed)'
@echo ' kernel32 -> kernel32.bin'
@echo ' kernel64 -> kernel64.bin'
@echo ' q32 build kernel32.bin and boot it in QEmu'
@echo ' q64 build kernel64.bin and boot it in QEmu'
@echo ' s32 build kernel32.bin and boot it in SMP-QEmu (SMP=2)'
@echo ' s64 build kernel64.bin and boot it in SMP-QEmu (SMP=2)'
@echo ' use "make SMP=4 s64" to configure the number of CPUs'
@echo ' xaxis build both kernels and copy to xaxis (using scp)'
@echo ' clean remove intermediate and built files'
debug :
@echo CFILES: $(CFILES)
@echo O32FILES: $(O32FILES)
@echo O64FILES: $(O64FILES)
@echo CFLAGS: $(CFLAGS)
config.inc : config.h
@echo CONVERT $< '->' $@
@echo "; do not edit this file, it is generated from config.h" > $@
@echo "; vim: set ft=asm:" >> $@
@grep '^#' $< | sed 's/^#/%/' >> $@
# PHONY: update temp file in any case
version.tmp :
@echo "UPDATE version.tmp"
@echo '#define SVN_REV "'$$(git rev-parse HEAD | awk '{ print substr($$0, 1, 7); }')'"' > version.tmp
@echo '#define OPT "'$(OPT)'"' >> version.tmp
# only if tmp and h differ: update version.h
# This way, the depending files are only updated, when the content changes (not when the timestamp changes; which is every call to make)
version.h : version.tmp
@echo "UPDATE version.h"
@if test -r version.h && diff version.h version.tmp 2>&1 >/dev/null ; then rm version.tmp; else mv version.tmp version.h; fi
# 32 bit start code for 32 bit kernel
start32.o : start32.asm start.asm start_smp.inc config.inc
@echo NASM $< '->' $@
@nasm -f aout -o $@ $<
# 32 bit start code for 64 bit kernel
start64.o : start64.asm start.asm
@echo NASM $< '->' $@
@nasm -f elf32 -o $@ $<
# 64 bit jump code for 64 bit kernel
jump64.o : jump64.asm start_smp.inc config.inc
@echo NASM $< '->' $@
@nasm -f elf64 -o $@ $<
scrn.o : scrn.c
@echo CC32 $< '->' $@
@$(CC32) $(C32FLAGS) -DEARLY -o $@ $<
# C files into 32 bit objects
$(O32FILES) : %.o32 : %.c
@echo CC32 $< '->' $@
@$(CC32) $(C32FLAGS) -o $@ $<
boot32.o : boot32.c
@echo CC32 $< '->' $@
@$(CC32) $(C32FLAGS) -o $@ $<
# C files into 64 bit objects
$(O64FILES) : %.o64 : %.c
@echo CC64 $< '->' $@
@$(CC64) $(C64FLAGS) -o $@ $<
# link 32 bit kernel (a.out-multiboot)
kernel32 : kernel32.bin
kernel32.bin : link32.ld start32.o boot32.o $(O32FILES)
@echo LD $^ '->' $@
@ld -T link32.ld -m i386linux -o $@ start32.o boot32.o $(O32FILES)
# link 64 bit kernel that will be embedded into kernel64.bin
kernel64.elf64 : link64.ld jump64.o $(O64FILES)
@echo LD $^ '->' $@
@ld -nostdlib -nodefaultlibs -T link64.ld -o kernel64.elf64 jump64.o $(O64FILES)
# generate .KERNEL64 section's data from 64 bit kernel
kernel64.section : kernel64.elf64
@echo GETSECTION $^ '->' $@
@readelf -SW "kernel64.elf64" | python getsection.py 0x140000 kernel64.elf64 kernel64.section
# export wanted symbols from KERNEL64 from 64 bit kernel
kernel64.symbols : kernel64.elf64
@echo GETSYMBOLS $^ '->' $@
@readelf -sW "kernel64.elf64" | python getsymbols.py $(KERNEL64_SYMBOLS) kernel64.symbols
# add section .KERNEL64 with 64 bit code and data to 32 bit start code (will still be ELF32)
kernel64.o : start64.o kernel64.section
@echo OBJCOPY $^ '->' $@
@objcopy --add-section .KERNEL64="kernel64.section" --set-section-flag .KERNEL64=alloc,data,load,contents start64.o kernel64.o
# finally link 32 bit start code with implanted .KERNEL64 (opaque blob)
# to a relocated ELF32-multiboot kernel image
kernel64 : kernel64.bin
kernel64.bin : link_start64.ld kernel64.symbols kernel64.o boot32.o scrn.o lib.o32
@echo LD $^ '->' $@
@ld -melf_i386 -T link_start64.ld -T kernel64.symbols kernel64.o boot32.o scrn.o lib.o32 -o kernel64.bin
depend : .depend
.depend : $(CFILES) boot32.c
@echo DEPEND $^
@$(CC) -MM $^ | sed "s+\(.*\):\(.*\)+\1 \132 \164 :\2+" > $@
# The sed regex prints every target left of ':' three time: the original
# and two versions for 32 and 64 bit objects:
# xxx.o : xxx.c yyy.h zzz.h
# becomes:
# xxx.o xxx.o32 xxx.o64 : xxx.c yyy.h zzz.h
# The part right of the colon is not changed.
# The regex catches the parts left and right of the ':' in '\(.*\)' (with arbitrary characters)
# and the catched expressions are issued by \1 and \2 (each tree times, separated by newlin \n)
-include .depend
tags : $(CFILES) boot32.c $(HFILES) $(ASMFILES)
@echo CTAGS
@ctags -R *.c *.h *.asm
# start QEMU with 32 or 64 bit
q32 : kernel32.bin
qemu -kernel kernel32.bin -append "$(CMDLINE)"
q64 : kernel64.bin
qemu-system-x86_64 -kernel kernel64.bin -append "$(CMDLINE)"
smp : s64
s32 : kernel32.bin
qemu -smp $(SMP) -kernel kernel32.bin -append "$(CMDLINE)"
s64 : kernel64.bin
qemu-system-x86_64 -smp $(SMP) -kernel kernel64.bin -append "$(CMDLINE)"
xaxis : kernel32.bin kernel64.bin
scp kernel??.bin root@xaxis:/boot/
# housekeeping
clean :
-rm -f *.o *.o32 *.o64 *.symbols *.section *.bin *.elf64 .depend config.inc tags
.PHONY : default help debug q32 q64 s32 s64 kernel32 kernel64 clean depend version.tmp