Compare commits
25
Commits
master
...
cd6983e2cd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd6983e2cd | ||
|
|
8df1646c61 | ||
|
|
3e25ab6ae4 | ||
|
|
05cc2da2e3 | ||
|
|
a54536660b | ||
|
|
9e3d9b18ea | ||
|
|
ef01239468 | ||
|
|
372b7265f1 | ||
|
|
1bc8722098 | ||
|
|
cd2f3f9a84 | ||
|
|
08a35e40d4 | ||
|
|
a855702214 | ||
|
|
706f2c1c5d | ||
|
|
704fd15f7b | ||
|
|
f054bab5cc | ||
|
|
3fa8e4a24b | ||
|
|
a38f95a7b8 | ||
|
|
dd57a31d38 | ||
|
|
406f17c1db | ||
|
|
0be1b113aa | ||
|
|
d782b59768 | ||
|
|
c3a6139f83 | ||
|
|
3d3a433800 | ||
|
|
54451bcf5b | ||
|
|
1fc2dd34e5 |
No files matched your search
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
.rscons*
|
.rscons*
|
||||||
/i686-elf-gcc/
|
/x86_64-elf-gcc/
|
||||||
/build/
|
/build/
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "uefi-d"]
|
||||||
|
path = uefi-d
|
||||||
|
url = git://github.com/kubasz/uefi-d
|
||||||
+57
-133
@@ -1,98 +1,31 @@
|
|||||||
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"
|
require "tmpdir"
|
||||||
|
|
||||||
# EFI (w/ GRUB) partition size (MiB)
|
project_name "HOS"
|
||||||
EFI_PART_SIZE = 8
|
path_prepend "x86_64-elf-gcc/bin"
|
||||||
# HOS partition size (MiB)
|
|
||||||
HOS_PART_SIZE = 4
|
|
||||||
# Kernel default font size
|
|
||||||
KFONT_SIZE = 15
|
|
||||||
|
|
||||||
class BiosImage < Builder
|
configure do
|
||||||
def run(options)
|
rscons "x86_64-elf-gcc.rb", "-b", "#{build_dir}/x86_64-elf-gcc"
|
||||||
unless @cache.up_to_date?(@target, nil, @sources, @env)
|
check_d_compiler "ldc2", use: "ldc2"
|
||||||
print_run_message("Generating BIOS boot image #{@target}", nil)
|
check_c_compiler "x86_64-w64-mingw32-gcc", use: "x86_64-w64-mingw32-gcc"
|
||||||
Dir.mktmpdir do |tmpdir|
|
check_c_compiler "x86_64-elf-gcc", use: "x86_64-elf-gcc"
|
||||||
# Create iso directory.
|
check_c_compiler
|
||||||
FileUtils.mkdir_p("#{tmpdir}/iso/boot/grub")
|
check_program "mformat", on_fail: "Install the mtools package"
|
||||||
File.open("#{tmpdir}/iso/boot/grub/grub.cfg", "wb") do |fh|
|
check_cfg package: "freetype2", on_fail: "Install libfreetype-dev", use: "freetype"
|
||||||
fh.write(<<EOF)
|
sh %w[git submodule update --init]
|
||||||
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
|
end
|
||||||
|
|
||||||
class EfiImage < Builder
|
# Kernel default font size.
|
||||||
|
KFONT_SIZE = 15
|
||||||
|
|
||||||
|
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 EFI boot image #{@target}", nil)
|
print_run_message("Creating disk image <target>#{@target}<reset>", nil)
|
||||||
Dir.mktmpdir do |tmpdir|
|
File.binwrite(@target, "\0" * (1440 * 1024))
|
||||||
# Build a standalone GRUB.
|
system(*%W[mformat -i #{@target} -f 1440 ::])
|
||||||
File.open("#{tmpdir}/grub.cfg", "wb") do |fh|
|
system(*%W[mmd -i #{@target} ::/EFI])
|
||||||
fh.write(<<EOF)
|
system(*%W[mmd -i #{@target} ::/EFI/BOOT])
|
||||||
insmod part_gpt
|
system(*%W[mcopy -i #{@target} #{@sources.first} ::/EFI/BOOT])
|
||||||
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 +45,46 @@ 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_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
|
hello_env = env "hello", use: %w[ldc2 x86_64-w64-mingw32-gcc] do |env|
|
||||||
kernel_env = env "kernel" do |env|
|
env.add_builder(Image)
|
||||||
env.add_builder(EfiImage)
|
env["sources"] = glob("src/hello/**/*.d")
|
||||||
env.add_builder(BiosImage)
|
env["sources"] += glob("uefi-d/source/**/*.d")
|
||||||
env.add_builder(FontGen)
|
env["DFLAGS"] += %w[-mtriple=x86_64-unknown-windows-coff --betterC -release -O3 --wi --enable-cross-module-inlining]
|
||||||
env.add_builder(Size)
|
env["D_IMPORT_PATH"] += %w[src/hello src/hulk uefi-d/source src/common]
|
||||||
env["OBJDUMP"] = "i686-elf-objdump"
|
env["LD"] = "x86_64-w64-mingw32-gcc"
|
||||||
env["SIZE"] = "i686-elf-size"
|
env["LDFLAGS"] += %w[-nostdlib -Wl,-dll -shared -Wl,--subsystem,10 -e efi_main -Wl,-Map,${_TARGET}.map]
|
||||||
env["CCFLAGS"] += %w[-ffreestanding -Wall -O2]
|
env["LDCMD"] = %w[${LD} -o ${_TARGET} ${LDFLAGS} ${_SOURCES} ${LIBDIRPREFIX}${LIBPATH} ${LIBLINKPREFIX}${LIBS}]
|
||||||
env["LDFLAGS"] += %w[-ffreestanding -nostdlib -T src/link.ld]
|
env["OBJDUMP"] = "x86_64-w64-mingw32-objdump"
|
||||||
env["LDFLAGS"] += %W[-Wl,-Map,${_TARGET}.map]
|
env.Program("^/BOOTX64.EFI", "${sources}")
|
||||||
env["LIBS"] += %w[gcc]
|
env.Disassemble("^/BOOTX64.txt", "^/BOOTX64.EFI")
|
||||||
env.FontGen("^/kfont/kfont.c", "font/Hack-Regular.ttf",
|
env.Image("^/hos.img", "^/BOOTX64.EFI")
|
||||||
"fontgen" => fontgen_env.expand("^/fontgen.bin"))
|
end
|
||||||
env.barrier
|
|
||||||
env["CPPPATH"] += ["#{env.build_root}/kfont"]
|
hulk_env = env "hulk", use: %w[ldc2 x86_64-elf-gcc] do |env|
|
||||||
env.Program("^/hos.elf", glob("src/**/*.{S,c}") + ["^/kfont/kfont.c"])
|
env["sources"] = glob("src/hulk/**/*.d")
|
||||||
env.depends("#{env.build_root}/hos.elf", "src/link.ld")
|
env["DFLAGS"] += %w[-mtriple=x86_64-unknown-elf --betterC -release -O3 --wi --enable-cross-module-inlining]
|
||||||
env.Disassemble("^/hos.elf.txt", "^/hos.elf")
|
env["D_IMPORT_PATH"] += %w[src/hulk src/common]
|
||||||
env.Size("^/hos.elf.size", "^/hos.elf")
|
env["LD"] = "x86_64-elf-gcc"
|
||||||
env.EfiImage("^/hos-efi.img", %w[^/hos.elf])
|
env["LDFLAGS"] += %w[-nostdlib -Tsrc/hulk/hulk.ld -Wl,-Map,${_TARGET}.map]
|
||||||
env.BiosImage("^/hos.img", %w[^/hos.elf])
|
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
|
end
|
||||||
|
|
||||||
task "run", desc: "Run HOS in QEMU" do
|
task "run", desc: "Run HOS in QEMU" do
|
||||||
img = kernel_env.expand("^/hos.img")
|
Dir.mktmpdir do |tmpdir|
|
||||||
sh %W[qemu-system-x86_64 -hda #{img}]
|
img = hello_env.expand("^/hos.img")
|
||||||
end
|
FileUtils.cp(img, tmpdir)
|
||||||
|
sh %W[qemu-system-x86_64 -bios OVMF.fd -drive file=#{tmpdir}/hos.img,format=raw]
|
||||||
task "run-efi", desc: "Run HOS EFI in QEMU" do
|
end
|
||||||
img = kernel_env.expand("^/hos-efi.img")
|
|
||||||
sh %W[qemu-system-x86_64 -bios OVMF.fd -hda #{img}]
|
|
||||||
end
|
end
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
# Copyright (c) 2013-2022 Josh Holtrop
|
# Copyright (c) 2013-2022 Josh Holtrop
|
||||||
#
|
#
|
||||||
# MIT License
|
# MIT License
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
# "Software"), to deal in the Software without restriction, including
|
# "Software"), to deal in the Software without restriction, including
|
||||||
@@ -11,10 +11,10 @@
|
|||||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
# permit persons to whom the Software is furnished to do so, subject to
|
# permit persons to whom the Software is furnished to do so, subject to
|
||||||
# the following conditions:
|
# the following conditions:
|
||||||
#
|
#
|
||||||
# The above copyright notice and this permission notice shall be
|
# The above copyright notice and this permission notice shall be
|
||||||
# included in all copies or substantial portions of the Software.
|
# included in all copies or substantial portions of the Software.
|
||||||
#
|
#
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
script = File.join(File.dirname(__FILE__), ".rscons-3.0.0-077c0388ca4d1d902141299abcc4b8f6.rb")
|
script = File.join(File.dirname(__FILE__), ".rscons-3.0.2-c49c635f1e4166223367979510498b28.rb")
|
||||||
unless File.exists?(script)
|
unless File.exists?(script)
|
||||||
if File.read(__FILE__, mode: "rb") =~ /^#==>(.*)/
|
if File.read(__FILE__, mode: "rb") =~ /^#==>(.*)/
|
||||||
require "zlib"
|
require "zlib"
|
||||||
@@ -43,4 +43,4 @@ load script
|
|||||||
if __FILE__ == $0
|
if __FILE__ == $0
|
||||||
Rscons::Cli.new.run(ARGV)
|
Rscons::Cli.new.run(ARGV)
|
||||||
end
|
end
|
||||||
#==>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 truncated
|
#==>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 truncated
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,26 @@
|
|||||||
|
import ldc.llvmasm;
|
||||||
|
|
||||||
|
ulong read_cr0()
|
||||||
|
{
|
||||||
|
return __asm!ulong("mov %cr0, %rax", "={rax}");
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong read_cr2()
|
||||||
|
{
|
||||||
|
return __asm!ulong("mov %cr2, %rax", "={rax}");
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong read_cr3()
|
||||||
|
{
|
||||||
|
return __asm!ulong("mov %cr3, %rax", "={rax}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_cr3(ulong v)
|
||||||
|
{
|
||||||
|
__asm("mov $0, %cr3", "r", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong read_cr4()
|
||||||
|
{
|
||||||
|
return __asm!ulong("mov %cr4, %rax", "={rax}");
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
import ldc.llvmasm;
|
||||||
|
|
||||||
|
void memset(void * dest, ubyte v, size_t n)
|
||||||
|
{
|
||||||
|
__asm("rep stosb",
|
||||||
|
"{al},{rcx},{rdi},~{rcx},~{rdi},~{memory}",
|
||||||
|
v, n, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void memset16(void * dest, ushort v, size_t n)
|
||||||
|
{
|
||||||
|
__asm("rep stosw",
|
||||||
|
"{ax},{rcx},{rdi},~{rcx},~{rdi},~{memory}",
|
||||||
|
v, n, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void memset32(void * dest, uint v, size_t n)
|
||||||
|
{
|
||||||
|
__asm("rep stosl",
|
||||||
|
"{eax},{rcx},{rdi},~{rcx},~{rdi},~{memory}",
|
||||||
|
v, n, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void memset64(void * dest, ulong v, size_t n)
|
||||||
|
{
|
||||||
|
__asm("rep stosq",
|
||||||
|
"{rax},{rcx},{rdi},~{rcx},~{rdi},~{memory}",
|
||||||
|
v, n, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void memcpy(void * dest, void * src, size_t n)
|
||||||
|
{
|
||||||
|
__asm("rep movsb",
|
||||||
|
"{rcx},{rsi},{rdi},~{rcx},~{rsi},~{rdi},~{memory}",
|
||||||
|
n, src, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void memcpy16(void * dest, void * src, size_t n)
|
||||||
|
{
|
||||||
|
__asm("rep movsw",
|
||||||
|
"{rcx},{rsi},{rdi},~{rcx},~{rsi},~{rdi},~{memory}",
|
||||||
|
n, src, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void memcpy32(void * dest, void * src, size_t n)
|
||||||
|
{
|
||||||
|
__asm("rep movsl",
|
||||||
|
"{rcx},{rsi},{rdi},~{rcx},~{rsi},~{rdi},~{memory}",
|
||||||
|
n, src, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void memcpy64(void * dest, void * src, size_t n)
|
||||||
|
{
|
||||||
|
__asm("rep movsq",
|
||||||
|
"{rcx},{rsi},{rdi},~{rcx},~{rsi},~{rdi},~{memory}",
|
||||||
|
n, src, dest);
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
struct PageTableEntry
|
||||||
|
{
|
||||||
|
ulong entry;
|
||||||
|
|
||||||
|
this(ulong address, ulong no_execute, ulong global,
|
||||||
|
ulong huge, ulong disable_cache, ulong write_through, ulong user,
|
||||||
|
ulong writable, ulong present)
|
||||||
|
{
|
||||||
|
entry = (present |
|
||||||
|
(writable << 1) |
|
||||||
|
(user << 2) |
|
||||||
|
(write_through << 3) |
|
||||||
|
(disable_cache << 4) |
|
||||||
|
(huge << 7) |
|
||||||
|
(global << 8) |
|
||||||
|
(no_execute << 63)) | address;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool present()
|
||||||
|
{
|
||||||
|
return (entry & 0x1u) != 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageTableEntry * next()
|
||||||
|
{
|
||||||
|
return cast(PageTableEntry *)(entry & 0x7FFF_FFFF_FFFF_F000u);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ulong page_table_index(ulong address, size_t level)
|
||||||
|
{
|
||||||
|
return ((address >> (39u - 9u * level)) & 0x1FFu);
|
||||||
|
}
|
||||||
|
}
|
||||||
File renamed without changes.
@@ -0,0 +1,215 @@
|
|||||||
|
import uefi;
|
||||||
|
import output;
|
||||||
|
import scratch;
|
||||||
|
import hulk.bootinfo;
|
||||||
|
import hos.page_table;
|
||||||
|
import hos.cpu;
|
||||||
|
import hos.memory;
|
||||||
|
|
||||||
|
__gshared EFI_SYSTEM_TABLE * st;
|
||||||
|
__gshared BootInfo bootinfo;
|
||||||
|
__gshared UINTN memory_map_key;
|
||||||
|
|
||||||
|
private void wait_key()
|
||||||
|
{
|
||||||
|
writeln("Press any key...");
|
||||||
|
st.ConIn.Reset(st.ConIn, FALSE);
|
||||||
|
EFI_INPUT_KEY key;
|
||||||
|
while (st.ConIn.ReadKeyStroke(st.ConIn, &key) == EFI_NOT_READY)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool in_qemu()
|
||||||
|
{
|
||||||
|
ulong * firmware_vendor = cast(ulong *) st.FirmwareVendor;
|
||||||
|
ulong fv1 = firmware_vendor[0];
|
||||||
|
return fv1 ==
|
||||||
|
((cast(ulong)'E') |
|
||||||
|
(cast(ulong)'D' << 16) |
|
||||||
|
(cast(ulong)'K' << 32) |
|
||||||
|
(cast(ulong)' ' << 48));
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool set_graphics_mode()
|
||||||
|
{
|
||||||
|
uint max_horizontal_resolution = in_qemu() ? 1920u : 0xFFFFFFFFu;
|
||||||
|
UINTN buffer_size = scratch_free();
|
||||||
|
EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||||
|
EFI_HANDLE * handles = cast(EFI_HANDLE *)scratch_current();
|
||||||
|
EFI_STATUS status = st.BootServices.LocateHandle(ByProtocol,
|
||||||
|
&gop_guid, null, &buffer_size, handles);
|
||||||
|
if (status != EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
writeln("LocateHandle: error %x", status);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
EFI_HANDLE gop_handle = handles[0];
|
||||||
|
EFI_HANDLE gop_interface;
|
||||||
|
status = st.BootServices.HandleProtocol(gop_handle,
|
||||||
|
&gop_guid, &gop_interface);
|
||||||
|
if (status != EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
writeln("HandleProtocol: error %x", status);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (gop_interface == null)
|
||||||
|
{
|
||||||
|
writeln("null interface from HandleProtocol");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
EFI_GRAPHICS_OUTPUT_PROTOCOL * gop = cast(EFI_GRAPHICS_OUTPUT_PROTOCOL *)gop_interface;
|
||||||
|
UINTN info_size;
|
||||||
|
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION * info;
|
||||||
|
uint best_width;
|
||||||
|
uint best_mode_number;
|
||||||
|
for (uint mode_number = 0u;
|
||||||
|
(status = gop.QueryMode(gop, mode_number, &info_size, &info)) == EFI_SUCCESS;
|
||||||
|
mode_number++)
|
||||||
|
{
|
||||||
|
if ((info.HorizontalResolution > best_width) &&
|
||||||
|
(info.HorizontalResolution <= max_horizontal_resolution))
|
||||||
|
{
|
||||||
|
best_width = info.HorizontalResolution;
|
||||||
|
best_mode_number = mode_number;
|
||||||
|
}
|
||||||
|
st.BootServices.FreePool(info);
|
||||||
|
}
|
||||||
|
if ((status = gop.SetMode(gop, best_mode_number)) != EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
writeln("SetMode: Error %x\n", status);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bootinfo.fb.buffer = cast(uint *)gop.Mode.FrameBufferBase;
|
||||||
|
bootinfo.fb.width = gop.Mode.Info.HorizontalResolution;
|
||||||
|
bootinfo.fb.height = gop.Mode.Info.VerticalResolution;
|
||||||
|
bootinfo.fb.stride = gop.Mode.Info.PixelsPerScanLine;
|
||||||
|
bootinfo.fb.format = gop.Mode.Info.PixelFormat;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool get_memory_map()
|
||||||
|
{
|
||||||
|
UINTN memory_map_size = scratch_free();
|
||||||
|
UINTN descriptor_size;
|
||||||
|
UINT32 descriptor_version;
|
||||||
|
ubyte * scratch_base = scratch_current();
|
||||||
|
UINTN status = st.BootServices.GetMemoryMap(
|
||||||
|
&memory_map_size,
|
||||||
|
cast(EFI_MEMORY_DESCRIPTOR *)scratch_base,
|
||||||
|
&memory_map_key,
|
||||||
|
&descriptor_size,
|
||||||
|
&descriptor_version);
|
||||||
|
if (status != EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
writeln("GetMemoryMap: Error %x", status);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
size_t n_entries = memory_map_size / descriptor_size;
|
||||||
|
size_t di;
|
||||||
|
for (size_t i = 0u; i < n_entries; i++)
|
||||||
|
{
|
||||||
|
EFI_MEMORY_DESCRIPTOR * descriptor = cast(EFI_MEMORY_DESCRIPTOR *)&scratch_base[i * descriptor_size];
|
||||||
|
if ((descriptor.Type == EfiConventionalMemory) ||
|
||||||
|
(descriptor.Type == EfiBootServicesCode) ||
|
||||||
|
(descriptor.Type == EfiBootServicesData))
|
||||||
|
{
|
||||||
|
bootinfo.memory_map[di].base = descriptor.PhysicalStart;
|
||||||
|
bootinfo.memory_map[di].size = descriptor.NumberOfPages * 4096u;
|
||||||
|
di++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bootinfo.memory_map_count = di;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PageTableEntry * new_page_table()
|
||||||
|
{
|
||||||
|
PageTableEntry * pt = cast(PageTableEntry *)scratch_alloc(1u);
|
||||||
|
memset64(pt, 0u, 512);
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void map(ulong source_page, ulong dest_page, PageTableEntry * pt_base)
|
||||||
|
{
|
||||||
|
PageTableEntry * pt = pt_base;
|
||||||
|
PageTableEntry * next_pt;
|
||||||
|
for (size_t level = 0; level < 4u; level++)
|
||||||
|
{
|
||||||
|
size_t pt_index = PageTableEntry.page_table_index(source_page, level);
|
||||||
|
if (pt[pt_index].present())
|
||||||
|
{
|
||||||
|
pt = pt[pt_index].next();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulong addr;
|
||||||
|
if (level < 3u)
|
||||||
|
{
|
||||||
|
next_pt = new_page_table();
|
||||||
|
addr = cast(ulong)next_pt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addr = dest_page;
|
||||||
|
}
|
||||||
|
pt[pt_index] = PageTableEntry(addr,
|
||||||
|
0u, 0u, 0u, 0u, 0u, 0u, 1u, 1u);
|
||||||
|
pt = next_pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void build_page_tables()
|
||||||
|
{
|
||||||
|
PageTableEntry * pt_base = new_page_table();
|
||||||
|
for (size_t i = 0u; i < bootinfo.memory_map_count; i++)
|
||||||
|
{
|
||||||
|
size_t n_pages = bootinfo.memory_map[i].size / 4096u;
|
||||||
|
for (size_t p = 0u; p < n_pages; p++)
|
||||||
|
{
|
||||||
|
ulong page_addr = bootinfo.memory_map[i].base + 4096u * p;
|
||||||
|
/* Identity map all pages. */
|
||||||
|
map(page_addr, page_addr, pt_base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write_cr3(cast(ulong)pt_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern (C) EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * st)
|
||||||
|
{
|
||||||
|
.st = st;
|
||||||
|
|
||||||
|
st.ConOut.ClearScreen(st.ConOut);
|
||||||
|
|
||||||
|
writeln("HELLO, HOS EFI Lightweight LOader, v0.1.0");
|
||||||
|
writeln("Firmware vendor: '%S', version: 0x%x", st.FirmwareVendor, st.FirmwareVendor);
|
||||||
|
|
||||||
|
if (!set_graphics_mode())
|
||||||
|
{
|
||||||
|
wait_key();
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
get_memory_map();
|
||||||
|
|
||||||
|
EFI_STATUS status = st.BootServices.ExitBootServices(image_handle, memory_map_key);
|
||||||
|
if (status == EFI_INVALID_PARAMETER)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (status == EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
writeln("ExitBootServices: Error %x", status);
|
||||||
|
wait_key();
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
build_page_tables();
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
import uefi;
|
||||||
|
import hello;
|
||||||
|
import core.stdc.stdarg;
|
||||||
|
|
||||||
|
private size_t format_hex(CHAR16 * s, ulong v, bool ptr)
|
||||||
|
{
|
||||||
|
string hex_chars = "0123456789ABCDEF";
|
||||||
|
bool print = ptr;
|
||||||
|
size_t si = 0u;
|
||||||
|
for (size_t i = 0u; i < 16u; i++)
|
||||||
|
{
|
||||||
|
if (ptr && (i == 8u))
|
||||||
|
{
|
||||||
|
s[si++] = '_';
|
||||||
|
}
|
||||||
|
ulong n = (v >> (60u - 4u * i)) & 0xFu;
|
||||||
|
if (n != 0u)
|
||||||
|
{
|
||||||
|
print = true;
|
||||||
|
}
|
||||||
|
if (print || (i == 15u))
|
||||||
|
{
|
||||||
|
s[si++] = hex_chars[n];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return si;
|
||||||
|
}
|
||||||
|
|
||||||
|
private size_t format_dec(CHAR16 * s, ulong v)
|
||||||
|
{
|
||||||
|
string dec_chars = "0123456789";
|
||||||
|
bool print;
|
||||||
|
char[20] buf;
|
||||||
|
size_t buf_i;
|
||||||
|
while ((buf_i == 0u) || (v != 0u))
|
||||||
|
{
|
||||||
|
ulong n = v % 10u;
|
||||||
|
buf[buf_i++] = dec_chars[n];
|
||||||
|
v /= 10u;
|
||||||
|
}
|
||||||
|
for (size_t si = 0u; si < buf_i; si++)
|
||||||
|
{
|
||||||
|
s[si] = buf[buf_i - si - 1u];
|
||||||
|
}
|
||||||
|
return buf_i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(string s, va_list args)
|
||||||
|
{
|
||||||
|
__gshared static CHAR16[256] s16;
|
||||||
|
size_t i = 0u;
|
||||||
|
bool escape = false;
|
||||||
|
foreach (char c; s)
|
||||||
|
{
|
||||||
|
if (escape)
|
||||||
|
{
|
||||||
|
if (c == '%')
|
||||||
|
{
|
||||||
|
s16[i++] = '%';
|
||||||
|
}
|
||||||
|
else if (c == 'x')
|
||||||
|
{
|
||||||
|
ulong v;
|
||||||
|
va_arg(args, v);
|
||||||
|
i += format_hex(&s16[i], v, false);
|
||||||
|
}
|
||||||
|
else if (c == 'p')
|
||||||
|
{
|
||||||
|
ulong v;
|
||||||
|
va_arg(args, v);
|
||||||
|
i += format_hex(&s16[i], v, true);
|
||||||
|
}
|
||||||
|
else if (c == 'S')
|
||||||
|
{
|
||||||
|
const(CHAR16) * s2;
|
||||||
|
va_arg(args, s2);
|
||||||
|
for (size_t s2_i = 0u; s2[s2_i] != 0; s2_i++)
|
||||||
|
{
|
||||||
|
s16[i++] = s2[s2_i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == 'u')
|
||||||
|
{
|
||||||
|
ulong v;
|
||||||
|
va_arg(args, v);
|
||||||
|
i += format_dec(&s16[i], v);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s16[i++] = c;
|
||||||
|
}
|
||||||
|
escape = false;
|
||||||
|
}
|
||||||
|
else if (c == '%')
|
||||||
|
{
|
||||||
|
escape = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s16[i++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s16[i++] = 0u;
|
||||||
|
st.ConOut.OutputString(st.ConOut, &s16[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern (C) void write(string s, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, s);
|
||||||
|
write(s, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern (C) void writeln(string s, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, s);
|
||||||
|
write(s, args);
|
||||||
|
write("\r\n", args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
__gshared ubyte[512 * 1024] scratch;
|
||||||
|
__gshared size_t scratch_used;
|
||||||
|
|
||||||
|
size_t scratch_free()
|
||||||
|
{
|
||||||
|
return scratch.sizeof - scratch_used;
|
||||||
|
}
|
||||||
|
|
||||||
|
ubyte * scratch_current()
|
||||||
|
{
|
||||||
|
return &scratch[scratch_used];
|
||||||
|
}
|
||||||
|
|
||||||
|
ubyte * scratch_alloc(size_t n = 1)
|
||||||
|
{
|
||||||
|
ubyte * address = &scratch[scratch_used];
|
||||||
|
scratch_used += 4096u * n;
|
||||||
|
return address;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import hulk.bootinfo;
|
||||||
|
import hos.memory;
|
||||||
|
import ldc.attributes;
|
||||||
|
|
||||||
|
@(ldc.attributes.section(".hulk_start"))
|
||||||
|
extern(C) void hulk_start(BootInfo * bootinfo)
|
||||||
|
{
|
||||||
|
for (size_t y = 100u; y < 120u; y++)
|
||||||
|
{
|
||||||
|
memset32(&bootinfo.fb.buffer[y * bootinfo.fb.stride + 20u], 0xFF8800u, 20u);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
ENTRY(hulk_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x0000800000000000;
|
||||||
|
_hulk_mem_start = .;
|
||||||
|
|
||||||
|
.text BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.hulk_start)
|
||||||
|
*(.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.rodata)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(COMMON)
|
||||||
|
*(.bss)
|
||||||
|
}
|
||||||
|
|
||||||
|
. = ALIGN(4K);
|
||||||
|
|
||||||
|
_hulk_mem_end = .;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
struct BootInfo
|
||||||
|
{
|
||||||
|
struct MemoryRegion
|
||||||
|
{
|
||||||
|
ulong base;
|
||||||
|
size_t size;
|
||||||
|
}
|
||||||
|
struct Framebuffer
|
||||||
|
{
|
||||||
|
uint * buffer;
|
||||||
|
uint width;
|
||||||
|
uint height;
|
||||||
|
uint stride;
|
||||||
|
uint format;
|
||||||
|
}
|
||||||
|
|
||||||
|
Framebuffer fb;
|
||||||
|
MemoryRegion[500] memory_map;
|
||||||
|
size_t memory_map_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ulong HULK_VIRTUAL_START = 0x0000_8000_0000_0000u;
|
||||||
Submodule
+1
Submodule uefi-d added at e70959ce8a.
@@ -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"
|
||||||
Reference in new issue
Block a user