-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMakefile
More file actions
175 lines (140 loc) · 6.49 KB
/
Makefile
File metadata and controls
175 lines (140 loc) · 6.49 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
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
# Rix - Rust Intelligentia UniX - Build System
# Minimal x64 Operating System in Rust
# Use rustup's nightly toolchain
export PATH := /Users/pg/.rustup/toolchains/nightly-aarch64-apple-darwin/bin:$(PATH)
# Detect OS and set tools
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
AS = nasm
LD = /opt/homebrew/bin/ld.lld
OBJCOPY = /opt/homebrew/opt/llvm/bin/llvm-objcopy
else
AS = nasm
LD = ld.lld
OBJCOPY = objcopy
endif
# Rust configuration
CARGO = cargo
RUSTFLAGS = -C link-arg=-nostdlib -C code-model=kernel -C relocation-model=static
# Flags
ASFLAGS = -f elf64 -w-label-redef-late
KERNEL_LD = kernel/linker.ld
APP_LD = apps/app.ld
# Source files
STAGE1_SRC = boot/stage1.asm
STAGE2_SRC = boot/stage2.asm
KERNEL_ASM = kernel/entry.asm
# Output
STAGE1_BIN = build/stage1.bin
STAGE2_BIN = build/stage2.bin
KERNEL_ENTRY_OBJ = build/entry.o
KERNEL_LIB = target/x86_64-unknown-none/release/librix_kernel.a
KERNEL_ELF = build/kernel.elf
KERNEL_BIN = build/kernel.bin
# App outputs
APP_KCALC_LIB = target/x86_64-unknown-none/release/libkcalc.a
APP_HELLO_LIB = target/x86_64-unknown-none/release/libhello.a
APP_CRASH_LIB = target/x86_64-unknown-none/release/libcrash.a
APP_CALC_LIB = target/x86_64-unknown-none/release/libcalc.a
APP_SHELL_LIB = target/x86_64-unknown-none/release/libshell.a
APP_TICK_LIB = target/x86_64-unknown-none/release/libtick.a
APP_TOCK_LIB = target/x86_64-unknown-none/release/libtock.a
APP_KCALC_BIN = build/apps/kcalc.bin
APP_HELLO_BIN = build/apps/hello.bin
APP_CRASH_BIN = build/apps/crash.bin
APP_CALC_BIN = build/apps/calc.bin
APP_SHELL_BIN = build/apps/shell.bin
APP_TICK_BIN = build/apps/tick.bin
APP_TOCK_BIN = build/apps/tock.bin
APP_TABLE = build/apps.img
OS_IMAGE = build/rix.img
.PHONY: all clean run kernel apps
all: $(OS_IMAGE)
# Create build directory
build:
mkdir -p build
mkdir -p build/apps
# Stage 1 bootloader
$(STAGE1_BIN): $(STAGE1_SRC) | build
$(AS) -f bin $< -o $@
# Stage 2 bootloader
$(STAGE2_BIN): $(STAGE2_SRC) | build
$(AS) -f bin $< -o $@
# Kernel entry (assembly)
$(KERNEL_ENTRY_OBJ): $(KERNEL_ASM) | build
$(AS) $(ASFLAGS) $< -o $@
# Build Rust kernel
$(KERNEL_LIB): kernel/*.rs kernel/build.rs
cd kernel && $(CARGO) build --release --target ../x86_64-unknown-none.json -Z build-std=core,compiler_builtins -Z build-std-features=compiler-builtins-mem
# Link kernel
$(KERNEL_ELF): $(KERNEL_ENTRY_OBJ) $(KERNEL_LIB)
$(LD) -nostdlib -T $(KERNEL_LD) -o $@ $(KERNEL_ENTRY_OBJ) $(KERNEL_LIB)
# Convert to binary
$(KERNEL_BIN): $(KERNEL_ELF)
$(OBJCOPY) -O binary $< $@
# Build Rust apps
$(APP_KCALC_LIB): apps/kcalc/kcalc.rs
cd apps/kcalc && $(CARGO) build --release --target ../../x86_64-unknown-none.json -Z build-std=core,compiler_builtins -Z build-std-features=compiler-builtins-mem
$(APP_HELLO_LIB): apps/hello/hello.rs
cd apps/hello && $(CARGO) build --release --target ../../x86_64-unknown-none.json -Z build-std=core,compiler_builtins -Z build-std-features=compiler-builtins-mem
$(APP_CRASH_LIB): apps/crash/crash.rs
cd apps/crash && $(CARGO) build --release --target ../../x86_64-unknown-none.json -Z build-std=core,compiler_builtins -Z build-std-features=compiler-builtins-mem
$(APP_CALC_LIB): apps/calc/calc.rs apps/userlib.rs
cd apps/calc && $(CARGO) build --release --target ../../x86_64-unknown-none.json -Z build-std=core,compiler_builtins -Z build-std-features=compiler-builtins-mem
$(APP_SHELL_LIB): apps/shell/shell.rs apps/userlib.rs
cd apps/shell && $(CARGO) build --release --target ../../x86_64-unknown-none.json -Z build-std=core,compiler_builtins -Z build-std-features=compiler-builtins-mem
$(APP_TICK_LIB): apps/tick/tick.rs apps/userlib.rs
cd apps/tick && $(CARGO) build --release --target ../../x86_64-unknown-none.json -Z build-std=core,compiler_builtins -Z build-std-features=compiler-builtins-mem
$(APP_TOCK_LIB): apps/tock/tock.rs apps/userlib.rs
cd apps/tock && $(CARGO) build --release --target ../../x86_64-unknown-none.json -Z build-std=core,compiler_builtins -Z build-std-features=compiler-builtins-mem
# Link apps
# Kernel apps use kernel_app.ld (loaded at 0x400000)
$(APP_KCALC_BIN): $(APP_KCALC_LIB) | build
$(LD) -nostdlib -T apps/kernel_app.ld -o build/apps/kcalc.elf $(APP_KCALC_LIB)
$(OBJCOPY) -O binary build/apps/kcalc.elf $@
# User apps use app.ld (loaded at 0x800000)
$(APP_HELLO_BIN): $(APP_HELLO_LIB) | build
$(LD) -nostdlib -T $(APP_LD) -o build/apps/hello.elf $(APP_HELLO_LIB)
$(OBJCOPY) -O binary build/apps/hello.elf $@
$(APP_CRASH_BIN): $(APP_CRASH_LIB) | build
$(LD) -nostdlib -T $(APP_LD) -o build/apps/crash.elf $(APP_CRASH_LIB)
$(OBJCOPY) -O binary build/apps/crash.elf $@
$(APP_CALC_BIN): $(APP_CALC_LIB) | build
$(LD) -nostdlib -T $(APP_LD) -o build/apps/calc.elf $(APP_CALC_LIB)
$(OBJCOPY) -O binary build/apps/calc.elf $@
$(APP_SHELL_BIN): $(APP_SHELL_LIB) | build
$(LD) -nostdlib -T $(APP_LD) -o build/apps/shell.elf $(APP_SHELL_LIB)
$(OBJCOPY) -O binary build/apps/shell.elf $@
$(APP_TICK_BIN): $(APP_TICK_LIB) | build
$(LD) -nostdlib -T $(APP_LD) -o build/apps/tick.elf $(APP_TICK_LIB)
$(OBJCOPY) -O binary build/apps/tick.elf $@
$(APP_TOCK_BIN): $(APP_TOCK_LIB) | build
$(LD) -nostdlib -T $(APP_LD) -o build/apps/tock.elf $(APP_TOCK_LIB)
$(OBJCOPY) -O binary build/apps/tock.elf $@
# App table
$(APP_TABLE): $(APP_KCALC_BIN) $(APP_HELLO_BIN) $(APP_CRASH_BIN) $(APP_CALC_BIN) $(APP_SHELL_BIN) $(APP_TICK_BIN) $(APP_TOCK_BIN)
python3 build_apptable.py $@ $(APP_KCALC_BIN) --usermode $(APP_HELLO_BIN) --usermode $(APP_CRASH_BIN) --usermode $(APP_CALC_BIN) --usermode $(APP_SHELL_BIN) --usermode $(APP_TICK_BIN) --usermode $(APP_TOCK_BIN)
# Create bootable image
# Layout: sector 0 = stage1, sectors 1-4 = stage2, sectors 5-8196 = kernel (up to 4MB), sector 8197+ = app table (up to 16MB)
$(OS_IMAGE): $(STAGE1_BIN) $(STAGE2_BIN) $(KERNEL_BIN) $(APP_TABLE)
dd if=/dev/zero of=$@ bs=512 count=40965 2>/dev/null
dd if=$(STAGE1_BIN) of=$@ conv=notrunc 2>/dev/null
dd if=$(STAGE2_BIN) of=$@ bs=512 seek=1 conv=notrunc 2>/dev/null
dd if=$(KERNEL_BIN) of=$@ bs=512 seek=5 conv=notrunc 2>/dev/null
# App table at sector 8197 (after 4MB kernel space)
dd if=$(APP_TABLE) of=$@ bs=512 seek=8197 conv=notrunc 2>/dev/null
@echo "✓ Rix image created successfully!"
# Run in QEMU
run: $(OS_IMAGE)
qemu-system-x86_64 -drive format=raw,file=$(OS_IMAGE) -m 256M
# Clean
clean:
rm -rf build target
cd kernel && $(CARGO) clean
cd apps/kcalc && $(CARGO) clean
cd apps/hello && $(CARGO) clean
cd apps/crash && $(CARGO) clean
cd apps/calc && $(CARGO) clean
cd apps/shell && $(CARGO) clean
cd apps/tick && $(CARGO) clean
cd apps/tock && $(CARGO) clean