# ============================================================================== # 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 # [AUTOMATION] USER_DIRS = $(wildcard $(USERPROG_DIR)/*) USER_NAMES = $(notdir $(USER_DIRS)) USER_BINS = $(addprefix $(USER_OUT_DIR)/, $(USER_NAMES)) # Config & Tools 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 # Sources & Artifacts 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 force_look 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 dirs: @mkdir -p $(BUILD_DIR) $(USER_OUT_DIR) $(INIT_OUT_DIR) # @mkdir -p $(USER_OUT_DIR) # @mkdir -p $(INIT_OUT_DIR) clean: @echo " [CLEAN] Cleaning root build dir..." @rm -rf $(BUILD_DIR) @echo " [CLEAN] Cleaning user programs..." @# 각 유저 프로그램 폴더 들어가서 make clean 실행 @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 @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 $(HOME_IMG): | dirs @echo " [HOME] Checking Home Filesystem..." @if [ -f $(DISK_IMG) ]; then \ echo " -> Extracting HomeFS from disk.img (Preserving Data)..."; \ $(DD) if=$(DISK_IMG) of=$@ bs=512 skip=$(HOME_OFFSET) count=$(HOME_SECTORS); \ elif [ ! -f $@ ]; then \ echo " -> Creating new HomeFS (Format)..."; \ $(DD) if=/dev/zero of=$@ bs=1M count=$(HOME_SIZE_MB); \ mkfs.ext4 -q -O ^64bit,^metadata_csum $@; \ else \ echo " -> 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 # $(DISK_IMG): $(PART_IMG) $(CORE_IMG) # @echo " [ASM] Assembling disk..." # @$(DD) if=/dev/zero of=$@ bs=1M count=$(DISK_SIZE_MB) # @echo "2048,,83,*" | sfdisk $@ > /dev/null 2>&1 # @$(DD) if=$(PART_IMG) of=$@ bs=512 seek=$(SECTOR_OFF) conv=notrunc # @$(DD) if=$(GRUB_LIB)/boot.img of=$@ bs=446 count=1 conv=notrunc # @$(DD) if=$(CORE_IMG) of=$@ bs=512 seek=1 conv=notrunc