Update build system for 64-bit, EFI, and D

This commit is contained in:
Josh Holtrop 2022-03-13 22:46:59 -04:00
parent cb6bd3914c
commit 1fc2dd34e5
28 changed files with 48 additions and 138 deletions

2
.gitignore vendored
View File

@ -1,3 +1,3 @@
.rscons* .rscons*
/i686-elf-gcc/ /x86_64-elf-gcc/
/build/ /build/

View File

@ -1,98 +1,29 @@
path_prepend "i686-elf-gcc/bin" project_name "HOS"
path_prepend "x86_64-elf-gcc/bin"
configure do configure do
rscons "i686-elf-gcc.rb", "-b", "#{build_dir}/i686-elf-gcc" rscons "x86_64-elf-gcc.rb", "-b", "#{build_dir}/x86_64-elf-gcc"
check_c_compiler "i686-elf-gcc" check_program "ldc2"
check_program "genext2fs" check_program "x86_64-w64-mingw32-gcc"
check_program "grub-mkstandalone" check_program "x86_64-elf-gcc"
check_c_compiler
check_program "mformat", on_fail: "Install the mtools package" check_program "mformat", on_fail: "Install the mtools package"
check_program "xorriso"
check_cfg package: "freetype2", on_fail: "Install libfreetype-dev", use: "freetype" check_cfg package: "freetype2", on_fail: "Install libfreetype-dev", use: "freetype"
sh %w[git submodule update --init]
end end
require "tmpdir" # Kernel default font size.
# 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 KFONT_SIZE = 15
class BiosImage < Builder class Image < Builder
def run(options) def run(options)
unless @cache.up_to_date?(@target, nil, @sources, @env) unless @cache.up_to_date?(@target, nil, @sources, @env)
print_run_message("Generating BIOS boot image #{@target}", nil) print_run_message("Creating disk image <target>#{@target}<reset>", nil)
Dir.mktmpdir do |tmpdir| File.binwrite(@target, "\0" * (1440 * 1024))
# Create iso directory. system(*%W[mformat -i #{@target} -f 1440 ::])
FileUtils.mkdir_p("#{tmpdir}/iso/boot/grub") system(*%W[mmd -i #{@target} ::/EFI])
File.open("#{tmpdir}/iso/boot/grub/grub.cfg", "wb") do |fh| system(*%W[mmd -i #{@target} ::/EFI/BOOT])
fh.write(<<EOF) system(*%W[mcopy -i #{@target} #{@sources.first} ::/EFI/BOOT])
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) @cache.register_build(@target, nil, @sources, @env)
end end
true true
@ -112,55 +43,33 @@ class FontGen < Builder
end 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>#{@target}<reset>", command, stdout: @target)
end
end
end
# FontGen Environment # FontGen Environment
fontgen_env = env "fontgen", use: "freetype" do |env| fontgen_env = env "fontgen", use: "freetype" do |env|
env["CC"] = "gcc" env.Program("^/fontgen", glob("src/fontgen/**/*.c"))
env.Program("^/fontgen.bin", glob("fontgen/**/*.c"))
end end
# Kernel Environment ## Kernel Environment
kernel_env = env "kernel" do |env| #kernel_env = env "kernel" do |env|
env.add_builder(EfiImage) # env.add_builder(Image)
env.add_builder(BiosImage) # env.add_builder(FontGen)
env.add_builder(FontGen) # env["OBJDUMP"] = "x86_64-elf-objdump"
env.add_builder(Size) # env["SIZE"] = "x86_64-elf-size"
env["OBJDUMP"] = "i686-elf-objdump" # env["CCFLAGS"] += %w[-ffreestanding -Wall -O2]
env["SIZE"] = "i686-elf-size" # env["LDFLAGS"] += %w[-ffreestanding -nostdlib -T src/link.ld]
env["CCFLAGS"] += %w[-ffreestanding -Wall -O2] # env["LDFLAGS"] += %W[-Wl,-Map,${_TARGET}.map]
env["LDFLAGS"] += %w[-ffreestanding -nostdlib -T src/link.ld] # env["LIBS"] += %w[gcc]
env["LDFLAGS"] += %W[-Wl,-Map,${_TARGET}.map] # env.FontGen("^/kfont/kfont.c", "font/Hack-Regular.ttf",
env["LIBS"] += %w[gcc] # "fontgen" => fontgen_env.expand("^/fontgen"))
env.FontGen("^/kfont/kfont.c", "font/Hack-Regular.ttf", # env.barrier
"fontgen" => fontgen_env.expand("^/fontgen.bin")) # env["CPPPATH"] += ["#{env.build_root}/kfont"]
env.barrier # env.Program("^/hos.elf", glob("src/**/*.{S,c}") + ["^/kfont/kfont.c"])
env["CPPPATH"] += ["#{env.build_root}/kfont"] # env.depends("#{env.build_root}/hos.elf", "src/link.ld")
env.Program("^/hos.elf", glob("src/**/*.{S,c}") + ["^/kfont/kfont.c"]) # env.Disassemble("^/hos.elf.txt", "^/hos.elf")
env.depends("#{env.build_root}/hos.elf", "src/link.ld") # env.Size("^/hos.elf.size", "^/hos.elf")
env.Disassemble("^/hos.elf.txt", "^/hos.elf") # env.Image("^/hos.img", %w[^/hos.elf])
env.Size("^/hos.elf.size", "^/hos.elf") #end
env.EfiImage("^/hos-efi.img", %w[^/hos.elf])
env.BiosImage("^/hos.img", %w[^/hos.elf])
end
task "run", desc: "Run HOS in QEMU" do task "run", desc: "Run HOS in QEMU" do
img = kernel_env.expand("^/hos.img") 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}] sh %W[qemu-system-x86_64 -bios OVMF.fd -hda #{img}]
end end

4
rscons

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,10 @@
project_name "x86_64-elf-gcc"
binutils_version = "2.35" binutils_version = "2.35"
binutils_checksum = "1b11659fb49e20e18db460d44485f09442c8c56d5df165de9461eb09c8302f85" binutils_checksum = "1b11659fb49e20e18db460d44485f09442c8c56d5df165de9461eb09c8302f85"
gcc_version = "10.2.0" gcc_version = "10.2.0"
gcc_checksum = "b8dd4368bb9c7f0b98188317ee0254dd8cc99d1e3a18d0ff146c855fe16c1d8c" gcc_checksum = "b8dd4368bb9c7f0b98188317ee0254dd8cc99d1e3a18d0ff146c855fe16c1d8c"
install_path = File.expand_path("i686-elf-gcc") install_path = File.expand_path("x86_64-elf-gcc")
target = "i686-elf" target = "x86_64-elf"
path_prepend "#{install_path}/bin" path_prepend "#{install_path}/bin"
configure do configure do
@ -53,7 +54,7 @@ default do
cd "#{build_dir}/build-gcc" do cd "#{build_dir}/build-gcc" do
sh %W[../gcc-#{gcc_version}/configure sh %W[../gcc-#{gcc_version}/configure
--target=#{target} --prefix=#{install_path} --disable-nls --target=#{target} --prefix=#{install_path} --disable-nls
--enable-languages=c,c++ --without-headers] --enable-languages=c --without-headers]
sh "make all-gcc" sh "make all-gcc"
sh "make all-target-libgcc" sh "make all-target-libgcc"
sh "make install-gcc" sh "make install-gcc"