Makefile 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. .POSIX:
  2. COMMON ?= common.h
  3. DOC_OUT = README.html
  4. ELF_EXT = .elf
  5. LD ?= ld
  6. LINKER_SCRIPT ?= linker.ld
  7. # Use gcc so that the preprocessor will run first.
  8. GAS ?= gcc
  9. GAS_EXT ?= .S
  10. NASM_EXT ?= .asm
  11. OBJ_EXT ?= .o
  12. OUT_EXT ?= .img
  13. QEMU ?= qemu-system-i386 -drive 'file=$(RUN_FILE),format=raw' -serial mon:stdio -smp 2
  14. RUN ?= bios_hello_world
  15. RUN_ARGS ?= -soundhw pcspk
  16. TMP_EXT ?= .tmp
  17. OUTS := $(sort $(foreach IN_EXT,$(NASM_EXT) $(GAS_EXT),$(patsubst %$(IN_EXT),%$(OUT_EXT),$(wildcard *$(IN_EXT)))))
  18. RUN_FILE := $(RUN)$(OUT_EXT)
  19. .PRECIOUS: %$(OBJ_EXT)
  20. .PHONY: all clean doc run
  21. all: $(OUTS)
  22. %$(OUT_EXT): %$(OBJ_EXT) $(LINKER_SCRIPT)
  23. $(LD) -melf_i386 -nostdlib -o '$(@:$(OUT_EXT)=$(ELF_EXT))' -T '$(LINKER_SCRIPT)' '$<'
  24. objcopy -O binary '$(@:$(OUT_EXT)=.elf)' '$@'
  25. %$(OBJ_EXT): %$(GAS_EXT) $(COMMON)
  26. $(GAS) -m32 -c -ggdb3 -o '$@' '$<'
  27. %$(OUT_EXT): %$(NASM_EXT)
  28. nasm -f bin -o '$@' '$<'
  29. # So that directories without a common.h can reuse this.
  30. $(COMMON):
  31. clean:
  32. rm -fr '$(DOC_OUT)' *$(ELF_EXT) *$(OBJ_EXT) *$(OUT_EXT) *$(TMP_EXT)
  33. run: $(RUN_FILE)
  34. $(QEMU) $(RUN_ARGS)
  35. debug: $(RUN_FILE)
  36. $(QEMU) -S -s &
  37. gdb -quiet -x gdb.gdb '$(<:$(OUT_EXT)=$(ELF_EXT))'
  38. bochs: $(RUN_FILE)
  39. # Supposes size is already multiples of 512.
  40. # We force that with our linker script,
  41. # and `grub-mkrescue` also seems to respect it as well.
  42. CYLINDERS="$$(($$(stat -c '%s' '$(RUN_FILE)') / 512))" && \
  43. bochs -qf /dev/null \
  44. 'ata0-master: type=disk, path="$(RUN_FILE)", mode=flat, cylinders='"$$CYLINDERS"', heads=1, spt=1' \
  45. 'com1: enabled=1, mode=file, dev=$(RUN).tmp.serial' \
  46. 'boot: disk' \
  47. 'display_library: sdl2' \
  48. 'megs: 128'
  49. BIG_IMG_DIR := big_img$(TMP_EXT)
  50. BOOT_DIR := $(BIG_IMG_DIR)/boot
  51. GRUB_DIR := $(BOOT_DIR)/grub
  52. big$(OUT_EXT): all
  53. rm -rf '$(BIG_IMG_DIR)'
  54. mkdir -p '$(GRUB_DIR)'
  55. for out in $(OUTS); do\
  56. printf "menuentry \"$${out%.*}\" {\n chainloader /boot/$$out\n}\n" >> '$(GRUB_DIR)/grub.cfg';\
  57. cp "$$out" '$(BOOT_DIR)';\
  58. done
  59. # TODO why does this fail to boot properly?
  60. #make -C multiboot/hello-world
  61. #mkdir -p '$(BOOT_DIR)/multiboot'
  62. #printf "menuentry \"multiboot/hello-world\" {\n chainloader /boot/multiboot/hello-world.img\n}\n" >> '$(GRUB_DIR)/grub.cfg';\
  63. #cp multiboot/hello-world/main.img '$(BOOT_DIR)/multiboot/hello-world.img'
  64. grub-mkrescue -o '$@' '$(BIG_IMG_DIR)'
  65. doc: $(DOC_OUT)
  66. $(DOC_OUT): README.adoc
  67. asciidoctor -o $@ -v $<