161 lines
5.3 KiB
Makefile
161 lines
5.3 KiB
Makefile
# ==============================================================================
|
|
# 1. Variables
|
|
# ==============================================================================
|
|
KERNEL_DIR = linux
|
|
INIT_DIR = init
|
|
USERPROG_DIR = userprog
|
|
GRUB_DIR = grub
|
|
BUILD_DIR = build
|
|
|
|
USER_OUT_DIR = $(BUILD_DIR)/userprog
|
|
INIT_OUT_DIR = $(BUILD_DIR)/init
|
|
|
|
USER_DIRS = $(wildcard $(USERPROG_DIR)/*)
|
|
USER_NAMES = $(notdir $(USER_DIRS))
|
|
USER_BINS = $(addprefix $(USER_OUT_DIR)/, $(USER_NAMES))
|
|
|
|
DISK_SIZE_MB = 512
|
|
|
|
ROOT_SIZE_MB = 256
|
|
ROOT_SECTORS = $$(($(ROOT_SIZE_MB) * 2048))
|
|
ROOT_OFFSET = 2048
|
|
|
|
HOME_SIZE_MB = 128
|
|
HOME_SECTORS = $$(($(HOME_SIZE_MB) * 2048))
|
|
HOME_OFFSET = $$(($(ROOT_OFFSET) + $(ROOT_SECTORS)))
|
|
|
|
GRUB_LIB = /usr/lib/grub/i386-pc
|
|
DD = dd status=none
|
|
DEBUGFS = debugfs
|
|
|
|
# --
|
|
KERNEL_SRC_BIN = $(KERNEL_DIR)/arch/x86/boot/bzImage
|
|
INIT_SRC = $(INIT_DIR)/init.c
|
|
GRUB_CFG_SRC = $(GRUB_DIR)/grub.cfg
|
|
# --
|
|
|
|
INIT_BIN = $(INIT_OUT_DIR)/init
|
|
|
|
DISK_IMG = $(BUILD_DIR)/disk.img
|
|
ROOT_IMG = $(BUILD_DIR)/rootfs.img
|
|
HOME_IMG = $(BUILD_DIR)/homefs.img
|
|
CORE_IMG = $(BUILD_DIR)/core.img
|
|
|
|
# ==============================================================================
|
|
# 2. Main Targets
|
|
# ==============================================================================
|
|
.PHONY: all clean run dirs help
|
|
|
|
all: dirs $(DISK_IMG)
|
|
@echo " [DONE] Image ready: $(DISK_IMG)"
|
|
|
|
run: $(DISK_IMG)
|
|
qemu-system-x86_64 -drive file=$(DISK_IMG),format=raw -nographic \
|
|
-net nic,model=e1000 -net user
|
|
@echo " [SYNC] Saving session data to homefs.img..."
|
|
@$(DD) if=$(DISK_IMG) of=$(HOME_IMG) bs=512 skip=$(HOME_OFFSET) count=$(HOME_SECTORS) status=none
|
|
@echo " -> Data saved successfully."
|
|
|
|
dirs:
|
|
@mkdir -p $(BUILD_DIR) $(USER_OUT_DIR) $(INIT_OUT_DIR)
|
|
|
|
clean:
|
|
@echo " [CLEAN] Cleaning root build dir..."
|
|
# @rm -rf $(BUILD_DIR)
|
|
@if [ -d $(BUILD_DIR) ]; then \
|
|
find $(BUILD_DIR) -type f ! -name "homefs.img" -delete; \
|
|
fi
|
|
|
|
@echo " [CLEAN] Cleaning user programs..."
|
|
@for dir in $(USER_DIRS); do \
|
|
if [ -f $$dir/Makefile ]; then $(MAKE) -C $$dir clean; fi; \
|
|
done
|
|
|
|
clean-kernel:
|
|
@$(MAKE) -C $(KERNEL_DIR) clean
|
|
|
|
# ==============================================================================
|
|
# 3. Build Rules
|
|
# ==============================================================================
|
|
|
|
$(INIT_BIN): $(INIT_SRC) | dirs
|
|
@echo " [CC] Compiling init..."
|
|
@gcc -static -o $@ $<
|
|
|
|
$(USER_BINS): $(USER_OUT_DIR)/%: force_look | dirs
|
|
@echo " [MAKE] Entering directory: $(USERPROG_DIR)/$*"
|
|
@$(MAKE) -s -C $(USERPROG_DIR)/$* OUT_BIN=$(abspath $@) --no-print-directory
|
|
|
|
force_look:
|
|
@true
|
|
|
|
$(KERNEL_SRC_BIN):
|
|
@echo " [MAKE] Checking Kernel..."
|
|
@$(MAKE) -C $(KERNEL_DIR) -j$$(nproc) bzImage
|
|
|
|
$(CORE_IMG): | dirs
|
|
@grub-mkimage -O i386-pc -o $@ -p "(hd0,msdos1)/boot/grub" biosdisk part_msdos ext2 linux configfile normal boot
|
|
|
|
$(ROOT_IMG): $(INIT_BIN) $(USER_BINS) $(KERNEL_SRC_BIN) $(GRUB_CFG_SRC) | dirs
|
|
@echo " [ROOT] Generating Root Filesystem..."
|
|
|
|
@$(DD) if=/dev/zero of=$@ bs=1M count=$(ROOT_SIZE_MB)
|
|
@mkfs.ext4 -q -O ^64bit,^metadata_csum $@
|
|
|
|
@echo " -> Creating Directory Structure..."
|
|
@$(DEBUGFS) -w -R "mkdir /boot" $@ > /dev/null 2>&1
|
|
@$(DEBUGFS) -w -R "mkdir /boot/grub" $@ > /dev/null 2>&1
|
|
@$(DEBUGFS) -w -R "mkdir /bin" $@ > /dev/null 2>&1
|
|
@$(DEBUGFS) -w -R "mkdir /dev" $@ > /dev/null 2>&1
|
|
@$(DEBUGFS) -w -R "mkdir /proc" $@ > /dev/null 2>&1
|
|
@$(DEBUGFS) -w -R "mkdir /sys" $@ > /dev/null 2>&1
|
|
@$(DEBUGFS) -w -R "mkdir /tmp" $@ > /dev/null 2>&1
|
|
@$(DEBUGFS) -w -R "mkdir /home" $@ > /dev/null 2>&1
|
|
@$(DEBUGFS) -w -R "mkdir /ext" $@ > /dev/null 2>&1
|
|
|
|
@echo " -> Injecting System Binaries..."
|
|
@$(DEBUGFS) -w -R "write $(INIT_BIN) /init" $@ > /dev/null 2>&1
|
|
@$(DEBUGFS) -w -R "write $(KERNEL_SRC_BIN) /boot/bzImage" $@ > /dev/null 2>&1
|
|
@$(DEBUGFS) -w -R "write $(GRUB_CFG_SRC) /boot/grub/grub.cfg" $@ > /dev/null 2>&1
|
|
|
|
@for prog in $(USER_NAMES); do \
|
|
$(DEBUGFS) -w -R "write $(USER_OUT_DIR)/$$prog /bin/$$prog" $@ > /dev/null 2>&1; \
|
|
done
|
|
|
|
@if [ -d ext ]; then \
|
|
echo " -> Injecting external files from ./ext..."; \
|
|
for file in ext/*; do \
|
|
if [ -f "$$file" ]; then \
|
|
fname=$$(basename "$$file"); \
|
|
$(DEBUGFS) -w -R "write $$file /ext/$$fname" $@ > /dev/null 2>&1; \
|
|
fi; \
|
|
done; \
|
|
fi
|
|
|
|
$(HOME_IMG): | dirs
|
|
@if [ ! -f $@ ]; then \
|
|
echo " [HOME] Creating NEW Home Filesystem..."; \
|
|
$(DD) if=/dev/zero of=$@ bs=1M count=$(HOME_SIZE_MB) status=none; \
|
|
mkfs.ext4 -q -O ^64bit,^metadata_csum $@; \
|
|
else \
|
|
echo " [HOME] Using existing homefs.img."; \
|
|
fi
|
|
|
|
$(DISK_IMG): $(ROOT_IMG) $(HOME_IMG) $(CORE_IMG)
|
|
@echo " [ASM] Assembling disk with partitions..."
|
|
@$(DD) if=/dev/zero of=$@ bs=1M count=$(DISK_SIZE_MB)
|
|
|
|
@echo "start=$(ROOT_OFFSET), size=$(ROOT_SECTORS), type=83, bootable" > partition.script
|
|
@echo "start=$(HOME_OFFSET), size=$(HOME_SECTORS), type=83" >> partition.script
|
|
@sfdisk $@ < partition.script > /dev/null 2>&1
|
|
@rm partition.script
|
|
|
|
@echo " -> Writing RootFS (p1)..."
|
|
@$(DD) if=$(ROOT_IMG) of=$@ bs=512 seek=$(ROOT_OFFSET) conv=notrunc
|
|
|
|
@echo " -> Writing HomeFS (p2)..."
|
|
@$(DD) if=$(HOME_IMG) of=$@ bs=512 seek=$(HOME_OFFSET) conv=notrunc
|
|
|
|
@echo " -> Installing GRUB..."
|
|
@$(DD) if=$(GRUB_LIB)/boot.img of=$@ bs=446 count=1 conv=notrunc
|
|
@$(DD) if=$(CORE_IMG) of=$@ bs=512 seek=1 conv=notrunc
|