boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

Makefile (4809B)


      1 # seed-kernel — minimal OS that satisfies docs/OS.md Tier 1/2.
      2 
      3 ARCH     ?= aarch64
      4 ifeq ($(origin CC),default)
      5 CC       := clang
      6 endif
      7 ifeq ($(origin LD),default)
      8 LD       := ld.lld
      9 endif
     10 ifeq ($(origin OBJCOPY),default)
     11 OBJCOPY  := llvm-objcopy
     12 endif
     13 ifeq ($(strip $(OBJCOPY)),)
     14 OBJCOPY  := llvm-objcopy
     15 endif
     16 OUT      := build
     17 ARCHDIR  := arch/$(ARCH)
     18 KOBJS    := $(OUT)/kasm.o $(OUT)/kernel.o $(OUT)/mmu.o $(OUT)/mem.o
     19 KIMAGE   := $(OUT)/kernel.elf
     20 KBIN     := $(OUT)/Image
     21 USER     := $(OUT)/init
     22 USER_FORK := $(OUT)/forktest
     23 USER_CHILD := $(OUT)/child
     24 INITRAMFS := $(OUT)/initramfs.cpio
     25 INITRAMFS_FORK := $(OUT)/initramfs-fork.cpio
     26 # Block-device images for the seed kernel's virtio-blk transport.
     27 # in*.img: cpio newc archive padded to a 512-byte multiple (read-only).
     28 # out.img: pre-allocated 256 MiB sparse file the kernel writes SEEDFS into.
     29 IN_IMG := $(OUT)/in.img
     30 IN_IMG_FORK := $(OUT)/in-fork.img
     31 OUT_IMG_SIZE := 268435456
     32 
     33 CFLAGS_COMMON := -nostdlib -ffreestanding -fno-stack-protector \
     34                  -fno-pic -static -Wall -Wextra -O2 \
     35                  -fno-asynchronous-unwind-tables -fno-unwind-tables
     36 KCFLAGS  := $(CFLAGS_COMMON) -I$(ARCHDIR)
     37 
     38 ifeq ($(ARCH),aarch64)
     39 KCFLAGS  += -target aarch64-unknown-elf -mcmodel=large -mgeneral-regs-only
     40 USER_ARCH_CFLAGS := -target aarch64-unknown-elf -mcmodel=large -mgeneral-regs-only
     41 LDFLAGS_ARCH := -m aarch64elf
     42 EXTRA_ARCH_TARGETS :=
     43 else ifeq ($(ARCH),amd64)
     44 KCFLAGS  += -target x86_64-unknown-elf -mcmodel=large -mno-red-zone -mno-sse -mno-mmx
     45 USER_ARCH_CFLAGS := -target x86_64-unknown-elf -mcmodel=large -mno-red-zone -mno-sse -mno-mmx
     46 LDFLAGS_ARCH := -m elf_x86_64
     47 EXTRA_ARCH_TARGETS :=
     48 else ifeq ($(ARCH),riscv64)
     49 KCFLAGS  += -target riscv64-unknown-elf -march=rv64imac_zicsr_zifencei -mabi=lp64 -mcmodel=medany -mno-relax -msmall-data-limit=0
     50 USER_ARCH_CFLAGS := -target riscv64-unknown-elf -march=rv64imac_zicsr_zifencei -mabi=lp64 -mcmodel=medany -mno-relax -msmall-data-limit=0
     51 LDFLAGS_ARCH := -m elf64lriscv
     52 EXTRA_ARCH_TARGETS :=
     53 else
     54 $(error seed-kernel backend '$(ARCH)' is unknown; use ARCH=aarch64, amd64, or riscv64)
     55 endif
     56 
     57 .PHONY: all clean kernel user initramfs
     58 all: $(KBIN) $(EXTRA_ARCH_TARGETS) $(INITRAMFS) $(INITRAMFS_FORK) $(IN_IMG) $(IN_IMG_FORK)
     59 
     60 $(OUT):
     61 	mkdir -p $(OUT)
     62 
     63 $(OUT)/kasm.o: $(ARCHDIR)/kernel.S | $(OUT)
     64 	$(CC) $(KCFLAGS) -c -o $@ $<
     65 
     66 $(OUT)/kernel.o: kernel.c $(ARCHDIR)/arch.h | $(OUT)
     67 	$(CC) $(KCFLAGS) -c -o $@ $<
     68 
     69 $(OUT)/mmu.o: $(ARCHDIR)/mmu.c $(ARCHDIR)/arch.h | $(OUT)
     70 	$(CC) $(KCFLAGS) -c -o $@ $<
     71 
     72 # Shared mem helpers (memcpy/memset/memmove/memcmp). Lives in
     73 # tcc/cc/mem.c so the tcc-built and gcc-built kernels link the same
     74 # implementation; tcc lowers some struct copies to memmove() that gcc
     75 # inlines, so the kernel needs all three regardless of the compiler.
     76 $(OUT)/mem.o: ../tcc/cc/mem.c | $(OUT)
     77 	$(CC) $(KCFLAGS) -c -o $@ $<
     78 
     79 $(KIMAGE): $(KOBJS) $(ARCHDIR)/kernel.lds
     80 	$(LD) $(LDFLAGS_ARCH) -nostdlib -static -T $(ARCHDIR)/kernel.lds -o $@ $(KOBJS)
     81 
     82 # Strip ELF down to a flat binary that QEMU's -kernel can load.
     83 $(KBIN): $(KIMAGE)
     84 	$(OBJCOPY) -O binary $< $@
     85 
     86 $(OUT)/init.o: user/hello.c | $(OUT)
     87 	$(CC) $(CFLAGS_COMMON) $(USER_ARCH_CFLAGS) -c -o $@ $<
     88 
     89 $(OUT)/forktest.o: user/forktest.c | $(OUT)
     90 	$(CC) $(CFLAGS_COMMON) $(USER_ARCH_CFLAGS) -c -o $@ $<
     91 
     92 $(OUT)/child.o: user/child.c | $(OUT)
     93 	$(CC) $(CFLAGS_COMMON) $(USER_ARCH_CFLAGS) -c -o $@ $<
     94 
     95 $(USER): $(OUT)/init.o user/user.lds
     96 	$(LD) $(LDFLAGS_ARCH) -nostdlib -static -T user/user.lds -o $@ $(OUT)/init.o
     97 
     98 $(USER_FORK): $(OUT)/forktest.o user/user.lds
     99 	$(LD) $(LDFLAGS_ARCH) -nostdlib -static -T user/user.lds -o $@ $(OUT)/forktest.o
    100 
    101 $(USER_CHILD): $(OUT)/child.o user/user.lds
    102 	$(LD) $(LDFLAGS_ARCH) -nostdlib -static -T user/user.lds -o $@ $(OUT)/child.o
    103 
    104 $(INITRAMFS): $(USER)
    105 	cd $(OUT) && printf 'init\n' | cpio -o -H newc > initramfs.cpio
    106 
    107 # Tier 2 demo cpio: /init is the fork driver, /child the program it execs.
    108 $(INITRAMFS_FORK): $(USER_FORK) $(USER_CHILD)
    109 	rm -rf $(OUT)/fork-stage && mkdir -p $(OUT)/fork-stage
    110 	cp $(USER_FORK) $(OUT)/fork-stage/init
    111 	cp $(USER_CHILD) $(OUT)/fork-stage/child
    112 	cd $(OUT)/fork-stage && printf 'init\nchild\n' | cpio -o -H newc > ../initramfs-fork.cpio
    113 
    114 # Pad an arbitrary cpio archive up to the next 512-byte multiple so QEMU's
    115 # virtio-blk transport sees a whole-sector device.
    116 $(IN_IMG): $(INITRAMFS)
    117 	cp $(INITRAMFS) $@.tmp
    118 	sz=$$(wc -c < $@.tmp); \
    119 	pad=$$(( (512 - sz % 512) % 512 )); \
    120 	if [ $$pad -gt 0 ]; then \
    121 	    head -c $$pad /dev/zero >> $@.tmp; \
    122 	fi
    123 	mv $@.tmp $@
    124 
    125 $(IN_IMG_FORK): $(INITRAMFS_FORK)
    126 	cp $(INITRAMFS_FORK) $@.tmp
    127 	sz=$$(wc -c < $@.tmp); \
    128 	pad=$$(( (512 - sz % 512) % 512 )); \
    129 	if [ $$pad -gt 0 ]; then \
    130 	    head -c $$pad /dev/zero >> $@.tmp; \
    131 	fi
    132 	mv $@.tmp $@
    133 
    134 kernel: $(KBIN)
    135 user: $(USER)
    136 initramfs: $(INITRAMFS)
    137 
    138 clean:
    139 	rm -rf $(OUT)