-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon.mk
120 lines (99 loc) · 3.52 KB
/
common.mk
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
# Common part for the Makefile.
# This file will be included by the Makefile of each project.
# Custom Macro Definition (Common part)
include ../defines.mk
DEFS +=
CROSS_COMPILE = riscv64-unknown-elf-
CFLAGS += -nostdlib -fno-builtin -g -Wall
CFLAGS += -march=rv32g -mabi=ilp32
QEMU = qemu-system-riscv32
QFLAGS = -nographic -smp 1 -machine virt -bios none
GDB = gdb-multiarch
CC = ${CROSS_COMPILE}gcc
OBJCOPY = ${CROSS_COMPILE}objcopy
OBJDUMP = ${CROSS_COMPILE}objdump
MKDIR = mkdir -p
RM = rm -rf
OUTPUT_PATH = out
# SRCS_ASM & SRCS_C are defined in the Makefile of each project.
# $(addprefix src/,foo bar) -> src/foo src/bar
OBJS_ASM := $(addprefix ${OUTPUT_PATH}/, $(patsubst %.S, %.o, ${SRCS_ASM}))
OBJS_C := $(addprefix $(OUTPUT_PATH)/, $(patsubst %.c, %.o, ${SRCS_C}))
OBJS = ${OBJS_ASM} ${OBJS_C}
ELF = ${OUTPUT_PATH}/os.elf
BIN = ${OUTPUT_PATH}/os.bin
USE_LINKER_SCRIPT ?= true
ifeq (${USE_LINKER_SCRIPT}, true)
LDFLAGS = -T ${OUTPUT_PATH}/os.ld.generated
else
LDFLAGS = -Ttext=0x80000000
endif
.DEFAULT_GOAL := all
all: ${OUTPUT_PATH} ${ELF}
# mkdir -p ${OUTPUT_PATH}
${OUTPUT_PATH}:
@${MKDIR} $@
# start.o must be the first in dependency!
#
# For USE_LINKER_SCRIPT == true, before do link, run preprocessor manually for
# linker script.
# -E specifies GCC to only run preprocessor
# -P prevents preprocessor from generating linemarkers (#line directives)
# -x c tells GCC to treat your linker script as C source file
${ELF}: ${OBJS}
ifeq (${USE_LINKER_SCRIPT}, true)
${CC} -E -P -x c ${DEFS} ${CFLAGS} os.ld > ${OUTPUT_PATH}/os.ld.generated
endif
${CC} ${CFLAGS} ${LDFLAGS} -o ${ELF} $^
${OBJCOPY} -O binary ${ELF} ${BIN}
${OUTPUT_PATH}/%.o : %.c
${CC} ${DEFS} ${CFLAGS} -c -o $@ $<
${OUTPUT_PATH}/%.o : %.S
${CC} ${DEFS} ${CFLAGS} -c -o $@ $<
# $ qemu-system-riscv32 -M ?
# Supported machines are:
# none empty machine
# sifive_e RISC-V Board compatible with SiFive E SDK
# sifive_u RISC-V Board compatible with SiFive U SDK
# spike RISC-V Spike Board (default)
# spike_v1.10 RISC-V Spike Board (Privileged ISA v1.10)
# spike_v1.9.1 RISC-V Spike Board (Privileged ISA v1.9.1)
# virt RISC-V VirtIO board
# $ qemu-system-riscv32 -M ? | grep virt
# virt RISC-V VirtIO board
# $ qemu-system-riscv32 -M ? | grep virt >/dev/null
# $ qemu-system-riscv32 -M ? | grep virt >/dev/null || exit
# if "qemu-system-riscv32 -M ? | grep virt >/dev/null" successfully execute,
# which means grep find "virt" in the output of "qemu-system-riscv32 -M ?",
# then nothing will be output; else execute "exit"
.PHONY : run
run: all
@# qemu-system-riscv32 -M ? | grep virt >/dev/null || exit
${QEMU} -M ? | grep virt >/dev/null || exit
@echo "Press Ctrl-A and then X to exit QEMU"
@echo "------------------------------------"
@# qemu-system-riscv32 -nographic -smp 1 -machine virt -bios none -kernel out/os.elf
${QEMU} ${QFLAGS} -kernel ${ELF}
.PHONY : run-qemu
run-qemu: all
@echo "Press Ctrl-A and then X to exit QEMU"
@echo "------------------------------------"
${QEMU} ${QFLAGS} -kernel ${ELF} -gdb tcp::1234 -S
.PHONY : debug
debug: all
@echo "Press Ctrl-C and then input 'quit' to exit GDB and QEMU"
@echo "-------------------------------------------------------"
${QEMU} ${QFLAGS} -kernel ${ELF} -s -S &
${GDB} ${ELF} -q -x ../gdbinit
.PHONY : code
code: all
@${OBJDUMP} -S ${ELF} | less
.PHONY : clean
clean:
@${RM} ${OUTPUT_PATH}
.PHONY : test
test: all
@echo "OBJS_ASM: ${OBJS_ASM}"
@echo "OBJS_C: ${OBJS_ASM}"
@echo "ELF: ${ELF}"
@echo "all: ${all}"