require "tmpdir" project_name "HOS" path_prepend "x86_64-elf-gcc/bin" configure do rscons "x86_64-elf-gcc.rb", "-b", "#{build_dir}/x86_64-elf-gcc" check_d_compiler "ldc2", use: "ldc2" check_c_compiler "x86_64-w64-mingw32-gcc", use: "x86_64-w64-mingw32-gcc" check_c_compiler "x86_64-elf-gcc", use: "x86_64-elf-gcc" check_c_compiler check_program "mformat", on_fail: "Install the mtools package" check_cfg package: "freetype2", on_fail: "Install libfreetype-dev", use: "freetype" sh %w[git submodule update --init] end # Kernel default font size. KFONT_SIZE = 15 class Image < Builder def run(options) unless @cache.up_to_date?(@target, nil, @sources, @env) print_run_message("Creating disk image #{@target}", nil) File.binwrite(@target, "\0" * (1440 * 1024)) system(*%W[mformat -i #{@target} -f 1440 ::]) system(*%W[mmd -i #{@target} ::/EFI]) system(*%W[mmd -i #{@target} ::/EFI/BOOT]) system(*%W[mcopy -i #{@target} #{@sources.first} ::/EFI/BOOT]) @cache.register_build(@target, nil, @sources, @env) end true end end class FontGen < Builder def run(options) if @command finalize_command else fontgen = @vars["fontgen"] @sources += [fontgen] command = %W[#{fontgen} #{@sources.first} #{KFONT_SIZE} #{@target}] standard_command("FontGen #{@target}", command, {}) end end end fontgen_env = env "fontgen", use: "freetype" do |env| env.Program("^/fontgen", glob("src/fontgen/**/*.c")) end hulk_env = env "hulk", use: %w[ldc2 x86_64-elf-gcc] do |env| env["sources"] = glob("src/hulk/**/*.d") env["DFLAGS"] += %w[-mtriple=x86_64-unknown-elf --betterC -release -O3 --wi --enable-cross-module-inlining] env["D_IMPORT_PATH"] += %w[src/hulk src/common] env["LD"] = "x86_64-elf-gcc" env["LDFLAGS"] += %w[-nostdlib -Tsrc/hulk/hulk.ld -Wl,-Map,${_TARGET}.map] env["LDCMD"] = %w[${LD} -o ${_TARGET} ${LDFLAGS} ${_SOURCES} ${LIBDIRPREFIX}${LIBPATH} ${LIBLINKPREFIX}${LIBS}] env["OBJDUMP"] = "x86_64-elf-objdump" env["OBJCOPY"] = "x86_64-elf-objcopy" env.Program("^/hulk.elf", "${sources}") env.depends("^/hulk.elf", "src/hulk/hulk.ld") env.Disassemble("^/hulk.txt", "^/hulk.elf") env.Command("^/hulk.bin", "^/hulk.elf", "CMD" => %W[${OBJCOPY} -O binary ${_SOURCES} ${_TARGET}], "CMD_DESC" => "Convert ELF to binary:") end hello_env = env "hello", use: %w[ldc2 x86_64-w64-mingw32-gcc] do |env| env.add_builder(Image) env["sources"] = glob("src/hello/**/*.d") env["sources"] += glob("uefi-d/source/**/*.d") env["DFLAGS"] += %w[-mtriple=x86_64-unknown-windows-coff --betterC -release -O3 --wi --enable-cross-module-inlining] env["D_IMPORT_PATH"] += %w[src/hello src/hulk uefi-d/source src/common] env["LD"] = "x86_64-w64-mingw32-gcc" env["LDFLAGS"] += %w[-nostdlib -Wl,-dll -shared -Wl,--subsystem,10 -e efi_main -Wl,-Map,${_TARGET}.map] env["LDCMD"] = %w[${LD} -o ${_TARGET} ${LDFLAGS} ${_SOURCES} ${LIBDIRPREFIX}${LIBPATH} ${LIBLINKPREFIX}${LIBS}] env["OBJDUMP"] = "x86_64-w64-mingw32-objdump" env.Program("^/BOOTX64.EFI", "${sources}") env.Disassemble("^/BOOTX64.txt", "^/BOOTX64.EFI") env.Image("^/hos.img", "^/BOOTX64.EFI") end task "run", desc: "Run HOS in QEMU" do Dir.mktmpdir do |tmpdir| img = hello_env.expand("^/hos.img") FileUtils.cp(img, tmpdir) sh %W[qemu-system-x86_64 -bios OVMF.fd -drive file=#{tmpdir}/hos.img,format=raw] end end