Compare commits

...

10 Commits

Author SHA1 Message Date
Aurora Wright
d55a454b15 Minor stuff 2017-04-17 03:31:00 +02:00
Aurora Wright
2b686a4de7 Update submodules 2017-01-26 04:18:16 +01:00
Aurora
64b1eefc5d Include base_tools instead of specifying binaries manually 2016-11-26 18:06:56 +01:00
Aurora
c77746f383 Try new stuff 2016-11-26 00:53:07 +01:00
Aurora
5d1c717cb4 Backup existing arm9loaderhax.bin 2016-11-23 00:03:45 +01:00
Aurora
bccdfe4404 Fix derp 2016-11-22 23:54:32 +01:00
Aurora
04a33143b7 Added warning if deletion fails 2016-11-22 23:39:26 +01:00
Aurora
2be5a24262 Move magic to the payload again 2016-11-22 23:13:21 +01:00
Aurora
7067c6d0e8 Clearer this way 2016-11-22 22:50:40 +01:00
Aurora
b1d596177a Change OTPless installation approach 2016-11-22 22:45:14 +01:00
34 changed files with 631 additions and 930 deletions

@ -1 +1 @@
Subproject commit 9f7cea77d4db4d743e45b2e5193df76ffed0a571
Subproject commit 1efda4e89476d34aeb307e0acd7a8dbcd1344601

@ -1 +1 @@
Subproject commit 5245c7b9dc232956a8578a36468f9024d8cf7001
Subproject commit 329212a8e09d4718e304cb9d94a0e10f66d9813d

View File

@ -4,19 +4,12 @@ ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/3ds_rules
CC := arm-none-eabi-gcc
AS := arm-none-eabi-as
LD := arm-none-eabi-ld
OC := arm-none-eabi-objcopy
include $(DEVKITARM)/base_tools
name := SafeA9LHInstaller
revision := $(shell git describe --tags --match v[0-9]* --abbrev=8 | sed 's/-[0-9]*-g/-/i')
dir_source := source
dir_loader := loader
dir_arm11 := arm11
dir_cakehax := CakeHax
dir_cakebrah := CakeBrah
dir_build := build
@ -31,14 +24,6 @@ objects= $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
$(call rwildcard, $(dir_source), *.s *.c)))
bundled = $(dir_build)/loader.bin.o $(dir_build)/arm11.bin.o
define bin2o
bin2s $< | $(AS) -o $(@)
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> $(dir_build)/bundled.h
echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> $(dir_build)/bundled.h
endef
.PHONY: all
all: launcher a9lh cakebrah
@ -56,8 +41,6 @@ release: $(dir_out)/$(name)$(revision).7z
.PHONY: clean
clean:
@$(MAKE) -C $(dir_loader) clean
@$(MAKE) -C $(dir_arm11) clean
@$(MAKE) $(FLAGS) -C $(dir_cakehax) clean
@$(MAKE) $(FLAGS) -C $(dir_cakebrah) clean
@rm -rf $(dir_out) $(dir_build)
@ -81,20 +64,11 @@ $(dir_out)/$(name)$(revision).7z: all
@7z a -mx $@ ./$(@D)/*
$(dir_build)/main.bin: $(dir_build)/main.elf
$(OC) -S -O binary $< $@
$(OBJCOPY) -S -O binary $< $@
$(dir_build)/main.elf: $(bundled) $(objects)
$(dir_build)/main.elf: $(objects)
$(LINK.o) -T linker.ld $(OUTPUT_OPTION) $^
$(dir_build)/%.bin.o: $(dir_build)/%.bin
@$(bin2o)
$(dir_build)/loader.bin: $(dir_loader) $(dir_build)
@$(MAKE) -C $<
$(dir_build)/arm11.bin: $(dir_arm11) $(dir_build)
@$(MAKE) -C $<
$(dir_build)/memory.o $(dir_build)/strings.o: CFLAGS += -O3
$(dir_build)/installer.o: CFLAGS += -DTITLE="\"$(name) $(revision)\""
@ -105,4 +79,3 @@ $(dir_build)/%.o: $(dir_source)/%.c
$(dir_build)/%.o: $(dir_source)/%.s
@mkdir -p "$(@D)"
$(COMPILE.s) $(OUTPUT_OPTION) $<
include $(call rwildcard, $(dir_build), *.d)

View File

@ -3,6 +3,7 @@
**Usage / Features:**
*DO NOT USE THIS VERSION TO INSTALL ON NEW 3DS UNLESS YOU HAVE AN HARDMOD, CAUSES RANDOM BRICKS! UNINSTALLATION IS FINE*
For a comprehensive guide to installing A9LH and to 3DS hacking in general, refer to [Plailect's guide](https://github.com/Plailect/Guide/wiki/Get-Started).
For other details about the program, refer to the [GBATemp thread](http://gbatemp.net/threads/safea9lhinstaller.419577/).

View File

@ -1,48 +0,0 @@
rwildcard = $(foreach d, $(wildcard $1*), $(filter $(subst *, %, $2), $d) $(call rwildcard, $d/, $2))
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/3ds_rules
CC := arm-none-eabi-gcc
AS := arm-none-eabi-as
LD := arm-none-eabi-ld
OC := arm-none-eabi-objcopy
name := $(shell basename $(CURDIR))
dir_source := source
dir_build := build
dir_out := ../$(dir_build)
ASFLAGS := -mcpu=mpcore -mfloat-abi=hard
CFLAGS := -Wall -Wextra -MMD -MP -mthumb -mthumb-interwork $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math
LDFLAGS := -nostdlib
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
$(call rwildcard, $(dir_source), *.s *.c)))
.PHONY: all
all: $(dir_out)/$(name).bin
.PHONY: clean
clean:
@rm -rf $(dir_build)
$(dir_out)/$(name).bin: $(dir_build)/$(name).elf
$(OC) -S -O binary $< $@
$(dir_build)/$(name).elf: $(objects)
$(LINK.o) -T linker.ld $(OUTPUT_OPTION) $^
$(dir_build)/%.o: $(dir_source)/%.c
@mkdir -p "$(@D)"
$(COMPILE.c) $(OUTPUT_OPTION) $<
$(dir_build)/%.o: $(dir_source)/%.s
@mkdir -p "$(@D)"
$(COMPILE.s) $(OUTPUT_OPTION) $<
include $(call rwildcard, $(dir_build), *.d)

View File

@ -1,12 +0,0 @@
ENTRY(_start)
SECTIONS
{
. = 0x1FFF4C80;
.text.start : { *(.text.start) }
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss COMMON) }
.rodata : { *(.rodata) }
. = ALIGN(4);
}

View File

@ -1,15 +0,0 @@
#include "types.h"
void main(void)
{
vu32 *arm11Entry = (vu32 *)0x1FFFFFF8;
//Clear ARM11 entrypoint
*arm11Entry = 0;
//Wait for the entrypoint to be set
while(!*arm11Entry);
//Jump to it
((void (*)())*arm11Entry)();
}

View File

@ -1,8 +0,0 @@
.section .text.start
.align 4
.global _start
_start:
@ Disable interrupts
CPSID aif
b main

View File

@ -1,7 +0,0 @@
#pragma once
#include <stdint.h>
//Common data types
typedef uint32_t u32;
typedef volatile u32 vu32;

View File

@ -1,11 +1,15 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x23F00000;
.text.start : { *(.text.start) }
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss COMMON) }
.rodata : { *(.rodata) }
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
.data : ALIGN(4) { *(.data*); . = ALIGN(4); }
.bss : ALIGN(8) { __bss_start = .; *(.bss* COMMON); . = ALIGN(8); __bss_end = .; }
. = ALIGN(4);
}

View File

@ -1,48 +0,0 @@
rwildcard = $(foreach d, $(wildcard $1*), $(filter $(subst *, %, $2), $d) $(call rwildcard, $d/, $2))
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/3ds_rules
CC := arm-none-eabi-gcc
AS := arm-none-eabi-as
LD := arm-none-eabi-ld
OC := arm-none-eabi-objcopy
name := $(shell basename $(CURDIR))
dir_source := source
dir_build := build
dir_out := ../$(dir_build)
ASFLAGS := -mcpu=arm946e-s
CFLAGS := -Wall -Wextra -MMD -MP -mthumb -mthumb-interwork $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math
LDFLAGS := -nostdlib
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
$(call rwildcard, $(dir_source), *.s *.c)))
.PHONY: all
all: $(dir_out)/$(name).bin
.PHONY: clean
clean:
@rm -rf $(dir_build)
$(dir_out)/$(name).bin: $(dir_build)/$(name).elf
$(OC) -S -O binary $< $@
$(dir_build)/$(name).elf: $(objects)
$(LINK.o) -T linker.ld $(OUTPUT_OPTION) $^
$(dir_build)/%.o: $(dir_source)/%.c
@mkdir -p "$(@D)"
$(COMPILE.c) $(OUTPUT_OPTION) $<
$(dir_build)/%.o: $(dir_source)/%.s
@mkdir -p "$(@D)"
$(COMPILE.s) $(OUTPUT_OPTION) $<
include $(call rwildcard, $(dir_build), *.d)

View File

@ -1,11 +0,0 @@
ENTRY(_start)
SECTIONS
{
. = 0x1FF8000;
.text.start : { *(.text.start) }
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss COMMON) }
.rodata : { *(.rodata) }
. = ALIGN(4);
}

View File

@ -1,35 +0,0 @@
/*
* This file is part of Luma3DS
* Copyright (C) 2016 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
*/
#include "types.h"
void main(void)
{
vu32 *payloadAddress = (vu32 *)0x23F00000;
payloadAddress[1] = 0xDEADCAFE;
//Ensure that all memory transfers have completed and that the caches have been flushed
((void (*)())0xFFFF0830)();
((void (*)())0xFFFF0AB4)();
((void (*)())payloadAddress)();
}

View File

@ -1,87 +0,0 @@
@ This file is part of Luma3DS
@ Copyright (C) 2016 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
@ the Free Software Foundation, either version 3 of the License, or
@ (at your option) any later version.
@
@ This program is distributed in the hope that it will be useful,
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ GNU General Public License for more details.
@
@ You should have received a copy of the GNU General Public License
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
@
@ Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
@ reasonable legal notices or author attributions in that material or in the Appropriate Legal
@ Notices displayed by works containing it.
@ Thanks to the numerous people who took part in writing this file
.section .text.start
.align 4
.global _start
_start:
@ Disable interrupts
mrs r0, cpsr
orr r0, #0x1C0
msr cpsr_cx, r0
@ 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
@ Give read/write access to all the memory regions
ldr r0, =0x3333333
mcr p15, 0, r0, c5, c0, 2 @ write data access
mcr p15, 0, r0, c5, c0, 3 @ write instruction access
@ Set MPU permissions and cache settings
ldr r0, =0xFFFF001D @ ffff0000 32k | bootrom (unprotected part)
ldr r1, =0x01FF801D @ 01ff8000 32k | itcm
ldr r2, =0x08000029 @ 08000000 2M | arm9 mem (O3DS / N3DS)
ldr r3, =0x10000029 @ 10000000 2M | io mem (ARM9 / first 2MB)
ldr r4, =0x20000037 @ 20000000 256M | fcram (O3DS / N3DS)
ldr r5, =0x1FF00027 @ 1FF00000 1M | dsp / axi wram
ldr r6, =0x1800002D @ 18000000 8M | vram (+ 2MB)
mov r7, #0
mov r8, #0x15
mcr p15, 0, r0, c6, c0, 0
mcr p15, 0, r1, c6, c1, 0
mcr p15, 0, r2, c6, c2, 0
mcr p15, 0, r3, c6, c3, 0
mcr p15, 0, r4, c6, c4, 0
mcr p15, 0, r5, c6, c5, 0
mcr p15, 0, r6, c6, c6, 0
mcr p15, 0, r7, c6, c7, 0
mcr p15, 0, r8, c3, c0, 0 @ Write bufferable 0, 2, 4
mcr p15, 0, r8, c2, c0, 0 @ Data cacheable 0, 2, 4
mcr p15, 0, r8, c2, c0, 1 @ Inst cacheable 0, 2, 4
@ Flush caches
ldr r0, =0xFFFF0830
blx r0
ldr r0, =0xFFFF0AB4
blx r0
@ Enable caches / MPU
mrc p15, 0, r0, c1, c0, 0 @ read control register
orr r0, r0, #(1<<12) @ - instruction cache enable
orr r0, r0, #(1<<2) @ - data cache enable
orr r0, r0, #(1<<0) @ - mpu enable
mcr p15, 0, r0, c1, c0, 0 @ write control register
@ Fix mounting of SDMC
ldr r0, =0x10000020
mov r1, #0x340
str r1, [r0]
b main

View File

@ -1,35 +0,0 @@
/*
* This file is part of Luma3DS
* Copyright (C) 2016 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
*/
#pragma once
#include <stdint.h>
//Common data types
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef volatile u8 vu8;
typedef volatile u16 vu16;
typedef volatile u32 vu32;
typedef volatile u64 vu64;

View File

@ -277,10 +277,10 @@ static u8 nandSlot;
static u32 fatStart;
__attribute__((aligned(4))) const u8 key2s[5][AES_BLOCK_SIZE] = {
{0x42, 0x3F, 0x81, 0x7A, 0x23, 0x52, 0x58, 0x31, 0x6E, 0x75, 0x8E, 0x3A, 0x39, 0x43, 0x2E, 0xD0},
{0x08, 0x24, 0xD3, 0xCB, 0x4A, 0xE9, 0x4D, 0x62, 0x4D, 0xAA, 0x52, 0x60, 0x47, 0xC5, 0x93, 0x94},
{0xA5, 0x25, 0x87, 0x11, 0x8F, 0x42, 0x9F, 0x3D, 0x65, 0x1D, 0xDD, 0x58, 0x0B, 0x6D, 0xF2, 0x17},
{0x65, 0x29, 0x3E, 0x12, 0x56, 0x0C, 0x0B, 0xD1, 0xDD, 0xB5, 0x63, 0x1C, 0xB6, 0xD9, 0x52, 0x75},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3B, 0xF5, 0xF6},
{0xA5, 0x25, 0x87, 0x11, 0x8F, 0x42, 0x9F, 0x3D, 0x65, 0x1D, 0xDD, 0x58, 0x0B, 0x6D, 0xF2, 0x17}
{0x08, 0x24, 0xD3, 0xCB, 0x4A, 0xE9, 0x4D, 0x62, 0x4D, 0xAA, 0x52, 0x60, 0x47, 0xC5, 0x93, 0x94}
},
devKey2s[2][AES_BLOCK_SIZE] = {
{0xFF, 0x77, 0xA0, 0x9A, 0x99, 0x81, 0xE9, 0x48, 0xEC, 0x51, 0xC9, 0x32, 0x5D, 0x14, 0xEC, 0x25},
@ -381,24 +381,21 @@ void generateSector(u8 *keySector, u32 mode)
//Inject key2
switch(mode)
{
case 0:
memcpy(keySector + AES_BLOCK_SIZE, !ISDEVUNIT ? key2s[1] : devKey2s[1], AES_BLOCK_SIZE);
break;
case 1:
memcpy(keySector + AES_BLOCK_SIZE, keySector, AES_BLOCK_SIZE);
break;
return;
case 2:
memcpy(keySector + AES_BLOCK_SIZE, !ISDEVUNIT ? key2s[0] : devKey2s[0], AES_BLOCK_SIZE);
break;
default:
memcpy(keySector + AES_BLOCK_SIZE, !ISDEVUNIT ? key2s[1] : devKey2s[1], AES_BLOCK_SIZE);
break;
}
if(mode != 1)
{
//Encrypt key sector
aes_use_keyslot(0x11);
for(u32 i = 0; i < 32; i++)
aes(keySector + (AES_BLOCK_SIZE * i), keySector + (AES_BLOCK_SIZE * i), 1, NULL, AES_ECB_ENCRYPT_MODE, 0);
}
}
void getSector(u8 *keySector)
@ -406,13 +403,12 @@ void getSector(u8 *keySector)
//Read keysector from NAND
sdmmc_nand_readsectors(0x96, 1, keySector);
if(ISA9LH || ISDEVUNIT)
{
if(!ISA9LH && !ISDEVUNIT) return;
//Decrypt key sector
aes_use_keyslot(0x11);
for(u32 i = 0; i < 32; i++)
aes(keySector + (AES_BLOCK_SIZE * i), keySector + (AES_BLOCK_SIZE * i), 1, NULL, AES_ECB_DECRYPT_MODE, 0);
}
}
bool verifyHash(const void *data, u32 size, const u8 *hash)
@ -427,8 +423,8 @@ u32 decryptExeFs(Cxi *cxi)
{
u32 exeFsSize = 0;
if(memcmp(cxi->ncch.magic, "NCCH", 4) == 0)
{
if(memcmp(cxi->ncch.magic, "NCCH", 4) != 0) return exeFsSize;
u8 *exeFsOffset = (u8 *)cxi + (cxi->ncch.exeFsOffset + 1) * 0x200;
exeFsSize = (cxi->ncch.exeFsSize - 1) * 0x200;
__attribute__((aligned(4))) u8 ncchCtr[AES_BLOCK_SIZE] = {0};
@ -443,7 +439,6 @@ u32 decryptExeFs(Cxi *cxi)
aes(cxi, exeFsOffset, exeFsSize / AES_BLOCK_SIZE, ncchCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
if(memcmp(cxi, "FIRM", 4) != 0) exeFsSize = 0;
}
return exeFsSize;
}

13
source/fatfs/00history.txt Executable file → Normal file
View File

@ -212,7 +212,7 @@ R0.10a (January 15, 2014)
R0.10b (May 19, 2014)
Fixed a hard error in the disk I/O layer can collapse the directory entry.
Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN. (appeared at R0.07)
Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07)
@ -268,7 +268,7 @@ R0.12a (July 10, 2016)
R0.12b (September 04, 2016)
Improved f_rename() to be able to rename objects with the same name but case.
Made f_rename() be able to rename objects with the same name but case.
Fixed an error in the case conversion teble of code page 866. (ff.c)
Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
@ -277,3 +277,12 @@ R0.12b (September 04, 2016)
Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)
R0.12c (March 04, 2017)
Improved write throughput at the fragmented file on the exFAT volume.
Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)

16
source/fatfs/00readme.txt Executable file → Normal file
View File

@ -1,21 +1,21 @@
FatFs Module Source Files R0.12a
FatFs Module Source Files R0.12c
FILES
00readme.txt This file.
history.txt Revision history.
ffconf.h Configuration file for FatFs module.
ff.h Common include file for FatFs and application module.
00history.txt Revision history.
ff.c FatFs module.
ffconf.h Configuration file of FatFs module.
ff.h Common include file for FatFs and application module.
diskio.h Common include file for FatFs and disk I/O module.
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
integer.h Integer type definitions for FatFs.
option Optional external functions.
option Optional external modules.
Low level disk I/O module is not included in this archive because the FatFs
module is only a generic file system layer and not depend on any specific
storage device. You have to provide a low level disk I/O module that written
to control the target storage device.
module is only a generic file system layer and it does not depend on any specific
storage device. You have to provide a low level disk I/O module written to
control the storage device that attached to the target system.

661
source/fatfs/ff.c Executable file → Normal file

File diff suppressed because it is too large Load Diff

25
source/fatfs/ff.h Executable file → Normal file
View File

@ -1,8 +1,8 @@
/*----------------------------------------------------------------------------/
/ FatFs - Generic FAT file system module R0.12b /
/ FatFs - Generic FAT file system module R0.12c /
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2016, ChaN, all right reserved.
/ Copyright (C) 2017, ChaN, all right reserved.
/
/ FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided
@ -19,7 +19,7 @@
#ifndef _FATFS
#define _FATFS 68020 /* Revision ID */
#define _FATFS 68300 /* Revision ID */
#ifdef __cplusplus
extern "C" {
@ -42,13 +42,6 @@ typedef struct {
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
} PARTITION;
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */
#else /* Single partition configuration */
#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */
#define LD2PT(vol) 0 /* Find first valid partition or in SFD */
#endif
@ -140,14 +133,15 @@ typedef struct {
FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
BYTE attr; /* Object attribute */
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:got flagmented, b2:sub-directory stretched) */
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:flagmented in this session, b2:sub-directory stretched) */
DWORD sclust; /* Object start cluster (0:no cluster or root directory) */
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
#if _FS_EXFAT
DWORD n_cont; /* Size of coutiguous part, clusters - 1 (valid when stat == 3) */
DWORD n_cont; /* Size of first fragment, clusters - 1 (valid when stat == 3) */
DWORD n_frag; /* Size of last fragment needs to be written (valid when not zero) */
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0) */
DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0 and non-directory object) */
#endif
#if _FS_LOCK != 0
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
@ -163,7 +157,7 @@ typedef struct {
BYTE flag; /* File status flags */
BYTE err; /* Abort flag (error code) */
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
DWORD clust; /* Current cluster of fpter (invalid when fprt is 0) */
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
#if !_FS_READONLY
DWORD dir_sect; /* Sector number containing the directory entry */
@ -185,7 +179,7 @@ typedef struct {
_FDID obj; /* Object identifier */
DWORD dptr; /* Current read/write offset */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector */
DWORD sect; /* Current sector (0:Read operation has terminated) */
BYTE* dir; /* Pointer to the directory item in the win[] */
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
#if _USE_LFN != 0
@ -285,6 +279,7 @@ TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the fil
#define f_size(fp) ((fp)->obj.objsize)
#define f_rewind(fp) f_lseek((fp), 0)
#define f_rewinddir(dp) f_readdir((dp), 0)
#define f_rmdir(path) f_unlink(path)
#ifndef EOF
#define EOF (-1)

21
source/fatfs/ffconf.h Executable file → Normal file
View File

@ -2,7 +2,7 @@
/ FatFs - FAT file system module configuration file
/---------------------------------------------------------------------------*/
#define _FFCONF 68020 /* Revision ID */
#define _FFCONF 68300 /* Revision ID */
/*---------------------------------------------------------------------------/
/ Function Configurations
@ -73,7 +73,7 @@
/* This option specifies the OEM code page to be used on the target system.
/ Incorrect setting of the code page can cause a file open failure.
/
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
/ 1 - ASCII (No support of extended character. Non-LFN cfg. only)
/ 437 - U.S.
/ 720 - Arabic
/ 737 - Greek
@ -148,7 +148,7 @@
/---------------------------------------------------------------------------*/
#define _VOLUMES 2
/* Number of volumes (logical drives) to be used. */
/* Number of volumes (logical drives) to be used. (1-10) */
#define _STR_VOLUME_ID 0
@ -172,11 +172,11 @@
#define _MIN_SS 512
#define _MAX_SS 512
/* These options configure the range of sector size to be supported. (512, 1024,
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
/ 2048 or 4096) Always set both 512 for most systems, generic memory card and
/ harddisk. But a larger value may be required for on-board flash memory and some
/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
/ disk_ioctl() function. */
/ to variable sector size and GET_SECTOR_SIZE command needs to be implemented to
/ the disk_ioctl() function. */
#define _USE_TRIM 0
@ -204,7 +204,7 @@
#define _FS_TINY 0
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/ At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes.
/ At the tiny configuration, size of file object (FIL) is shrinked _MAX_SS bytes.
/ Instead of private sector buffer eliminated from the file object, common sector
/ buffer in the file system object (FATFS) is used for the file data transfer. */
@ -212,13 +212,13 @@
#define _FS_EXFAT 0
/* This option switches support of exFAT file system. (0:Disable or 1:Enable)
/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1)
/ Note that enabling exFAT discards C89 compatibility. */
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
#define _FS_NORTC 1
#define _NORTC_MON 1
#define _NORTC_MDAY 1
#define _NORTC_YEAR 2016
#define _NORTC_YEAR 2017
/* The option _FS_NORTC switches timestamp functiton. If the system does not have
/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
@ -258,10 +258,11 @@
/
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.h. */
/* #include <windows.h> // O/S definitions */
/*--- End of configuration options ---*/

2
source/fatfs/integer.h Executable file → Normal file
View File

@ -30,7 +30,7 @@ typedef unsigned short WCHAR;
typedef long LONG;
typedef unsigned long DWORD;
/* This type MUST be 64-bit (Remove this for C89 compatibility) */
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
typedef unsigned long long QWORD;
#endif

0
source/fatfs/option/ccsbcs.c Executable file → Normal file
View File

View File

@ -472,10 +472,11 @@ void sdmmc_get_cid(bool isNand, u32 *info)
sdmmc_send_command(device, 0x10507, device->initarg << 0x10);
}
bool sdmmc_sdcard_init(bool isOtpless)
bool sdmmc_sdcard_init(bool initSd, bool initNand)
{
InitSD();
int nand_ret = Nand_Init();
if(isOtpless) return true;
return (nand_ret | SD_Init()) == 0;
int ret = 0;
if(initNand) ret |= Nand_Init();
if(initSd) ret |= SD_Init();
return ret == 0;
}

View File

@ -91,7 +91,7 @@ typedef struct mmcdevice {
u32 res;
} mmcdevice;
bool sdmmc_sdcard_init(bool isOtpless);
bool sdmmc_sdcard_init(bool initSd, bool initNand);
int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, u8 *out);
int sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, const u8 *in);
int sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, u8 *out);

View File

@ -32,24 +32,17 @@ bool mountFs(bool isSd)
return isSd ? f_mount(&fs, "0:", 1) == FR_OK : f_mount(&fs, "1:", 1) == FR_OK;
}
void unmountCtrNand(void)
{
f_mount(NULL, "1:", 1);
}
u32 fileRead(void *dest, const char *path, u32 maxSize)
{
FIL file;
u32 ret;
u32 ret = 0;
if(f_open(&file, path, FA_READ) != FR_OK) return ret;
if(f_open(&file, path, FA_READ) != FR_OK) ret = 0;
else
{
u32 size = f_size(&file);
if(size <= maxSize)
f_read(&file, dest, size, (unsigned int *)&ret);
f_close(&file);
}
return ret;
}
@ -57,7 +50,6 @@ u32 fileRead(void *dest, const char *path, u32 maxSize)
bool fileWrite(const void *buffer, const char *path, u32 size)
{
FIL file;
bool ret;
switch(f_open(&file, path, FA_WRITE | FA_OPEN_ALWAYS))
{
@ -68,8 +60,7 @@ bool fileWrite(const void *buffer, const char *path, u32 size)
f_truncate(&file);
f_close(&file);
ret = (u32)written == size;
break;
return (u32)written == size;
}
case FR_NO_PATH:
for(u32 i = 1; path[i] != 0; i++)
@ -81,19 +72,25 @@ bool fileWrite(const void *buffer, const char *path, u32 size)
f_mkdir(folder);
}
ret = fileWrite(buffer, path, size);
break;
return fileWrite(buffer, path, size);
default:
ret = false;
break;
return false;
}
}
return ret;
void fileDelete(const char *path)
{
f_unlink(path);
}
void fileRename(const char *oldPath, const char *newPath)
{
f_rename(oldPath, newPath);
}
u32 firmRead(void *dest)
{
const char *firmFolders[] = { "00000002", "20000002" };
const char *firmFolders[] = {"00000002", "20000002"};
char path[48] = "1:/title/00040138/";
concatenateStrings(path, firmFolders[ISN3DS ? 1 : 0]);
concatenateStrings(path, "/content");
@ -103,8 +100,8 @@ u32 firmRead(void *dest)
u32 firmVersion = 0xFFFFFFFF,
ret = 0;
if(f_opendir(&dir, path) == FR_OK)
{
if(f_opendir(&dir, path) != FR_OK) goto exit;
FILINFO info;
//Parse the target directory
@ -118,8 +115,8 @@ u32 firmRead(void *dest)
u32 tempVersion = hexAtoi(info.altname, 8);
//FIRM is equal or newer than 11.0
if(!ISDEVUNIT && tempVersion >= (ISN3DS ? 0x21 : 0x52)) ret = tempVersion <= (ISN3DS ? 0x28 : 0x58) ? 5 : 2;
//FIRM is newer than 11.3
if(!ISDEVUNIT && tempVersion > (ISN3DS ? 0x2D : 0x5C)) ret = 2;
//Found an older cxi
if(tempVersion < firmVersion) firmVersion = tempVersion;
@ -127,8 +124,8 @@ u32 firmRead(void *dest)
f_closedir(&dir);
if(ret != 1 && firmVersion != 0xFFFFFFFF)
{
if(ret == 1 || firmVersion == 0xFFFFFFFF) goto exit;
//Complete the string with the .app name
concatenateStrings(path, "/00000000.app");
@ -136,9 +133,8 @@ u32 firmRead(void *dest)
hexItoa(firmVersion, path + 35, 8);
if(!fileRead(dest, path, 0x100000)) ret = 3;
}
}
exit:
if(firmVersion == 0xFFFFFFFF) ret = 4;
return ret;

View File

@ -25,7 +25,8 @@
#include "types.h"
bool mountFs(bool isSd);
void unmountCtrNand(void);
u32 fileRead(void *dest, const char *path, u32 maxSize);
bool fileWrite(const void *buffer, const char *path, u32 size);
void fileDelete(const char *path);
void fileRename(const char *oldPath, const char *newPath);
u32 firmRead(void *dest);

View File

@ -11,7 +11,6 @@
#include "types.h"
#include "installer.h"
#include "fatfs/sdmmc/sdmmc.h"
#include "../build/bundled.h"
static const u8 sectorHashRetail[SHA_256_HASH_SIZE] = {
0x82, 0xF2, 0x73, 0x0D, 0x2C, 0x2D, 0xA3, 0xF3, 0x01, 0x65, 0xF9, 0x87, 0xFD, 0xCC, 0xAC, 0x5C,
@ -29,21 +28,9 @@ static const u8 sectorHashRetail[SHA_256_HASH_SIZE] = {
0x68, 0x52, 0xCC, 0x21, 0x89, 0xAE, 0x28, 0x38, 0x1A, 0x75, 0x90, 0xE7, 0x38, 0x23, 0x48, 0x41,
0x8E, 0x80, 0x78, 0x75, 0x27, 0x64, 0x04, 0xD6, 0x28, 0xD6, 0xFA, 0x39, 0xA8, 0x6F, 0xB0, 0x3F
},
firm0100Hash[SHA_256_HASH_SIZE] = {
firm1HashRetail[SHA_256_HASH_SIZE] = {
0xD8, 0x2D, 0xB7, 0xB4, 0x38, 0x2B, 0x07, 0x88, 0x99, 0x77, 0x91, 0x0C, 0xC6, 0xEC, 0x6D, 0x87,
0x7D, 0x21, 0x79, 0x23, 0xD7, 0x60, 0xAF, 0x4E, 0x8B, 0x3A, 0xAB, 0xB2, 0x63, 0xE4, 0x21, 0xC6
},
firm1HashRetail[SHA_256_HASH_SIZE] = {
0xD2, 0x53, 0xC1, 0xCC, 0x0A, 0x5F, 0xFA, 0xC6, 0xB3, 0x83, 0xDA, 0xC1, 0x82, 0x7C, 0xFB, 0x3B,
0x2D, 0x3D, 0x56, 0x6C, 0x6A, 0x1A, 0x8E, 0x52, 0x54, 0xE3, 0x89, 0xC2, 0x95, 0x06, 0x23, 0xE5
},
firm104O3DSHash[SHA_256_HASH_SIZE] = {
0x5D, 0x33, 0xD9, 0xCE, 0xE3, 0x39, 0x05, 0xD5, 0xCE, 0x37, 0xFE, 0xFB, 0xB5, 0xEC, 0x73, 0x6A,
0xA0, 0x10, 0xAD, 0x87, 0xF8, 0xDC, 0x55, 0x39, 0xFD, 0xDB, 0x48, 0x69, 0xAC, 0x5F, 0x3C, 0x2B
},
firm104N3DSHash[SHA_256_HASH_SIZE] = {
0x2D, 0x6B, 0xCC, 0xCE, 0x3B, 0x81, 0xD7, 0xCA, 0x67, 0x17, 0x90, 0x33, 0x35, 0x4D, 0xFA, 0xA5,
0x70, 0xF4, 0x7A, 0x99, 0xBB, 0x60, 0x0C, 0x2F, 0x34, 0x90, 0xFF, 0x10, 0xD4, 0x4C, 0x97, 0x42
},
sectorHashDev[SHA_256_HASH_SIZE] = {
0xB2, 0x91, 0xD9, 0xB1, 0x33, 0x05, 0x79, 0x0D, 0x47, 0xC6, 0x06, 0x98, 0x4C, 0x67, 0xC3, 0x70,
@ -64,9 +51,9 @@ static const u8 sectorHashRetail[SHA_256_HASH_SIZE] = {
u32 posY;
static void drawTitle(bool isOtpless)
static void drawTitle(void)
{
initScreens(isOtpless);
initScreens();
posY = drawString(TITLE, 10, 10, COLOR_TITLE);
posY = drawString("Thanks to delebile, #cakey and StandardBus", 10, posY + SPACING_Y, COLOR_WHITE);
@ -74,11 +61,11 @@ static void drawTitle(bool isOtpless)
void main(void)
{
bool isOtpless = ISA9LH && magic == 0xDEADCAFE;
bool isOtpless = ISA9LH && *(vu32 *)0x80FD0FC == 0xEAFE4AA3 && magic == 0xDEADCAFE;
if(!isOtpless) drawTitle(false);
if(!isOtpless) drawTitle();
if(!sdmmc_sdcard_init(isOtpless))
if(!sdmmc_sdcard_init(!isOtpless, true) && !isOtpless)
shutdown(1, "Error: failed to initialize SD and NAND");
u32 pressed;
@ -170,13 +157,11 @@ static inline void installer(bool isOtpless)
break;
case 2:
case 3:
updateKey2 = true;
break;
case 4:
updateFirm1 = true;
updateKey2 = true;
break;
default:
case 1:
break;
}
@ -191,15 +176,6 @@ static inline void installer(bool isOtpless)
if(!ISA9LH || updateKey2 || isOtpless) generateSector(keySector, (!ISA9LH && ISN3DS && !ISDEVUNIT) ? 1 : 0);
if(!ISA9LH && ISN3DS && !ISDEVUNIT)
{
//Read 10.0 FIRM0
if(fileRead((void *)FIRM0_100_OFFSET, "a9lh/firm0_100.bin", FIRM0100_SIZE) != FIRM0100_SIZE)
shutdown(1, "Error: firm0_100.bin doesn't exist or has a wrong size");
if(!verifyHash((void *)FIRM0_100_OFFSET, FIRM0100_SIZE, firm0100Hash))
shutdown(1, "Error: firm0_100.bin is invalid or corrupted");
}
if(!ISA9LH || updateFirm0)
{
//Read FIRM0
@ -218,6 +194,16 @@ static inline void installer(bool isOtpless)
shutdown(1, "Error: firm1.bin is invalid or corrupted");
}
if(!ISA9LH && ISN3DS && !ISDEVUNIT)
{
magic = 0xDEADCAFE;
fileRename("arm9loaderhax.bin", "arm9loaderhax.bak");
if(!fileWrite((void *)0x23F00000, "arm9loaderhax.bin", 0x10000))
shutdown(1, "Error: couldn't write arm9loaderhax.bin");
}
if(!isOtpless)
{
bool missingStage1Hash,
@ -274,23 +260,32 @@ static inline void installer(bool isOtpless)
if(!ISA9LH || updateFirm1) writeFirm((u8 *)FIRM1_OFFSET, true, FIRM1_SIZE);
if(!ISA9LH || updateKey2 || isOtpless) sdmmc_nand_writesectors(0x96, 1, keySector);
if(!isOtpless) writeFirm((u8 *)FIRM0_OFFSET, false, FIRM0_SIZE);
else
{
*(vu32 *)0x80FD0FC = 0;
drawTitle();
if(sdmmc_sdcard_init(true, false) && mountFs(true))
{
fileDelete("arm9loaderhax.bin");
fileRename("arm9loaderhax.bak", "arm9loaderhax.bin");
}
else
{
posY = drawString("Couldn't remove arm9loaderhax.bin!", 10, posY + SPACING_Y, COLOR_RED);
posY = drawString("Do it yourself after the install ends", 10, posY, COLOR_RED);
}
}
if(!ISA9LH && ISN3DS && !ISDEVUNIT)
{
const u8 ldrAndBranch[] = {0x00, 0x00, 0x9F, 0xE5, 0x10, 0xFF, 0x2F, 0xE1, 0x00, 0x80, 0xFF, 0x01};
memcpy((void *)0x80FD0FC, ldrAndBranch, sizeof(ldrAndBranch));
memcpy((void *)0x1FF8000, loader_bin, loader_bin_size);
writeFirm((u8 *)FIRM0_100_OFFSET, false, FIRM0100_SIZE);
*(vu32 *)0x80FD0FC = 0xEAFE4AA3;
mcuReboot();
}
writeFirm((u8 *)FIRM0_OFFSET, false, FIRM0_SIZE);
if(isOtpless) drawTitle(true);
shutdown(2, ISA9LH && !isOtpless ? "Update: success!" : "Full install: success!");
}
@ -331,32 +326,10 @@ static inline void uninstaller(void)
case 1:
shutdown(1, "Error: more than one FIRM has been detected");
break;
case 5:
posY = drawString("FIRM 11.0/11.1/11.2 has been detected!", 10, posY + SPACING_Y, COLOR_RED);
posY = drawString("Press SELECT to load 10.4 FIRM from SD", 10, posY + SPACING_Y, COLOR_WHITE);
posY = drawString("Press any other button to load FIRM from CTRNAND", 10, posY, COLOR_RED);
if(waitInput() == BUTTON_SELECT)
{
u32 firm104Size = ISN3DS ? 0xF2000 : 0xEA000;
unmountCtrNand();
if(!mountFs(true)) shutdown(1, "Error: failed to mount the SD card");
if(fileRead((void *)FIRM0_OFFSET, "a9lh/firm104.bin", firm104Size) != firm104Size)
shutdown(1, "Error: firm104.bin doesn't exist or has a wrong size");
if(!verifyHash((void *)FIRM0_OFFSET, firm104Size, ISN3DS ? firm104N3DSHash : firm104O3DSHash))
shutdown(1, "Error: firm104.bin is invalid or corrupted");
firmSize = firm104Size;
break;
}
case 2:
if(result == 2) posY = drawString("A FIRM newer than 11.2 has been detected!", 10, posY + SPACING_Y, COLOR_RED);
posY = drawString("A FIRM newer than 11.3 has been detected!", 10, posY + SPACING_Y, COLOR_RED);
posY = drawString("You are about to uninstall A9LH!", 10, posY + SPACING_Y, COLOR_RED);
posY = drawString("To reinstall you'll need an hardmod or a DSi dg!", 10, posY, COLOR_RED);
posY = drawString("To reinstall you'll need hardmod + NAND backup!", 10, posY, COLOR_RED);
break;
case 3:
shutdown(1, "Error: the CTRNAND FIRM is too large");
@ -365,23 +338,16 @@ static inline void uninstaller(void)
shutdown(1, "Error: couldn't read FIRM from CTRNAND");
break;
default:
break;
}
if(firmSize != 0 || !result)
{
posY = drawString("You are about to uninstall A9LH!", 10, posY + SPACING_Y, COLOR_RED);
posY = drawString("To reinstall you'll need 9.2 or lower!", 10, posY, COLOR_RED);
break;
}
inputSequence();
//Decrypt it and get its size
if(!firmSize)
{
firmSize = decryptExeFs((Cxi *)FIRM0_OFFSET);
if(firmSize == 0) shutdown(1, "Error: couldn't decrypt the CTRNAND FIRM");
}
//writeFirm encrypts in-place, so we need two copies
memcpy((void *)FIRM1_OFFSET, (void *)FIRM0_OFFSET, firmSize);

View File

@ -9,18 +9,17 @@
#define OTP_FROM_MEM 0x10012000
#define FIRM0_OFFSET 0x24000000
#define SECTION2_POSITION 0x66A00
#define FIRM0_100_OFFSET 0x24100000
#define FIRM1_OFFSET 0x24200000
#define FIRM1_OFFSET 0x24100000
#define FIRM0_SIZE 0xF3000
#define FIRM0100_SIZE 0xF2000
#define FIRM1_SIZE 0xF2000
#define STAGE1_POSITION 0xF0590
#define STAGE1_OFFSET FIRM0_OFFSET + STAGE1_POSITION
#define STAGE2_OFFSET 0x24300000
#define STAGE2_OFFSET 0x24200000
#define MAX_STAGE1_SIZE 0x1E70
#define MAX_STAGE2_SIZE 0x89A00
extern u32 magic;
extern const u8 key2s[5][AES_BLOCK_SIZE],
devKey2s[2][AES_BLOCK_SIZE];

View File

@ -39,21 +39,9 @@
#include "utils.h"
#include "memory.h"
#include "i2c.h"
#include "../build/bundled.h"
vu32 *arm11Entry = (vu32 *)BRAHMA_ARM11_ENTRY;
static inline void ownArm11(void)
{
memcpy((void *)A11_PAYLOAD_LOC, arm11_bin, arm11_bin_size);
*arm11Entry = 1;
*(vu32 *)0x1FFAED80 = 0xE51FF004;
*(vu32 *)0x1FFAED84 = A11_PAYLOAD_LOC;
*(vu8 *)0x1FFFFFF0 = 2;
while(*arm11Entry != 0);
}
static void invokeArm11Function(void (*func)())
{
*arm11Entry = (u32)func;
@ -87,7 +75,7 @@ void clearScreens(void)
invokeArm11Function(ARM11);
}
void initScreens(bool isOtpless)
void initScreens(void)
{
void __attribute__((naked)) initSequence(void)
{
@ -195,10 +183,6 @@ void initScreens(bool isOtpless)
if(!ARESCREENSINITED)
{
wait(3ULL);
if(isOtpless) ownArm11();
invokeArm11Function(initSequence);
//Turn on backlight

View File

@ -33,7 +33,6 @@
#define ARESCREENSINITED (PDN_GPU_CNT != 1)
#define BRAHMA_ARM11_ENTRY 0x1FFFFFF8
#define A11_PAYLOAD_LOC 0x1FFF4C80
#define WAIT_FOR_ARM9() *arm11Entry = 0; while(!*arm11Entry); ((void (*)())*arm11Entry)();
#define SCREEN_TOP_WIDTH 400
@ -49,4 +48,4 @@ static struct fb {
} *const fb = (struct fb *)0x23FFFE00;
void clearScreens(void);
void initScreens(bool isOtpless);
void initScreens(void);

View File

@ -91,4 +91,11 @@ start:
mov r1, #0x340
str r1, [r0]
@ Clear BSS
ldr r0, =__bss_start
mov r1, #0
ldr r2, =__bss_end
sub r2, r0
bl memset32
b main

View File

@ -8,56 +8,32 @@
#include "cache.h"
#include "i2c.h"
static void startChrono(void)
{
REG_TIMER_CNT(0) = 0; //67MHz
for(u32 i = 1; i < 4; i++) REG_TIMER_CNT(i) = 4; //Count-up
for(u32 i = 0; i < 4; i++) REG_TIMER_VAL(i) = 0;
REG_TIMER_CNT(0) = 0x80; //67MHz; enabled
for(u32 i = 1; i < 4; i++) REG_TIMER_CNT(i) = 0x84; //Count-up; enabled
}
static u64 chrono(void)
{
u64 res;
for(u32 i = 0; i < 4; i++) res |= REG_TIMER_VAL(i) << (16 * i);
res /= (TICKS_PER_SEC / 1000);
return res;
}
u32 waitInput(void)
{
bool pressedKey = false;
u32 key,
oldKey = HID_PAD;
while(!pressedKey)
while(true)
{
key = HID_PAD;
if(!key) oldKey = key;
else if(key != oldKey)
if(!key)
{
oldKey = 0;
continue;
}
if(key == oldKey) continue;
//Make sure the key is pressed
u32 i;
for(i = 0; i < 0x13000 && key == HID_PAD; i++);
if(i == 0x13000) pressedKey = true;
}
if(i == 0x13000) break;
}
return key;
}
void wait(u64 amount)
{
startChrono();
while(chrono() < amount);
}
void mcuReboot(void)
{
clearScreens();

View File

@ -28,7 +28,6 @@
extern u32 posY;
u32 waitInput(void);
void wait(u64 amount);
void mcuReboot(void);
void inputSequence(void);
void shutdown(u32 mode, const char *message);