-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMakefile
More file actions
120 lines (97 loc) · 4.09 KB
/
Makefile
File metadata and controls
120 lines (97 loc) · 4.09 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
# Copyright (c) 2025, Rye Stahle-Smith
# December 2nd, 2025 - Makefile
# Description: Build system for compiling, linking, embedding, and running the RISC-V OS and its user programs under QEMU.
AS = riscv64-unknown-elf-as
CC = riscv64-unknown-elf-g++
LD = riscv64-unknown-elf-ld
OBJCOPY = riscv64-unknown-elf-objcopy
CFLAGS = -ffreestanding -nostdlib -march=rv64imaczicsr -mabi=lp64 -O2 -mcmodel=medany
ASFLAGS = -march=rv64imaczicsr -mabi=lp64
OBJS = boot.o kernel.o trap.o trap_S.o shell.o memory.o scheduler.o fat.o embedded_user_programs.o
KERNEL = kernel.elf
LDSCRIPT = linker.ld
PROGRAMS_DIR = user_programs
USER_SOURCES = $(wildcard $(PROGRAMS_DIR)/*.S)
USER_BINS = $(USER_SOURCES:.S=.bin)
# Default target
all: $(PROGRAMS_DIR) $(USER_BINS) embedded_user_programs.c $(KERNEL)
# User Program Pipeline: .S → .o → .elf → .bin
$(PROGRAMS_DIR)/%.o: $(PROGRAMS_DIR)/%.S
$(AS) $(ASFLAGS) $< -o $@
$(PROGRAMS_DIR)/%.elf: $(PROGRAMS_DIR)/%.o
$(LD) -T user_program.ld $< -o $@
$(PROGRAMS_DIR)/%.bin: $(PROGRAMS_DIR)/%.elf
$(OBJCOPY) -O binary $< $@
# Kernel Objects
trap.o: trap.cpp
$(CC) $(CFLAGS) -c $< -o $@
trap_S.o: trap.S
$(CC) $(ASFLAGS) -c $< -o $@
boot.o: boot.S
$(CC) $(ASFLAGS) -c $< -o $@
kernel.o: kernel.cpp
$(CC) $(CFLAGS) -c $< -o $@
shell.o: shell.cpp shell.h
$(CC) $(CFLAGS) -c $< -o $@
memory.o: memory.cpp memory.h
$(CC) $(CFLAGS) -c $< -o $@
scheduler.o: scheduler.cpp scheduler.h
$(CC) $(CFLAGS) -c $< -o $@
fat.o: fat.cpp fat.h
$(CC) $(CFLAGS) -c $< -o $@
$(KERNEL): $(OBJS) $(LDSCRIPT)
$(LD) -T $(LDSCRIPT) $(OBJS) -o $(KERNEL)
# Auto-embed user programs into C arrays
embedded_user_programs.c: $(USER_BINS)
@echo "Generating embedded_user_programs.c..."
@echo "#include <stdint.h>" > embedded_user_programs.c
@echo "#include \"embedded_user_programs.h\"" >> embedded_user_programs.c
@echo "" >> embedded_user_programs.c
@rm -f embedded_user_programs.tmp
@touch embedded_user_programs.tmp
@i=0; \
for f in $(USER_SOURCES); do \
name=$$(basename $$f .S); \
var=$$(echo $$name | sed 's/[^A-Za-z0-9_]/_/g'); \
binfile=$(PROGRAMS_DIR)/$$name.bin; \
\
echo " embedding: $$name"; \
echo "// Assembly source for $$name" >> embedded_user_programs.c; \
echo "const char source_$$var[] = " >> embedded_user_programs.c; \
sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$$/\\n"/' $$f >> embedded_user_programs.c; \
echo ";" >> embedded_user_programs.c; \
echo "" >> embedded_user_programs.c; \
\
echo "// Binary for $$name" >> embedded_user_programs.c; \
echo "const uint8_t binary_$$var[] = {" >> embedded_user_programs.c; \
xxd -i < $$binfile >> embedded_user_programs.c; \
echo "};" >> embedded_user_programs.c; \
echo "" >> embedded_user_programs.c; \
\
echo "{ \"$$name\", binary_$$var, sizeof(binary_$$var)," \
"source_$$var, sizeof(source_$$var) }," >> embedded_user_programs.tmp; \
i=$$((i+1)); \
done; \
echo "const EmbeddedFile embedded_files[] = {" >> embedded_user_programs.c; \
cat embedded_user_programs.tmp >> embedded_user_programs.c; \
echo "};" >> embedded_user_programs.c; \
echo "const unsigned int embedded_file_count = $$i;" >> embedded_user_programs.c; \
rm -f embedded_user_programs.tmp
embedded_user_programs.o: embedded_user_programs.c embedded_user_programs.h
$(CC) $(CFLAGS) -c embedded_user_programs.c -o embedded_user_programs.o
# Cleaning
clean:
rm -f $(OBJS) $(KERNEL) embedded_user_programs.c
rm -f $(PROGRAMS_DIR)/*.o $(PROGRAMS_DIR)/*.elf $(PROGRAMS_DIR)/*.bin
deep_clean: clean
rm -rf $(PROGRAMS_DIR)
# Run in QEMU
run: $(KERNEL)
qemu-system-riscv64 \
-machine virt \
-m 128M \
-nographic \
-bios none \
-kernel $(KERNEL) \
-serial mon:stdio \
# -d guest_errors,int,mmu,cpu