136 lines
4.6 KiB
Plaintext
136 lines
4.6 KiB
Plaintext
configure do
|
|
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
|
|
|
|
build do
|
|
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 = 12
|
|
|
|
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(<<EOF)
|
|
set default="0"
|
|
set timeout=1
|
|
menuentry "HOS" {
|
|
insmod multiboot2
|
|
multiboot2 /hos.elf
|
|
}
|
|
EOF
|
|
end
|
|
@sources.each do |source|
|
|
FileUtils.cp(source, "#{tmpdir}/iso")
|
|
end
|
|
# Build bootable GRUB image.
|
|
system(*%W[grub-mkrescue -o #{@target} #{tmpdir}/iso], err: "#{@env.build_root}/grub-mkrescue.log")
|
|
end
|
|
@cache.register_build(@target, nil, @sources, @env)
|
|
end
|
|
true
|
|
end
|
|
end
|
|
|
|
class EfiImage < Builder
|
|
def run(options)
|
|
unless @cache.up_to_date?(@target, nil, @sources, @env)
|
|
print_run_message("Generating EFI boot image #{@target}", nil)
|
|
Dir.mktmpdir do |tmpdir|
|
|
# Build a standalone GRUB.
|
|
File.open("#{tmpdir}/grub.cfg", "wb") do |fh|
|
|
fh.write(<<EOF)
|
|
insmod part_gpt
|
|
configfile (hd0,gpt2)/grub.cfg
|
|
EOF
|
|
end
|
|
system(*%W[grub-mkstandalone -O x86_64-efi -o #{tmpdir}/BOOTX64.EFI boot/grub/grub.cfg=#{tmpdir}/grub.cfg])
|
|
# Create EFI partition.
|
|
system(*%W[dd if=/dev/zero of=#{tmpdir}/efi.part bs=1M count=#{EFI_PART_SIZE}], err: "/dev/null")
|
|
system(*%W[mformat -i #{tmpdir}/efi.part ::])
|
|
system(*%W[mmd -i #{tmpdir}/efi.part ::/EFI])
|
|
system(*%W[mmd -i #{tmpdir}/efi.part ::/EFI/BOOT])
|
|
system(*%W[mcopy -i #{tmpdir}/efi.part #{tmpdir}/BOOTX64.EFI ::/EFI/BOOT])
|
|
# Create ext2 HOS partition.
|
|
FileUtils.mkdir_p("#{tmpdir}/ext2")
|
|
@sources.each do |source|
|
|
FileUtils.cp(source, "#{tmpdir}/ext2")
|
|
end
|
|
File.open("#{tmpdir}/ext2/grub.cfg", "wb") do |fh|
|
|
fh.write(<<EOF)
|
|
set default="0"
|
|
set timeout=1
|
|
menuentry "HOS" {
|
|
insmod part_gpt
|
|
insmod multiboot2
|
|
set root=(hd0,gpt2)
|
|
multiboot2 /hos.elf
|
|
}
|
|
EOF
|
|
end
|
|
system(*%W[genext2fs -b #{HOS_PART_SIZE * 1024} -d #{tmpdir}/ext2 #{tmpdir}/ext2.part])
|
|
# Create full disk image.
|
|
system(*%W[dd if=/dev/zero of=#{@target} bs=1M count=#{EFI_PART_SIZE + HOS_PART_SIZE + 2}], err: "/dev/null")
|
|
system(*%W[parted -s #{@target} mklabel gpt])
|
|
system(*%W[parted -s #{@target} mkpart efi 1MiB #{EFI_PART_SIZE + 1}MiB])
|
|
system(*%W[parted -s #{@target} mkpart hos #{EFI_PART_SIZE + 1}MiB #{EFI_PART_SIZE + HOS_PART_SIZE + 1}MiB])
|
|
system(*%W[dd if=#{tmpdir}/efi.part of=#{@target} bs=1M seek=1 conv=notrunc], err: "/dev/null")
|
|
system(*%W[dd if=#{tmpdir}/ext2.part of=#{@target} bs=1M seek=#{1 + EFI_PART_SIZE} conv=notrunc], err: "/dev/null")
|
|
end
|
|
@cache.register_build(@target, nil, @sources, @env)
|
|
end
|
|
true
|
|
end
|
|
end
|
|
|
|
class FontGen < Builder
|
|
def run(options)
|
|
if @command
|
|
finalize_command
|
|
else
|
|
@sources += ["build/fontgen"]
|
|
command = %W[build/fontgen #{@sources.first} #{KFONT_SIZE} #{@target}]
|
|
standard_command("FontGen <target>#{@target}<reset>", command, {})
|
|
end
|
|
end
|
|
end
|
|
|
|
# FontGen Environment
|
|
Environment.new(use: "freetype") do |env|
|
|
env["CC"] = "gcc"
|
|
env.Program("build/fontgen", glob("fontgen/**/*.c"))
|
|
end
|
|
|
|
# Kernel Environment
|
|
Environment.new do |env|
|
|
env.add_builder(EfiImage)
|
|
env.add_builder(BiosImage)
|
|
env.add_builder(FontGen)
|
|
env["CCFLAGS"] += %w[-ffreestanding -Wall -O2]
|
|
env["LDFLAGS"] += %w[-ffreestanding -nostdlib -T src/link.ld]
|
|
env["LIBS"] += %w[gcc]
|
|
env["OBJDUMP"] = "i686-elf-objdump"
|
|
env.FontGen("^/kfont/kfont.c", "font/Hack-Regular.ttf")
|
|
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.EfiImage("build/hos-efi.img", %w[^/hos.elf])
|
|
env.BiosImage("build/hos.img", %w[^/hos.elf])
|
|
end
|
|
end
|