]> Chaos Git - corbenik/corbenik.git/commitdiff
BOOM, FIRMLAUNCH IS A GO
authorJon Feldman <chaos.kagami@gmail.com>
Sat, 11 Feb 2017 12:15:13 +0000 (07:15 -0500)
committerJon Feldman <chaos.kagami@gmail.com>
Sat, 11 Feb 2017 12:17:01 +0000 (07:17 -0500)
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.

boot/arm11.c
boot/corbenik.c
boot/firm/firmlaunch.c
include/arm11.h
include/firm/firm.h
include/patcher.h

index 54d68928995ffd931d9377bb727add5b32e61d32..22ef514af065c2287381235b8690b5eccf2528ae 100644 (file)
@@ -39,6 +39,8 @@
 #include <malloc.h>          // for memalign
 #include <std/draw.h>        // 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;
 }
+
index 526302c83db2bb0371135ee7021f8844c41f4780..0eacb4f78689e220ddb429c4ebcbfdb064d94485 100644 (file)
@@ -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)
index ac597b7ffeb918995f75f15f8b2299c2f4e67d6f..38949357891f876e7f04e713de6ca075c2fdb080 100644 (file)
 #include "std/draw.h"       // for crflush, stderr
 #include "std/fs.h"         // for crumount
 
+#include "patcher.h"
+#include <ctr9/ctr_system.h>
+
 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);
+}
+
index 57e9c8f8efc3b75ccf0f5f4c559eaef1c66d146c..2ad4b1a3aabfb72bcf3ac10052779d536346b604 100644 (file)
@@ -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
index ea32a2fe909e916c1e053196f8097a0e7a2deedf..1c9af9c811c8386a8ef063b183f05f2ab61ae4bf 100644 (file)
@@ -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
index d13ab36f81844e05025a11235c0911c966da58fa..cd3293051b1d4657de249bb7716c56617709c3b3 100644 (file)
@@ -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