meso: add script to build mesosphere.bin

This commit is contained in:
Michael Scire 2020-01-23 19:00:42 -08:00
parent 3982afdd6b
commit bce7133128
6 changed files with 79 additions and 6 deletions

View file

@ -27,7 +27,7 @@ namespace ams::kern::init {
u32 rw_end_offset;
u32 bss_offset;
u32 bss_end_offset;
u32 ini_end_offset;
u32 ini_load_offset;
u32 dynamic_offset;
u32 init_array_offset;
u32 init_array_end_offset;

View file

@ -16,6 +16,8 @@
#include <mesosphere.hpp>
#include <vapours/svc/svc_codegen.hpp>
/* TODO: Enable compilation of this file when the kernel supports supervisor calls. */
#if 0
namespace ams::kern::svc {
namespace {
@ -41,7 +43,6 @@ namespace ams::kern::svc {
}
/* TODO: 32-bit ABI */
const std::array<SvcTableEntry, NumSupervisorCalls> SvcTable64From32 = [] {
std::array<SvcTableEntry, NumSupervisorCalls> table = {};
@ -65,3 +66,4 @@ namespace ams::kern::svc {
}();
}
#endif

View file

@ -9,7 +9,8 @@ clean: $(CLEAN_TARGETS)
@rm -f mesosphere.bin
mesosphere.bin: $(TARGETS)
@echo "todo: py script"
@python build_mesosphere.py
@echo "Built mesosphere.bin..."
$(TARGETS):
$(MAKE) -C $@

View file

@ -0,0 +1,45 @@
#!/usr/bin/env python
import sys, os
from struct import pack as pk, unpack as up
def align_up(val, algn):
val += algn - 1
return val - (val % algn)
def main(argc, argv):
if argc != 1:
print('Usage: %s' % argv[0])
return 1
with open('kernel_ldr/kernel_ldr.bin', 'rb') as f:
kernel_ldr = f.read()
with open('kernel/kernel.bin', 'rb') as f:
kernel = f.read()
kernel_metadata_offset = up('<I', kernel[4:8])[0]
assert (kernel_metadata_offset <= len(kernel) - 0x40)
assert (kernel[kernel_metadata_offset:kernel_metadata_offset + 4] == b'MSS0')
kernel_end = up('<I', kernel[kernel_metadata_offset + 0x30:kernel_metadata_offset + 0x34])[0]
assert (kernel_end >= len(kernel))
embedded_ini = b''
embedded_ini_offset = align_up(kernel_end, 0x1000) + 0x1000
embedded_ini_end = embedded_ini_offset + 0 # TODO: Create and embed an INI, eventually.
kernel_ldr_offset = align_up(embedded_ini_end, 0x1000) + 0x1000
kernel_ldr_end = kernel_ldr_offset + len(kernel_ldr)
with open('mesosphere.bin', 'wb') as f:
f.write(kernel[:kernel_metadata_offset + 8])
f.write(pk('<II', embedded_ini_offset, kernel_ldr_offset))
f.write(kernel[kernel_metadata_offset + 0x10:])
f.seek(embedded_ini_offset)
f.write(embedded_ini)
f.seek(embedded_ini_end)
f.seek(kernel_ldr_offset)
f.write(kernel_ldr)
f.seek(kernel_ldr_end)
return 0
if __name__ == '__main__':
sys.exit(main(len(sys.argv), sys.argv))

View file

@ -23,3 +23,26 @@
_start:
/* TODO */
b _start
.word (__metadata_begin - _start)
__metadata_begin:
.ascii "MSS0" /* Magic */
.word 0 /* KInitArguments */
.word 0 /* INI1 base address. */
.word 0 /* Kernel Loader base address. */
__metadata_kernel_layout:
.word _start - _start /* rx_offset */
.word __rodata_start - _start /* rx_end_offset */
.word __rodata_start - _start /* ro_offset */
.word __data_start - _start /* ro_end_offset */
.word __data_start - _start /* rw_offset */
.word __bss_start__ - _start /* rw_end_offset */
.word __bss_start__ - _start /* bss_offset */
.word __bss_end__ - _start /* bss_end_offset */
.word __end__ - _start /* ini_load_offset */
.word _DYNAMIC - _start /* dynamic_offset */
.word __init_array_start - _start /* init_array_offset */
.word __init_array_end - _start /* init_array_end_offset */
.if (. - __metadata_begin) != 0x40
.error "Incorrect Mesosphere Metadata"
.endif

View file

@ -269,7 +269,7 @@ namespace ams::kern::init::loader {
MESOSPHERE_ABORT_UNLESS(util::IsAligned(rw_offset, 0x1000));
MESOSPHERE_ABORT_UNLESS(util::IsAligned(bss_end_offset, 0x1000));
const uintptr_t bss_offset = layout->bss_offset;
const uintptr_t ini_end_offset = layout->ini_end_offset;
const uintptr_t ini_load_offset = layout->ini_load_offset;
const uintptr_t dynamic_offset = layout->dynamic_offset;
const uintptr_t init_array_offset = layout->init_array_offset;
const uintptr_t init_array_end_offset = layout->init_array_end_offset;
@ -277,9 +277,11 @@ namespace ams::kern::init::loader {
/* Decide if Kernel should have enlarged resource region. */
const bool use_extra_resources = KSystemControl::Init::ShouldIncreaseThreadResourceLimit();
const size_t resource_region_size = KernelResourceRegionSize + (use_extra_resources ? ExtraKernelResourceSize : 0);
static_assert(KernelResourceRegionSize > InitialProcessBinarySizeMax);
static_assert(KernelResourceRegionSize + ExtraKernelResourceSize > InitialProcessBinarySizeMax);
/* Setup the INI1 header in memory for the kernel. */
const uintptr_t ini_end_address = base_address + ini_end_offset + resource_region_size;
const uintptr_t ini_end_address = base_address + ini_load_offset + resource_region_size;
const uintptr_t ini_load_address = ini_end_address - InitialProcessBinarySizeMax;
if (ini_base_address != ini_load_address) {
/* The INI is not at the correct address, so we need to relocate it. */