Makefile 2.1 KB

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