path_prepend "i686-elf-gcc/bin" configure do rscons "i686-elf-gcc.rb", "-b", "#{build_dir}/i686-elf-gcc" check_c_compiler "i686-elf-gcc" check_program "genext2fs" check_program "grub-mkstandalone" check_program "mformat", on_fail: "Install the mtools package" check_program "xorriso" check_cfg package: "freetype2", on_fail: "Install libfreetype-dev", use: "freetype" end require "tmpdir" # EFI (w/ GRUB) partition size (MiB) EFI_PART_SIZE = 8 # HOS partition size (MiB) HOS_PART_SIZE = 4 # Kernel default font size KFONT_SIZE = 15 class BiosImage < Builder def run(options) unless @cache.up_to_date?(@target, nil, @sources, @env) print_run_message("Generating BIOS boot image #{@target}", nil) Dir.mktmpdir do |tmpdir| # Create iso directory. FileUtils.mkdir_p("#{tmpdir}/iso/boot/grub") File.open("#{tmpdir}/iso/boot/grub/grub.cfg", "wb") do |fh| fh.write(<#{@target}", command, {}) end end end class Size < Builder def run(options) if @command finalize_command else @vars["_SOURCES"] = @sources @vars["_TARGET"] = @target command = @env.build_command(%w[${SIZE} ${_SOURCES}], @vars) standard_command("Size #{@target}", command, stdout: @target) end end end # FontGen Environment fontgen_env = env "fontgen", use: "freetype" do |env| env["CC"] = "gcc" env.Program("^/fontgen.bin", glob("fontgen/**/*.c")) end # Kernel Environment kernel_env = env "kernel" do |env| env.add_builder(EfiImage) env.add_builder(BiosImage) env.add_builder(FontGen) env.add_builder(Size) env["OBJDUMP"] = "i686-elf-objdump" env["SIZE"] = "i686-elf-size" env["CCFLAGS"] += %w[-ffreestanding -Wall -O2] env["LDFLAGS"] += %w[-ffreestanding -nostdlib -T src/link.ld] env["LDFLAGS"] += %W[-Wl,-Map,${_TARGET}.map] env["LIBS"] += %w[gcc] env.FontGen("^/kfont/kfont.c", "font/Hack-Regular.ttf", "fontgen" => fontgen_env.expand("^/fontgen.bin")) env.barrier env["CPPPATH"] += ["#{env.build_root}/kfont"] env.Program("^/hos.elf", glob("src/**/*.{S,c}") + ["^/kfont/kfont.c"]) env.depends("#{env.build_root}/hos.elf", "src/link.ld") env.Disassemble("^/hos.elf.txt", "^/hos.elf") env.Size("^/hos.elf.size", "^/hos.elf") env.EfiImage("^/hos-efi.img", %w[^/hos.elf]) env.BiosImage("^/hos.img", %w[^/hos.elf]) end task "run", desc: "Run HOS in QEMU" do img = kernel_env.expand("^/hos.img") sh %W[qemu-system-x86_64 -hda #{img}] end task "run-efi", desc: "Run HOS EFI in QEMU" do img = kernel_env.expand("^/hos-efi.img") sh %W[qemu-system-x86_64 -bios OVMF.fd -hda #{img}] end