mirror of
https://github.com/ApacheThunder/XuluMenu.git
synced 2025-06-19 03:55:32 -04:00
Add stage2 loader
* Can now boot stage2 (in safe block mode) if holding L-Shoulder + R-Shoulder + A + B + DPAD Up on boot. This allows using built in stage2 usb update mode for "bootleg" style N-Cards that have Xulumenu installed. * This button combo will not do anything for regular N-Card users as they already have a proper stage2 section on nand and it will always end up booting to USB update mode with this button combo before xulumenu can boot.
This commit is contained in:
parent
b621b163c8
commit
2550af0c99
10
Makefile
10
Makefile
@ -10,7 +10,7 @@ export TOPDIR := $(CURDIR)
|
|||||||
|
|
||||||
include $(DEVKITARM)/ds_rules
|
include $(DEVKITARM)/ds_rules
|
||||||
|
|
||||||
.PHONY: data bootloader bootloaderalt clean
|
.PHONY: data bootloader udiskloader clean
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# main targets
|
# main targets
|
||||||
@ -37,15 +37,15 @@ data:
|
|||||||
bootloader: data
|
bootloader: data
|
||||||
$(MAKE) -C bootloader LOADBIN=$(TOPDIR)/data/load.bin
|
$(MAKE) -C bootloader LOADBIN=$(TOPDIR)/data/load.bin
|
||||||
|
|
||||||
bootloaderalt: data
|
udiskloader: data
|
||||||
$(MAKE) -C bootloaderalt LOADBIN=$(TOPDIR)/data/loadAlt.bin
|
$(MAKE) -C udiskloader LOADBIN=$(TOPDIR)/data/udiskloader.bin
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
arm7/$(TARGET).elf:
|
arm7/$(TARGET).elf:
|
||||||
$(MAKE) -C arm7
|
$(MAKE) -C arm7
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
arm9/$(TARGET).elf: bootloader bootloaderalt
|
arm9/$(TARGET).elf: bootloader udiskloader
|
||||||
$(MAKE) -C arm9
|
$(MAKE) -C arm9
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
@ -53,6 +53,6 @@ clean:
|
|||||||
$(MAKE) -C arm9 clean
|
$(MAKE) -C arm9 clean
|
||||||
$(MAKE) -C arm7 clean
|
$(MAKE) -C arm7 clean
|
||||||
$(MAKE) -C bootloader clean
|
$(MAKE) -C bootloader clean
|
||||||
$(MAKE) -C bootloaderalt clean
|
$(MAKE) -C udiskloader clean
|
||||||
rm -rf data
|
rm -rf data
|
||||||
rm -f $(TARGET).nds
|
rm -f $(TARGET).nds
|
||||||
|
@ -30,3 +30,4 @@ int main(void) {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
arm9/binaries/stage2.srl
Normal file
BIN
arm9/binaries/stage2.srl
Normal file
Binary file not shown.
Binary file not shown.
@ -8,6 +8,8 @@ extern "C" {
|
|||||||
|
|
||||||
extern void udiskData();
|
extern void udiskData();
|
||||||
extern void udiskData_end();
|
extern void udiskData_end();
|
||||||
|
extern void stage2Data();
|
||||||
|
extern void stage2_end();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
.arm
|
.arm
|
||||||
.global udiskData, udiskData_end
|
.global udiskData, udiskData_end, stage2Data, stage2_end
|
||||||
|
|
||||||
udiskData:
|
udiskData:
|
||||||
.incbin "../binaries/udisk.srl"
|
.incbin "../binaries/udisk.srl"
|
||||||
udiskData_end:
|
udiskData_end:
|
||||||
|
|
||||||
|
stage2Data:
|
||||||
|
.incbin "../binaries/stage2.srl"
|
||||||
|
stage2_end:
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,15 +67,15 @@ int FileBrowser() {
|
|||||||
// Construct a command line
|
// Construct a command line
|
||||||
vector<string> argarray;
|
vector<string> argarray;
|
||||||
if (!argsFillArray(filename, argarray)) {
|
if (!argsFillArray(filename, argarray)) {
|
||||||
iprintf("Invalid NDS or arg file selected\n");
|
iprintf("\n\nInvalid NDS or arg file selected\n");
|
||||||
} else {
|
} else {
|
||||||
iprintf("Running %s with %d parameters\n", argarray[0].c_str(), argarray.size());
|
iprintf("\n\nRunning %s with %d\nparameters\n", argarray[0].c_str(), argarray.size());
|
||||||
// Make a copy of argarray using C strings, for the sake of runNdsFile
|
// Make a copy of argarray using C strings, for the sake of runNdsFile
|
||||||
vector<const char*> c_args;
|
vector<const char*> c_args;
|
||||||
for (const auto& arg: argarray) { c_args.push_back(arg.c_str()); }
|
for (const auto& arg: argarray) { c_args.push_back(arg.c_str()); }
|
||||||
// Try to run the NDS file with the given arguments
|
// Try to run the NDS file with the given arguments
|
||||||
int err = runNdsFile(c_args[0], c_args.size(), &c_args[0]);
|
int err = runNdsFile(c_args[0], c_args.size(), &c_args[0]);
|
||||||
iprintf("Start failed. Error %i\n", err);
|
iprintf("\n\nStart failed. Error %i\n", err);
|
||||||
}
|
}
|
||||||
argarray.clear();
|
argarray.clear();
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -97,17 +97,23 @@ int RecoveryPrompt(void) {
|
|||||||
scanKeys();
|
scanKeys();
|
||||||
if(keysDown() & KEY_A)break;
|
if(keysDown() & KEY_A)break;
|
||||||
}
|
}
|
||||||
return runUdisk();
|
return runSRLbinary(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
// Any error results in starting integrated uDisk 1.45 SRL as fall back
|
// Any error results in starting integrated uDisk 1.45 SRL as fall back
|
||||||
scanKeys();
|
scanKeys();
|
||||||
if ((keysHeld() & KEY_L) && (keysHeld() & KEY_R))return RecoveryPrompt(); // Recovery option if FAT init hangs
|
u32 KeysHeld = keysHeld();
|
||||||
|
if ((KeysHeld & KEY_L) && (KeysHeld & KEY_R) && (KeysHeld & KEY_A) && (KeysHeld & KEY_B) && (KeysHeld & KEY_UP)) {
|
||||||
|
return runSRLbinary(true); // Recovery option if need to boot stage2
|
||||||
|
} else if ((KeysHeld & KEY_L) && (KeysHeld & KEY_R)) {
|
||||||
|
return RecoveryPrompt(); // Recovery option if FAT init hangs
|
||||||
|
}
|
||||||
if (!fatInitDefault())return RecoveryPrompt();
|
if (!fatInitDefault())return RecoveryPrompt();
|
||||||
if((access("/boot.nds", F_OK) == 0) && !(keysHeld() & KEY_B))runNdsFile("/boot.nds", 0, NULL);
|
if (!(KeysHeld & KEY_B)) {
|
||||||
if((access("/udisk.nds", F_OK) == 0) && !(keysHeld() & KEY_B))runNdsFile("/udisk.nds", 0, NULL);
|
if((access("/boot.nds", F_OK) == 0))return runNdsFile("/boot.nds", 0, NULL);
|
||||||
|
if((access("/udisk.nds", F_OK) == 0))return runNdsFile("/udisk.nds", 0, NULL);
|
||||||
|
}
|
||||||
FileBrowser();
|
FileBrowser();
|
||||||
return RecoveryPrompt();
|
return RecoveryPrompt();
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#include <fat.h>
|
#include <fat.h>
|
||||||
|
|
||||||
#include "load_bin.h"
|
#include "load_bin.h"
|
||||||
#include "loadAlt_bin.h"
|
#include "udiskloader_bin.h"
|
||||||
#include "binaries.h"
|
#include "binaries.h"
|
||||||
#include "tonccpy.h"
|
#include "tonccpy.h"
|
||||||
|
|
||||||
@ -229,8 +229,12 @@ static bool dldiPatchLoader (data_t *binData, u32 binSize, bool clearBSS) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int runUdisk() {
|
int runSRLbinary(bool isStage2) {
|
||||||
|
if (isStage2) {
|
||||||
|
tonccpy((void*)TMP_DATA, (void*)stage2Data, (stage2_end - stage2Data));
|
||||||
|
} else {
|
||||||
tonccpy((void*)TMP_DATA, (void*)udiskData, (udiskData_end - udiskData));
|
tonccpy((void*)TMP_DATA, (void*)udiskData, (udiskData_end - udiskData));
|
||||||
|
}
|
||||||
// Start Bootloader
|
// Start Bootloader
|
||||||
irqDisable(IRQ_ALL);
|
irqDisable(IRQ_ALL);
|
||||||
// Direct CPU access to VRAM bank D
|
// Direct CPU access to VRAM bank D
|
||||||
@ -238,14 +242,14 @@ int runUdisk() {
|
|||||||
// Clear VRAM
|
// Clear VRAM
|
||||||
vramset (LCDC_BANK_D, 0x0000, 128 * 1024);
|
vramset (LCDC_BANK_D, 0x0000, 128 * 1024);
|
||||||
// Load the loader/patcher into the correct address
|
// Load the loader/patcher into the correct address
|
||||||
vramcpy (LCDC_BANK_D, loadAlt_bin, loadAlt_bin_size);
|
vramcpy (LCDC_BANK_D, udiskloader_bin, udiskloader_bin_size);
|
||||||
// Give the VRAM to the ARM7
|
// Give the VRAM to the ARM7
|
||||||
VRAM_D_CR = VRAM_ENABLE | VRAM_D_ARM7_0x06020000;
|
VRAM_D_CR = VRAM_ENABLE | VRAM_D_ARM7_0x06020000;
|
||||||
// Reset into a passme loop
|
// Reset into a passme loop
|
||||||
REG_EXMEMCNT = 0xFFFF;
|
REG_EXMEMCNT = 0xFFFF;
|
||||||
*((vu32*)0x027FFFFC) = 0;
|
*((vu32*)0x02FFFFFC) = 0;
|
||||||
*((vu32*)0x027FFE04) = (u32)0xE59FF018;
|
*((vu32*)0x02FFFE04) = (u32)0xE59FF018;
|
||||||
*((vu32*)0x027FFE24) = (u32)0x027FFE04;
|
*((vu32*)0x02FFFE24) = (u32)0x02FFFE04;
|
||||||
resetARM7(0x06020000);
|
resetARM7(0x06020000);
|
||||||
swiSoftReset();
|
swiSoftReset();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -36,7 +36,7 @@ typedef enum {
|
|||||||
|
|
||||||
#define LOAD_DEFAULT_NDS 0
|
#define LOAD_DEFAULT_NDS 0
|
||||||
|
|
||||||
int runUdisk();
|
int runSRLbinary(bool isStage2);
|
||||||
|
|
||||||
eRunNdsRetCode runNds (const void* loader, u32 loaderSize, u32 cluster, bool initDisc, bool dldiPatchNds, int argc, const char** argv);
|
eRunNdsRetCode runNds (const void* loader, u32 loaderSize, u32 cluster, bool initDisc, bool dldiPatchNds, int argc, const char** argv);
|
||||||
|
|
||||||
|
@ -285,6 +285,17 @@ void startBinary_ARM7 (void) {
|
|||||||
while(REG_VCOUNT==191);
|
while(REG_VCOUNT==191);
|
||||||
// copy NDS ARM9 start address into the header, starting ARM9
|
// copy NDS ARM9 start address into the header, starting ARM9
|
||||||
*((vu32*)0x02FFFE24) = TEMP_ARM9_START_ADDRESS;
|
*((vu32*)0x02FFFE24) = TEMP_ARM9_START_ADDRESS;
|
||||||
|
|
||||||
|
bool isXmenu = false;
|
||||||
|
|
||||||
|
switch (*((vu16*)0x02FFFF5E)) {
|
||||||
|
case 0xF63D: { isXmenu = true; }break;
|
||||||
|
case 0x0695: { isXmenu = true; }break;
|
||||||
|
case 0xE4C4: { isXmenu = true; }break;
|
||||||
|
case 0x918C: { isXmenu = true; }break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ARM9_START_FLAG = 1;
|
ARM9_START_FLAG = 1;
|
||||||
// Start ARM7
|
// Start ARM7
|
||||||
VoidFn arm7code = *(VoidFn*)(0x2FFFE34);
|
VoidFn arm7code = *(VoidFn*)(0x2FFFE34);
|
||||||
@ -294,9 +305,7 @@ void startBinary_ARM7 (void) {
|
|||||||
int sdmmc_sd_readsectors(u32 sector_no, u32 numsectors, void *out);
|
int sdmmc_sd_readsectors(u32 sector_no, u32 numsectors, void *out);
|
||||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
// Main function
|
// Main function
|
||||||
bool sdmmc_inserted() {
|
bool sdmmc_inserted() { return true; }
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sdmmc_startup() {
|
bool sdmmc_startup() {
|
||||||
sdmmc_controller_init(true);
|
sdmmc_controller_init(true);
|
||||||
@ -324,18 +333,9 @@ int main (void) {
|
|||||||
#endif
|
#endif
|
||||||
u32 fileCluster = storedFileCluster;
|
u32 fileCluster = storedFileCluster;
|
||||||
// Init card
|
// Init card
|
||||||
if(!FAT_InitFiles(initDisc))
|
if(!FAT_InitFiles(initDisc))return -1;
|
||||||
{
|
if ((fileCluster < CLUSTER_FIRST) || (fileCluster >= CLUSTER_EOF))fileCluster = getBootFileCluster(bootName); /* Invalid file cluster specified */
|
||||||
return -1;
|
if (fileCluster == CLUSTER_FREE)return -1;
|
||||||
}
|
|
||||||
if ((fileCluster < CLUSTER_FIRST) || (fileCluster >= CLUSTER_EOF)) /* Invalid file cluster specified */
|
|
||||||
{
|
|
||||||
fileCluster = getBootFileCluster(bootName);
|
|
||||||
}
|
|
||||||
if (fileCluster == CLUSTER_FREE)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ARM9 clears its memory part 2
|
// ARM9 clears its memory part 2
|
||||||
// copy ARM9 function to RAM, and make the ARM9 jump to it
|
// copy ARM9 function to RAM, and make the ARM9 jump to it
|
||||||
@ -380,6 +380,7 @@ int main (void) {
|
|||||||
// Pass command line arguments to loaded program
|
// Pass command line arguments to loaded program
|
||||||
passArgs_ARM7();
|
passArgs_ARM7();
|
||||||
|
|
||||||
|
|
||||||
startBinary_ARM7();
|
startBinary_ARM7();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -12,7 +12,7 @@ endif
|
|||||||
# SOURCES is a list of directories containing source code
|
# SOURCES is a list of directories containing source code
|
||||||
# INCLUDES is a list of directories containing extra header files
|
# INCLUDES is a list of directories containing extra header files
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
TARGET := loadAlt
|
TARGET := udiskloader
|
||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := source source/patches
|
SOURCES := source source/patches
|
||||||
INCLUDES := build ../include
|
INCLUDES := build ../include
|
@ -5,7 +5,7 @@ ENTRY(_start)
|
|||||||
MEMORY {
|
MEMORY {
|
||||||
|
|
||||||
vram : ORIGIN = 0x06020000, LENGTH = 64K
|
vram : ORIGIN = 0x06020000, LENGTH = 64K
|
||||||
arm9ram : ORIGIN = 0x027FD800, LENGTH = 4K
|
arm9ram : ORIGIN = 0x02FFD800, LENGTH = 4K
|
||||||
}
|
}
|
||||||
|
|
||||||
__vram_start = ORIGIN(vram);
|
__vram_start = ORIGIN(vram);
|
@ -36,7 +36,7 @@ _start:
|
|||||||
bl CopyMem
|
bl CopyMem
|
||||||
|
|
||||||
@ Start ARM9 binary
|
@ Start ARM9 binary
|
||||||
ldr r0, =0x027FFE24
|
ldr r0, =0x02FFFE24
|
||||||
ldr r1, =_arm9_start
|
ldr r1, =_arm9_start
|
||||||
str r1, [r0]
|
str r1, [r0]
|
||||||
|
|
@ -49,7 +49,7 @@
|
|||||||
extern void arm7_clearmem (void* loc, size_t len);
|
extern void arm7_clearmem (void* loc, size_t len);
|
||||||
extern void arm7_reset (void);
|
extern void arm7_reset (void);
|
||||||
|
|
||||||
#define NDS_HEADER 0x027FFE00
|
#define NDS_HEADER 0x02FFFE00
|
||||||
|
|
||||||
#define TMP_DATA 0x02100000
|
#define TMP_DATA 0x02100000
|
||||||
|
|
@ -64,7 +64,7 @@ arm7_reset:
|
|||||||
@ ipcSendState(ARM7_BOOT)
|
@ ipcSendState(ARM7_BOOT)
|
||||||
strh r0, [r12]
|
strh r0, [r12]
|
||||||
|
|
||||||
ldr r0,=0x27FFE34
|
ldr r0,=0x2FFFE34
|
||||||
|
|
||||||
ldr r0,[r0]
|
ldr r0,[r0]
|
||||||
bx r0
|
bx r0
|
@ -100,7 +100,7 @@ arm9_reset:
|
|||||||
@ while (ipcRecvState() != ARM7_BOOT);
|
@ while (ipcRecvState() != ARM7_BOOT);
|
||||||
bl waitsync
|
bl waitsync
|
||||||
|
|
||||||
ldr r10, =0x27FFE24
|
ldr r10, =0x2FFFE24
|
||||||
ldr r2, [r10]
|
ldr r2, [r10]
|
||||||
|
|
||||||
@ Switch MPU to startup default
|
@ Switch MPU to startup default
|
||||||
@ -130,6 +130,6 @@ mpu_initial_data:
|
|||||||
.word 0x08000035 @ p15,0,c6,c3,0,r6 ;PU Protection Unit Data/Unified Region 3
|
.word 0x08000035 @ p15,0,c6,c3,0,r6 ;PU Protection Unit Data/Unified Region 3
|
||||||
.word 0x0300001b @ p15,0,c6,c4,0,r7 ;PU Protection Unit Data/Unified Region 4
|
.word 0x0300001b @ p15,0,c6,c4,0,r7 ;PU Protection Unit Data/Unified Region 4
|
||||||
.word 0xffff001d @ p15,0,c6,c6,0,r8 ;PU Protection Unit Data/Unified Region 6
|
.word 0xffff001d @ p15,0,c6,c6,0,r8 ;PU Protection Unit Data/Unified Region 6
|
||||||
.word 0x027ff017 @ p15,0,c6,c7,0,r9 ;PU Protection Unit Data/Unified Region 7 4KB
|
.word 0x02fff017 @ p15,0,c6,c7,0,r9 ;PU Protection Unit Data/Unified Region 7 4KB
|
||||||
.word 0x0300000a @ p15,0,c9,c1,0,r10 ;TCM Data TCM Base and Virtual Size
|
.word 0x0300000a @ p15,0,c9,c1,0,r10 ;TCM Data TCM Base and Virtual Size
|
||||||
itcm_reset_code_end:
|
itcm_reset_code_end:
|
Loading…
Reference in New Issue
Block a user