From: Jon Feldman Date: Sat, 11 Feb 2017 12:15:13 +0000 (-0500) Subject: BOOM, FIRMLAUNCH IS A GO X-Git-Tag: v0.3.1~8 X-Git-Url: https://chaos.moe/g/?a=commitdiff_plain;h=c1770d10e9c9048f0c245af2df8eb22260faf8a4;p=corbenik%2Fcorbenik.git BOOM, FIRMLAUNCH IS A GO Turns out the entrypoint under firmlaunch for ARM11 is at 0x1FFFFFFC, not 0x1FFFFFF8 like arm9loaderhax / brahma That also explains why screeninit fails on firmlaunch; the wrong entry is used. Either way I still want to do some cleanup, but it works now. I'm going to slap a big thank you here to the authors of Luma3DS. I never would have realized the entrypoint was different unless I looked at their code. --- diff --git a/boot/arm11.c b/boot/arm11.c index 54d6892..22ef514 100644 --- a/boot/arm11.c +++ b/boot/arm11.c @@ -39,6 +39,8 @@ #include // for memalign #include // for framebuffers +int screen_is_init = 0; + struct framebuffers *framebuffers; volatile uint32_t *const arm11Entry = (volatile uint32_t *)0x1FFFFFF8; @@ -160,6 +162,10 @@ void set_fb_struct() { } } +int get_screen_is_init() { + return screen_is_init; +} + void screen_mode(uint32_t mode, uint32_t bright_level) { static uint32_t stride, init_top, init_bottom, bright; @@ -282,4 +288,7 @@ void screen_mode(uint32_t mode, uint32_t bright_level) { // i2cWriteRegister(I2C_DEV_MCU, 0x22, 1 << 1); //Turn on backlight i2cWriteRegister(I2C_DEV_MCU, 0x22, 0x2A); + + screen_is_init = 1; } + diff --git a/boot/corbenik.c b/boot/corbenik.c index 526302c..0eacb4f 100644 --- a/boot/corbenik.c +++ b/boot/corbenik.c @@ -26,6 +26,13 @@ extern int changed_consoles; extern uint16_t titleid_passthru[8]; +int is_firmlaunch() { + for (int i=0; i < 8; i++) + if (titleid_passthru[i] != 0) + return 1; + return 0; +} + int get_firmtype() { if (titleid_passthru[5] >= u'0' && titleid_passthru[5] <= u'2') return titleid_passthru[5] - u'0'; @@ -36,9 +43,6 @@ int get_firmtype() { int main(int argc, char** argv) { - if (get_firmtype() != 0) - ctr_system_poweroff(); - int have_bg = 0; int si = 0; @@ -54,6 +58,19 @@ main(int argc, char** argv) load_config(); // Load configuration. + // Check key down for autoboot + set_fb_struct(); + + if (is_firmlaunch()) { + shut_up(); + + const char* firm_paths[] = { PATH_NATIVE_P, PATH_TWL_P, PATH_AGB_P }; + + firmlaunch_file(firm_paths[get_firmtype()]); + + ctr_system_poweroff(); + } + install_interrupts(); // Get some free debug info. installArm11Stub(); @@ -63,9 +80,6 @@ main(int argc, char** argv) set_font(PATH_TERMFONT); // Read the font before all else. - // Check key down for autoboot - set_fb_struct(); - clear_bg(); // This is a menuhax splash (90deg rotated BGR8 pixel data) diff --git a/boot/firm/firmlaunch.c b/boot/firm/firmlaunch.c index ac597b7..3894935 100644 --- a/boot/firm/firmlaunch.c +++ b/boot/firm/firmlaunch.c @@ -11,7 +11,11 @@ #include "std/draw.h" // for crflush, stderr #include "std/fs.h" // for crumount +#include "patcher.h" +#include + static volatile uint32_t *const a11_entry = (volatile uint32_t *)0x1FFFFFF8; +static volatile uint32_t *const a11_entry_fl = (volatile uint32_t *)0x1FFFFFFC; void firmlaunch(firm_h* firm) { // Get entrypoints @@ -29,10 +33,24 @@ void firmlaunch(firm_h* firm) { crumount(); // Unmount SD. - deinitScreens(); // Turn off display + if (get_screen_is_init()) + deinitScreens(); // Turn off display if on - *a11_entry = (uint32_t)entry11; // Start kernel11 + if (is_firmlaunch()) + *a11_entry_fl = (uint32_t)entry11; // Start kernel11 + else + *a11_entry = (uint32_t)entry11; // Start kernel11 entry9(); // Start process9 } +void firmlaunch_file(const char* path) { + FILE* f = cropen(path, "r"); + size_t s = crsize(f); + uint8_t* mem = malloc(s); + crread(mem, 1, s, f); + crclose(f); + + firmlaunch((firm_h*)mem); +} + diff --git a/include/arm11.h b/include/arm11.h index 57e9c8f..2ad4b1a 100644 --- a/include/arm11.h +++ b/include/arm11.h @@ -43,6 +43,8 @@ #define ARM11_STUB_ADDRESS (0x25000000 - 0x30) //It's currently only 0x28 bytes large. We're putting 0x30 just to be sure here #define WAIT_FOR_ARM9() *arm11Entry = 0; while(!*arm11Entry); ((void (*)())*arm11Entry)(); +int get_screen_is_init(); + /* Initializes the screen and sets the display mode. * * \param mode Screen mode to initialize in, one of RGBA8, BGR8, RGB565_OES, RGB5_A1_OES, or RGBA4_OES diff --git a/include/firm/firm.h b/include/firm/firm.h index ea32a2f..1c9af9c 100644 --- a/include/firm/firm.h +++ b/include/firm/firm.h @@ -43,6 +43,8 @@ int boot_firm(const char* firm_path, const char* prepatch_path, const char* modu */ firm_h* load_firm(const char *path, size_t *size_out); +void firmlaunch_file(const char* path); + exefs_h* find_proc9(firm_h *firm); #endif diff --git a/include/patcher.h b/include/patcher.h index d13ab36..cd32930 100644 --- a/include/patcher.h +++ b/include/patcher.h @@ -1,6 +1,9 @@ #ifndef __PATCHER_H #define __PATCHER_H +int is_firmlaunch(); +int get_firmtype(); + /* Patches firmware with the current configuration. * * \return zero on success