Bringup loader config block parsing

Not tested yet
This commit is contained in:
plutoo 2018-01-11 22:59:29 +01:00
parent fd4522423b
commit 6720355dd1
6 changed files with 108 additions and 7 deletions

View File

@ -12,7 +12,8 @@ startup:
bl +4 bl +4
sub x28, x30, #0x84 sub x28, x30, #0x84
// save main thread handle // save context ptr and main thread handle
mov x26, x0
mov x27, x1 mov x27, x1
// clear .bss // clear .bss
@ -36,7 +37,8 @@ bss_loop:
bl __nx_dynamic bl __nx_dynamic
// initialize system // initialize system
mov x0, x27 mov x0, x26
mov x1, x27
bl __libnx_init bl __libnx_init
// call entrypoint // call entrypoint

View File

@ -44,6 +44,8 @@ extern "C" {
#include <switch/gfx/nvioctl.h> #include <switch/gfx/nvioctl.h>
#include <switch/gfx/nvgfx.h> #include <switch/gfx/nvgfx.h>
#include <switch/runtime/env.h>
#include <switch/runtime/util/utf.h> #include <switch/runtime/util/utf.h>
#include <switch/runtime/devices/console.h> #include <switch/runtime/devices/console.h>

View File

@ -0,0 +1,5 @@
// Copyright 2018 plutoo
void envParse(void* ctx, Handle main_thread);
Handle envGetMainThreadHandle(void);
bool envIsNso(void);

91
nx/source/runtime/env.c Normal file
View File

@ -0,0 +1,91 @@
// Copyright 2018 plutoo
#include <switch.h>
static bool g_isNso = false;
static Handle g_mainThreadHandle = INVALID_HANDLE;
static void* g_loaderRetAddr = NULL;
static void* g_overrideHeapAddr = NULL;
static u64 g_overrideHeapSize = 0;
typedef struct {
u32 Key;
u32 Flags;
u64 Value[2];
} ConfigEntry;
enum {
EntryType_EndOfList=0,
EntryType_MainThreadHandle=1,
EntryType_LoaderReturnAddr=2,
EntryType_OverrideHeap=3,
EntryType_OverrideService=4,
EntryType_Argv=5,
EntryType_SyscallAvailableHint=6,
EntryType_AppletType=7
};
void envParse(void* ctx, Handle main_thread)
{
if (main_thread != INVALID_HANDLE)
{
g_mainThreadHandle = main_thread;
g_isNso = true;
return;
}
ConfigEntry* ent = ctx;
while (ent->Key != EntryType_EndOfList)
{
switch (ent->Key)
{
case EntryType_MainThreadHandle:
g_mainThreadHandle = ent->Value[0];
break;
case EntryType_LoaderReturnAddr:
g_loaderRetAddr = (void*) ent->Value[0];
break;
case EntryType_OverrideHeap:
g_overrideHeapAddr = (void*) ent->Value[0];
g_overrideHeapSize = ent->Value[1];
break;
case EntryType_OverrideService:
// TODO
break;
case EntryType_Argv:
// TODO
break;
case EntryType_SyscallAvailableHint:
// TODO
break;
case EntryType_AppletType:
// TODO
break;
default:
// TODO
break;
}
ent++;
}
}
Handle envGetMainThreadHandle(void) {
if (g_mainThreadHandle != INVALID_HANDLE) {
return g_mainThreadHandle;
}
fatalSimple(1);
}
bool envIsNso(void) {
return g_isNso;
}

View File

@ -3,7 +3,7 @@
void __nx_exit(int rc); void __nx_exit(int rc);
void virtmemSetup(void); void virtmemSetup(void);
void newlibSetup(Handle main_thread); void newlibSetup(void);
void __system_initArgv(void); void __system_initArgv(void);
@ -53,12 +53,13 @@ void __attribute__((weak)) __appExit(void)
smExit(); smExit();
} }
void __attribute__((weak)) __libnx_init(Handle main_thread) void __attribute__((weak)) __libnx_init(void* ctx, Handle main_thread)
{ {
// Called by crt0. // Called by crt0.
// Libnx initialization goes here. // Libnx initialization goes here.
newlibSetup(main_thread); envParse(ctx, main_thread);
newlibSetup();
virtmemSetup(); virtmemSetup();
__libnx_initheap(); __libnx_initheap();

View File

@ -18,7 +18,7 @@ static struct _reent* __libnx_get_reent(void) {
return tv->reent; return tv->reent;
} }
void newlibSetup(Handle main_thread) { void newlibSetup() {
// Register newlib syscalls // Register newlib syscalls
__syscalls.exit = __libnx_exit; __syscalls.exit = __libnx_exit;
__syscalls.getreent = __libnx_get_reent; __syscalls.getreent = __libnx_get_reent;
@ -39,7 +39,7 @@ void newlibSetup(Handle main_thread) {
tv->thread_ptr = NULL; tv->thread_ptr = NULL;
tv->reent = _impure_ptr; tv->reent = _impure_ptr;
tv->tls_tp = __tls_start-2*sizeof(void*); // subtract size of Thread Control Block (TCB) tv->tls_tp = __tls_start-2*sizeof(void*); // subtract size of Thread Control Block (TCB)
tv->handle = main_thread; tv->handle = envGetMainThreadHandle();
u32 tls_size = __tdata_lma_end - __tdata_lma; u32 tls_size = __tdata_lma_end - __tdata_lma;
if (tls_size) if (tls_size)