Remove A9LH & Brahma support altogether, use FIRM format instead

This commit is contained in:
TuxSH 2017-05-18 01:05:56 +02:00
parent 1d4245e582
commit ab14e77b50
20 changed files with 307 additions and 154 deletions

View File

@ -36,13 +36,13 @@ define bin2o
endef
.PHONY: all
all: a9lh
all: firm
.PHONY: release
release: $(dir_out)/$(name)$(revision).7z
.PHONY: a9lh
a9lh: $(dir_out)/arm9loaderhax.bin
.PHONY: firm
firm: $(dir_out)/boot.firm
.PHONY: clean
clean:
@ -63,12 +63,9 @@ $(dir_out)/$(name)$(revision).7z: all
@mkdir -p "$(@D)"
@7z a -mx $@ ./$(@D)/* ./$(dir_exceptions)/exception_dump_parser.py
$(dir_out)/arm9loaderhax.bin: $(dir_build)/main.bin
$(dir_out)/boot.firm: $(dir_build)/main.elf
@mkdir -p "$(@D)"
@cp -a $(dir_build)/main.bin $@
$(dir_build)/main.bin: $(dir_build)/main.elf
$(OBJCOPY) -S -O binary $< $@
@firmtool build $@ -e 0 -D $^ -C NDMA
$(dir_build)/main.elf: $(bundled) $(objects)
$(LINK.o) -T linker.ld $(OUTPUT_OPTION) $^

View File

@ -28,7 +28,6 @@ enum singleOptions
AUTOBOOTEMU = 0,
USEEMUFIRM,
LOADEXTFIRMSANDMODULES,
USECUSTOMPATH,
PATCHGAMES,
PATCHVERSTRING,
SHOWGBABOOT,

View File

@ -22,15 +22,20 @@
#include "memory.h"
#include "cache.h"
#include "firm.h"
void main(u32 payloadSize)
void main(int argc __attribute__((unused)), char **argv)
{
void *payloadAddress = (void *)0x23F00000;
Firm *firm = (Firm *)0x24000000;
char absPath[92];
memcpy(payloadAddress, (void *)0x24000000, payloadSize);
u32 i;
for(i = 0; i < 91 && argv[1] != 0; i++)
absPath[i] = argv[1][i];
for(; i < 91; i++)
absPath[i] = 0;
//Ensure that all memory transfers have completed and that the caches have been flushed
flushCaches();
char *argvPassed[1] = {absPath};
((void (*)())payloadAddress)();
launchFirm(firm, 1, argvPassed);
}

View File

@ -1,5 +1,5 @@
@ This file is part of Luma3DS
@ Copyright (C) 2016 Aurora Wright, TuxSH
@ Copyright (C) 2017 Aurora Wright, TuxSH
@
@ This program is free software: you can redistribute it and/or modify
@ it under the terms of the GNU General Public License as published by

View File

@ -45,4 +45,4 @@
sdmmc: .ascii "SDMC"
nand_offset: .ascii "NAND" ; For rednand this should be 1
ncsd_header_offset: .ascii "NCSD" ; Depends on nand manufacturer + emunand type (GW/RED)
.close
.close

View File

@ -102,4 +102,4 @@
b die
.pool
.close
.close

View File

@ -2,9 +2,15 @@
.arm.little
payload_addr equ 0x23F00000 ; Brahma payload address
payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeBrah supports)
argv_addr equ 0x27FFDF00
fname_addr equ 0x27FFDF80
low_tid_addr equ 0x27FFDFE0
copy_launch_stub_addr equ 0x27FFE000
firm_addr equ 0x24000000
firm_maxsize equ (copy_launch_stub_addr - 0x1000 - firm_addr)
arm11_entrypoint_addr equ 0x1FFFFFFC
.create "build/reboot.bin", 0
.arm
; Interesting registers and locations to keep in mind, set just before this code is ran:
@ -28,42 +34,41 @@ payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeB
cmp r0, r2
bne pxi_wait_recv
mov r4, #2
; Open file
add r0, r7, #8
adr r1, fname
mov r2, #1
ldr r6, [fopen]
orr r6, 1
blx r6
cmp r0, #0
bne panic
open_payload:
; Open file
add r0, r7, #8
adr r1, fname
mov r2, #1
ldr r6, [fopen]
orr r6, 1
blx r6
cmp r0, #0
beq read_payload
subs r4, r4, #1
beq panic
adr r0, fname
adr r1, nand_mount
mov r2, #8
bl memcpy16
b open_payload
read_payload:
; Read file
mov r0, r7
adr r1, bytes_read
ldr r2, =payload_addr
ldr r3, =payload_maxsize
ldr r6, [r7]
ldr r6, [r6, #0x28]
blx r6
; Read file
mov r0, r7
adr r1, bytes_read
ldr r2, =firm_addr
ldr r3, =firm_maxsize
ldr r6, [r7]
ldr r6, [r6, #0x28]
blx r6
; Copy the low TID (in UTF-16) of the wanted firm to the 5th byte of the payload
ldr r0, =payload_addr + 4
ldr r0, =low_tid_addr
add r1, r8, #0x1A
mov r2, #0x10
bl memcpy16
ldr r0, =fname_addr
adr r1, fname
mov r2, #42
bl memcpy16
ldr r0, =argv_addr
ldr r1, =fname_addr
ldr r2, =low_tid_addr
stmia r0, {r1, r2}
; Set kernel state
mov r0, #0
mov r1, #0
@ -81,12 +86,14 @@ payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeB
b die
memcpy16:
cmp r2, #0
bxeq lr
add r2, r0, r2
copy_loop:
copy_loop16:
ldrh r3, [r1], #2
strh r3, [r0], #2
cmp r0, r2
blo copy_loop
blo copy_loop16
bx lr
panic:
@ -98,7 +105,7 @@ payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeB
bytes_read: .word 0
fopen: .ascii "OPEN"
.pool
fname: .dcw "sdmc:/arm9loaderhax.bin"
fname: .dcw "sdmc:/arm9loaderha.firm"
.word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.pool
nand_mount: .dcw "nand"
@ -106,12 +113,75 @@ nand_mount: .dcw "nand"
.align 4
kernelcode_start:
ldr sp, =0x080FF000
mrs r0, cpsr ; disable interrupts
orr r0, #0xC0
msr cpsr, r0
ldr sp, =0x27FFDF00
ldr r0, =copy_launch_stub_addr
adr r1, copy_launch_stub
mov r2, #(copy_launch_stub_end - copy_launch_stub)
bl memcpy32
; Disable MPU
ldr r0, =0x42078 ; alt vector select, enable itcm
mcr p15, 0, r0, c1, c0, 0
bl flushCaches
ldr r0, =copy_launch_stub_addr
bx r0
copy_launch_stub:
ldr r4, =firm_addr
mov r5, #0
load_section_loop:
; Such checks. Very ghetto. Wow.
add r3, r4, #0x40
add r3, r5,lsl #5
add r3, r5,lsl #4
ldmia r3, {r6-r8}
mov r0, r7
add r1, r4, r6
mov r2, r8
bl memcpy32
add r5, #1
cmp r5, #3
blo load_section_loop
ldr r0, =arm11_entrypoint_addr
ldr r1, [r4, #0x08]
str r1, [r0]
mov r0, #2 ; argc
ldr r1, =argv_addr ; argv
ldr r2, =0xBEEF ; magic word
ldr r5, =arm11_entrypoint_addr
ldr r6, [r4, #0x08]
str r6, [r5]
ldr lr, [r4, #0x0c]
bx lr
memcpy32:
cmp r2, #0
bxeq lr
add r2, r0, r2
copy_loop32:
ldr r3, [r1], #4
str r3, [r0], #4
cmp r0, r2
blo copy_loop32
bx lr
copy_launch_stub_end:
flushCaches:
; Clean and flush data cache
mov r1, #0 ; segment counter
outer_loop:
@ -134,10 +204,7 @@ nand_mount: .dcw "nand"
; Flush instruction cache
mcr p15, 0, r1, c7, c5, 0
; Jump to payload
ldr r0, =payload_addr
bx r0
bx lr
.pool
.close

View File

@ -45,4 +45,4 @@ infoStart:
.word 0 ; truncated commit hash
.word 0 ; config
infoEnd:
.close
.close

View File

@ -24,6 +24,8 @@
* Adapted from 3DBrew and https://github.com/mid-kid/CakesForeveryWan/blob/master/source/headers.h
*/
#pragma once
typedef struct __attribute__((packed))
{
u32 address;
@ -139,7 +141,7 @@ typedef struct __attribute__((packed))
typedef struct __attribute__((packed))
{
u32 magic;
char magic[4];
u32 reserved1;
u8 *arm11Entry;
u8 *arm9Entry;
@ -158,4 +160,4 @@ typedef struct __attribute__((packed))
char magic[4];
u8 reserved2[0xC];
u8 slot0x16keyX[0x10];
} Arm9Bin;
} Arm9Bin;

View File

@ -84,7 +84,6 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
const char *singleOptionsText[] = { "( ) Autoboot EmuNAND",
"( ) Use EmuNAND FIRM if booting with R",
"( ) Enable loading external FIRMs and modules",
"( ) Use custom path",
"( ) Enable game patching",
"( ) Show NAND or user string in System Settings",
"( ) Show GBA boot screen in patched AGB_FIRM",
@ -147,10 +146,6 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
"This isn't needed in most cases.\n\n"
"Refer to the wiki for instructions.",
"Use a custom path for the\n"
"Luma3DS payload.\n\n"
"Refer to the wiki for instructions.",
"Enable overriding the region and\n"
"language configuration and the usage\n"
"of patched code binaries,\n"
@ -195,8 +190,8 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
"Enable Luma3DS's ARM9/ARM11 exception\n"
"handlers.\n"
"A9LH is required, and Luma3DS should\n"
"be ran as arm9loaderhax.bin.\n"
"Luma3DS should be ran as:\n"
"arm9loaderhax.bin\n\n"
"Useful for debugging."
};
@ -226,8 +221,7 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
{ .visible = true },
{ .visible = true },
{ .visible = true },
{ .visible = true },
{ .visible = true}
{ .visible = true }
};
//Calculate the amount of the various kinds of options and pre-select the first single one

View File

@ -30,7 +30,7 @@
#define CONFIG_FILE "config.bin"
#define CONFIG_VERSIONMAJOR 1
#define CONFIG_VERSIONMINOR 10
#define CONFIG_VERSIONMINOR 11
#define BOOTCFG_NAND BOOTCONFIG(0, 7)
#define BOOTCFG_FIRM BOOTCONFIG(3, 7)
@ -50,7 +50,6 @@ enum singleOptions
AUTOBOOTEMU = 0,
USEEMUFIRM,
LOADEXTFIRMSANDMODULES,
USECUSTOMPATH,
PATCHGAMES,
PATCHVERSTRING,
SHOWGBABOOT,

View File

@ -230,7 +230,7 @@ static void aes_batch(void *dst, const void *src, u32 blockCount)
}
}
static void aes(void *dst, const void *src, u32 blockCount, void *iv, u32 mode, u32 ivMode)
void aes(void *dst, const void *src, u32 blockCount, void *iv, u32 mode, u32 ivMode)
{
*REG_AESCNT = mode |
AES_CNT_INPUT_ORDER | AES_CNT_OUTPUT_ORDER |
@ -278,10 +278,8 @@ static void sha_wait_idle()
while(*REG_SHA_CNT & 1);
}
static void sha(void *res, const void *src, u32 size, u32 mode)
void sha(void *res, const void *src, u32 size, u32 mode)
{
backupAndRestoreShaHash(false);
sha_wait_idle();
*REG_SHA_CNT = mode | SHA_CNT_OUTPUT_ENDIAN | SHA_NORMAL_ROUND;
@ -571,21 +569,3 @@ void computePinHash(u8 *outbuf, const u8 *inbuf)
aes(cipherText, inbuf, 1, cid, AES_CBC_ENCRYPT_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
sha(outbuf, cipherText, sizeof(cipherText), SHA_256_MODE);
}
void backupAndRestoreShaHash(bool isRestore)
{
if(ISSIGHAX) return;
static bool didShaHashBackup = false;
__attribute__((aligned(4))) static u8 shaHashBackup[SHA_256_HASH_SIZE];
if(isRestore)
{
if(didShaHashBackup) memcpy((void *)REG_SHA_HASH, shaHashBackup, sizeof(shaHashBackup));
}
else if(!didShaHashBackup)
{
memcpy(shaHashBackup, (void *)REG_SHA_HASH, sizeof(shaHashBackup));
didShaHashBackup = true;
}
}

View File

@ -107,6 +107,9 @@
extern u32 emuOffset;
extern FirmwareSource firmSource;
void aes(void *dst, const void *src, u32 blockCount, void *iv, u32 mode, u32 ivMode);
void sha(void *res, const void *src, u32 size, u32 mode);
void ctrNandInit(void);
int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf);
int ctrNandWrite(u32 sector, u32 sectorCount, const u8 *inbuf);
@ -114,4 +117,3 @@ bool decryptExeFs(Cxi *cxi);
bool decryptNusFirm(const Ticket *ticket, Cxi *cxi, u32 ncchSize);
void kernel9Loader(Arm9Bin *arm9Section);
void computePinHash(u8 *outbuf, const u8 *inbuf);
void backupAndRestoreShaHash(bool isRestore);

View File

@ -35,8 +35,6 @@
#include "fmt.h"
#include "../build/bundled.h"
static Firm *firm = (Firm *)0x24000000;
static inline bool loadFirmFromStorage(FirmwareType firmType)
{
const char *firmwareFiles[] = {

View File

@ -23,6 +23,9 @@
#pragma once
#include "types.h"
#include "3dsheaders.h"
static Firm *const firm = (Firm *const)0x24000000;
u32 loadFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadFromStorage, bool isSafeMode);
u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isSafeMode, bool doUnitinfoPatch, bool enableExceptionHandlers);

View File

@ -32,6 +32,8 @@
#include "config.h"
#include "fatfs/ff.h"
#include "buttons.h"
#include "firm.h"
#include "crypto.h"
#include "../build/bundled.h"
static FATFS sdFs,
@ -116,12 +118,80 @@ void fileDelete(const char *path)
f_unlink(path);
}
static __attribute__((noinline)) bool overlaps(u32 as, u32 ae, u32 bs, u32 be)
{
if (as <= bs && bs <= ae)
return true;
else if (bs <= as && as <= be)
return true;
return false;
}
static bool checkFirmPayload(void)
{
if(memcmp(firm->magic, "FIRM", 4) != 0)
return false;
if(firm->arm9Entry == NULL) //allow for the arm11 entrypoint to be zero in which case nothing is done on the arm11 side
return false;
u32 size = 0x200;
for(u32 i = 0; i < 4; i++)
size += firm->section[i].size;
bool arm9EpFound = false, arm11EpFound = false;
for(u32 i = 0; i < 4; i++)
{
__attribute__((aligned(4))) u8 hash[0x20];
FirmSection *section = &firm->section[i];
// allow empty sections
if (section->size == 0)
continue;
if(section->offset < 0x200)
return false;
if(section->address + section->size < section->address) //overflow check
return false;
if(((u32)section->address & 3) || (section->offset & 0x1FF) || (section->size & 0x1FF)) //alignment check
return false;
if(overlaps((u32)section->address, (u32)section->address + section->size, 0x27FFE000, 0x28000000))
return false;
else if(overlaps((u32)section->address, (u32)section->address + section->size, 0x27FFE000 - 0x1000, 0x27FFE000))
return false;
else if(overlaps((u32)section->address, (u32)section->address + section->size, (u32)firm, (u32)firm + size))
return false;
sha(hash, (u8 *)firm + section->offset, section->size, SHA_256_MODE);
if(memcmp(hash, section->hash, 0x20) != 0)
return false;
if(firm->arm9Entry >= section->address && firm->arm9Entry < (section->address + section->size))
arm9EpFound = true;
if(firm->arm11Entry >= section->address && firm->arm11Entry < (section->address + section->size))
arm11EpFound = true;
}
return arm9EpFound && (firm->arm11Entry == NULL || arm11EpFound);
}
void loadPayload(u32 pressed, const char *payloadPath)
{
u32 *loaderAddress = (u32 *)0x27FFE000;
u8 *payloadAddress = (u8 *)0x24000000;
u32 payloadSize = 0,
maxPayloadSize = 0xFFE00;
maxPayloadSize = (u32)((u8 *)loaderAddress - (u8 *)firm);
char path[62] = {0},
absPath[92] = {0};
char mountPoint[5] = {0};
for(u32 i = 0; i < 4 && launchedPath[i] != ':'; i++)
mountPoint[i] = launchedPath[i];
if(payloadPath == NULL)
{
@ -142,7 +212,6 @@ void loadPayload(u32 pressed, const char *payloadPath)
DIR dir;
FILINFO info;
FRESULT result;
char path[22];
result = f_findfirst(&dir, &info, "payloads", pattern);
@ -153,24 +222,36 @@ void loadPayload(u32 pressed, const char *payloadPath)
if(!info.fname[0]) return;
sprintf(path, "payloads/%s", info.altname);
payloadSize = fileRead(payloadAddress, path, maxPayloadSize);
}
else payloadSize = fileRead(payloadAddress, payloadPath, maxPayloadSize);
if(memcmp(mountPoint, "nand", 4))
sprintf(absPath, "nand:/rw/luma/payloads/%s", info.altname);
else
sprintf(absPath, "%s:/luma/payloads/%s", mountPoint, info.altname);
if(!payloadSize) return;
payloadSize = fileRead(firm, path, maxPayloadSize);
}
else
{
if(memcmp(mountPoint, "nand", 4))
sprintf(absPath, "nand:/rw/luma/payloads/%s", payloadPath);
else
sprintf(absPath, "%s:/luma/payloads/%s", mountPoint, payloadPath);
payloadSize = fileRead(firm, payloadPath, maxPayloadSize);
}
if(!payloadSize || !checkFirmPayload()) return;
writeConfig(true);
char *argv[1] = {absPath};
memcpy(loaderAddress, loader_bin, loader_bin_size);
if(ISN3DS) kernel9Loader(NULL);
backupAndRestoreShaHash(true);
initScreens();
flushDCacheRange(loaderAddress, loader_bin_size);
flushICacheRange(loaderAddress, loader_bin_size);
((void (*)(u32))loaderAddress)(payloadSize);
((void (*)(int, char **, u32))loaderAddress)(1, argv, 0x0000BEEF);
}
void payloadMenu(void)
@ -190,11 +271,11 @@ void payloadMenu(void)
u32 nameLength = strlen(info.fname);
if(nameLength < 5 || nameLength > 52) continue;
if(nameLength < 6 || nameLength > 52) continue;
nameLength -= 4;
nameLength -= 5;
if(memcmp(info.fname + nameLength, ".bin", 4) != 0) continue;
if(memcmp(info.fname + nameLength, ".firm", 5) != 0) continue;
memcpy(payloadList[payloadNum], info.fname, nameLength);
payloadList[payloadNum][nameLength] = 0;
@ -258,7 +339,7 @@ void payloadMenu(void)
if(pressed != BUTTON_START)
{
sprintf(path, "payloads/%s.bin", payloadList[selectedPayload]);
sprintf(path, "payloads/%s.firm", payloadList[selectedPayload]);
loadPayload(0, path);
error("The payload is too large or corrupted.");
}

View File

@ -32,12 +32,16 @@
#include "pin.h"
#include "crypto.h"
#include "fmt.h"
#include "memory.h"
extern CfgData configData;
extern ConfigurationStatus needConfig;
extern FirmwareSource firmSource;
void main(void)
u16 launchedFirmTidLow[8];
u16 launchedPath[42];
void main(int argc, char **argv)
{
bool isSafeMode = false,
isNoForceFlagSet = false;
@ -45,15 +49,59 @@ void main(void)
FirmwareType firmType;
FirmwareSource nandType;
switch(argc)
{
case 0:
error("Unsupported launcher.");
break;
case 1: //Normal boot
{
u32 i;
for(i = 0; i < 41 && launchedPath[i] != 0; i++) //Copy and convert the path to utf16
launchedPath[2 * i] = argv[0][i];
for(; i < 41; i++)
launchedPath[i] = 0;
for(u32 i = 0; i < 8; i++)
launchedFirmTidLow[i] = 0;
break;
}
case 2: //Firmlaunch
{
u32 i;
u16 *p = (u16 *)argv[0];
for(i = 0; i < 41 && launchedPath[i] != 0; i++)
launchedPath[i] = p[i];
for(; i < 41; i++)
launchedPath[i] = 0;
memcpy(launchedFirmTidLow, (u16 *)argv[1], 16);
break;
}
}
char mountPoint[5] = {0};
for(u32 i = 0; i < 4 && argv[0][i] != ':'; i++)
mountPoint[i] = argv[0][i];
//Mount SD or CTRNAND
bool isSdMode;
if(mountFs(true, false)) isSdMode = true;
else
if(memcmp(mountPoint, "sdmc", 4) == 0)
{
if(!mountFs(true, false)) error("Failed to mount SD.");
isSdMode = true;
}
else if(memcmp(mountPoint, "nand", 4) == 0)
{
firmSource = FIRMWARE_SYSNAND;
if(!mountFs(false, true)) error("Failed to mount SD and CTRNAND.");
isSdMode = false;
}
else
error("Launched from an unsupported location");
//Attempt to read the configuration file
needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION;

View File

@ -37,30 +37,6 @@
#include "utils.h"
#include "../build/bundled.h"
static inline void pathChanger(u8 *pos)
{
const char *pathFile = "path.txt";
u8 path[57];
u32 pathSize = fileRead(path, pathFile, sizeof(path));
if(pathSize < 6) return;
if(path[pathSize - 1] == 0xA) pathSize--;
if(path[pathSize - 1] == 0xD) pathSize--;
if(pathSize < 6 || pathSize > 55 || path[0] != '/' || memcmp(path + pathSize - 4, ".bin", 4) != 0) return;
u16 finalPath[56];
for(u32 i = 0; i < pathSize; i++)
finalPath[i] = (u16)path[i];
finalPath[pathSize] = 0;
u8 *posPath = memsearch(pos, u"sd", reboot_bin_size, 4) + 0xA;
memcpy(posPath, finalPath, (pathSize + 1) * 2);
}
u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
{
u8 *temp = memsearch(pos, "NCCH", size, 4);
@ -159,7 +135,8 @@ u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr)
u32 *pos_fopen = (u32 *)memsearch(off, "OPEN", reboot_bin_size, 4);
*pos_fopen = fOpenOffset;
if(CONFIG(USECUSTOMPATH)) pathChanger(off);
//u16 *fname = (u16 *)memsearch(off, u"sd", reboot_bin_size, 4);
//memcpy(fname, u"sdmc:/test.firm", 32);
return 0;
}

View File

@ -24,32 +24,31 @@
.align 4
.global _start
_start:
b start
.global launchedFirmTidLow
launchedFirmTidLow:
.hword 0, 0, 0, 0, 0, 0, 0, 0
start:
@ Disable interrupts
mrs r0, cpsr
orr r0, #0x1C0
msr cpsr_cx, r0
mrs r4, cpsr
orr r4, #0x1C0
msr cpsr_cx, r4
ldr r4, =0xBEEF
cmp r2, r4
movne r0, #0 @ check magic word
@ Change the stack pointer
mov sp, #0x27000000
@ Disable caches / MPU
mrc p15, 0, r0, c1, c0, 0 @ read control register
bic r0, #(1<<12) @ - instruction cache disable
bic r0, #(1<<2) @ - data cache disable
bic r0, #(1<<0) @ - mpu disable
mcr p15, 0, r0, c1, c0, 0 @ write control register
mrc p15, 0, r4, c1, c0, 0 @ read control register
bic r4, #(1<<12) @ - instruction cache disable
bic r4, #(1<<2) @ - data cache disable
bic r4, #(1<<0) @ - mpu disable
mcr p15, 0, r4, c1, c0, 0 @ write control register
@ Flush caches
bl flushEntireDCache
bl flushEntireICache
push {r0-r3}
@ Give read/write access to all the memory regions
ldr r0, =0x3333333
mcr p15, 0, r0, c5, c0, 2 @ write data access
@ -98,4 +97,5 @@ start:
sub r2, r0
bl memset32
pop {r0-r3}
b main

View File

@ -115,4 +115,5 @@ typedef enum FirmwareType
NATIVE_FIRM1X2X
} FirmwareType;
extern u16 launchedFirmTidLow[8]; //Defined in start.s
extern u16 launchedFirmTidLow[8];
extern u16 launchedPath[42];