Skip to content

Commit

Permalink
-added ported cfw booter to directly boot into a fw.img on sd card
Browse files Browse the repository at this point in the history
  • Loading branch information
FIX94 committed Nov 12, 2016
1 parent e80cd48 commit be37e6d
Show file tree
Hide file tree
Showing 25 changed files with 1,016 additions and 12 deletions.
54 changes: 49 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
.PHONY := all code550.bin

all: brainage kirby yoshids brainage.zip kirby.zip yoshids.zip
all: brainage kirby yoshids brainage.zip kirby.zip yoshids.zip brainage_cfw.zip kirby_cfw.zip yoshids_cfw.zip

brainage: setup_brainage brainage.nds
brainage: setup_brainage brainage.nds setup_brainage_cfw brainage_cfw.nds

kirby: setup_kirby kirby.nds
kirby: setup_kirby kirby.nds setup_kirby_cfw kirby_cfw.nds

yoshids: setup_yoshids yoshids.nds
yoshids: setup_yoshids yoshids.nds setup_yoshids_cfw yoshids_cfw.nds

setup_brainage:
rm -f *.bin
Expand All @@ -23,17 +23,50 @@ setup_yoshids:
@cd hbl_loader && make && cd ..
@cp -f yoshids_defs.s defines.s

setup_brainage_cfw:
rm -f *.bin
@cd cfw_booter && make && cd ..
@cp -f brainage_defs.s defines.s

setup_kirby_cfw:
rm -f *.bin
@cd cfw_booter && make && cd ..
@cp -f kirby_defs.s defines.s

setup_yoshids_cfw:
rm -f *.bin
@cd cfw_booter && make && cd ..
@cp -f yoshids_defs.s defines.s

brainage.nds:
armips haxchi_rop.s
armips haxchi.s
mv rom.nds brainage.nds

kirby.nds:
armips haxchi_rop.s
armips haxchi.s
mv rom.nds kirby.nds

yoshids.nds:
armips haxchi_rop.s
armips haxchi.s
mv rom.nds yoshids.nds

brainage_cfw.nds:
armips haxchi_rop.s
armips haxchi.s
mv rom.nds brainage_cfw.nds

kirby_cfw.nds:
armips haxchi_rop.s
armips haxchi.s
mv rom.nds kirby_cfw.nds

yoshids_cfw.nds:
armips haxchi_rop.s
armips haxchi.s
mv rom.nds yoshids_cfw.nds

brainage.zip:
zip -JXjq9 brainage.zip brainage.nds
Expand All @@ -44,7 +77,18 @@ kirby.zip:
yoshids.zip:
zip -JXjq9 yoshids.zip yoshids.nds

brainage_cfw.zip:
zip -JXjq9 brainage_cfw.zip brainage_cfw.nds

kirby_cfw.zip:
zip -JXjq9 kirby_cfw.zip kirby_cfw.nds

yoshids_cfw.zip:
zip -JXjq9 yoshids_cfw.zip yoshids_cfw.nds

clean:
@rm -f *.bin brainage.nds brainage.zip kirby.nds kirby.zip yoshids.nds yoshids.zip
@rm -f *.bin defines.s brainage.nds brainage.zip kirby.nds kirby.zip yoshids.nds yoshids.zip
@rm -f brainage_cfw.nds brainage_cfw.zip kirby_cfw.nds kirby_cfw.zip yoshids_cfw.nds yoshids_cfw.zip
@cd cfw_booter && make clean && cd ..
@cd hbl_loader && make clean && cd ..
@echo "all cleaned up !"
2 changes: 0 additions & 2 deletions brainage_defs.s
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@

FILE_NDS_NAME equ "brainage.nds"

; game stack return address
HAX_TARGET_ADDRESS equ (0x1076FAA4)

Expand Down
50 changes: 50 additions & 0 deletions cfw_booter/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
PATH := $(DEVKITPPC)/bin:$(PATH)
PREFIX ?= powerpc-eabi-
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc
CFLAGS = -std=gnu99 -O0 -nostdinc -fno-builtin -g
ASFLAGS = -mregnames -x assembler-with-cpp
LD = $(PREFIX)ld
OBJCOPY = $(PREFIX)objcopy
LDFLAGS=-Ttext 1800000 -L$(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2 -lgcc
OBJDUMP ?= $(PREFIX)objdump
project := .
root := $(CURDIR)
build := $(root)/bin

CFLAGS += -DUSE_SD_LOADER
ASFLAGS += -DUSE_SD_LOADER
FIRMWARE = 550

all: clean setup main

$(CURDIR)/payload/arm_kernel_bin.h: $(CURDIR)/payload/arm_user_bin.h
@$(MAKE) --no-print-directory -C $(CURDIR)/arm_kernel -f $(CURDIR)/arm_kernel/Makefile
@-mkdir -p $(CURDIR)/payload
@cp -p $(CURDIR)/arm_kernel/arm_kernel_bin.h $@

$(CURDIR)/payload/arm_user_bin.h:
@$(MAKE) --no-print-directory -C $(CURDIR)/arm_user -f $(CURDIR)/arm_user/Makefile
@-mkdir -p $(CURDIR)/payload
@cp -p $(CURDIR)/arm_user/arm_user_bin.h $@

setup:
mkdir -p $(root)/bin/

main: $(CURDIR)/payload/arm_kernel_bin.h
$(CC) $(CFLAGS) -DVER=$(FIRMWARE) -c $(project)/main.c
$(AS) $(ASFLAGS) -DVER=$(FIRMWARE) -c $(project)/crt0.S
cp -r $(root)/*.o $(build)
rm $(root)/*.o
$(LD) -o code$(FIRMWARE).elf $(build)/crt0.o `find $(build) -name "*.o" ! -name "crt0.o"` $(LDFLAGS) -Map code.map
$(OBJCOPY) code$(FIRMWARE).elf -O binary ../code$(FIRMWARE).bin

clean:
rm -rf $(build) payload
rm -rf code$(FIRMWARE).elf code.map
$(MAKE) --no-print-directory -C $(CURDIR)/arm_user -f $(CURDIR)/arm_user/Makefile clean
$(MAKE) --no-print-directory -C $(CURDIR)/arm_kernel -f $(CURDIR)/arm_kernel/Makefile clean

print_stats:
@echo
@echo "code size : loadiine =>" `$(OBJDUMP) -h ../loadiine.elf | awk '/.kernel_code|.text|.menu_magic|.loader_magic|.fs_method_calls|.rodata|.data|.sdata|.bss|.sbss|.fs_magic/ { sum+=strtonum("0x"$$3) } END {print sum}'` / 7530312
2 changes: 2 additions & 0 deletions cfw_booter/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This is a modified version of cfw booter which can be found here:
https://github.com/dimok789/cfw_booter
71 changes: 71 additions & 0 deletions cfw_booter/arm_kernel/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif

ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),)
export PATH:=$(DEVKITARM)/bin:$(PATH)
endif

CC = arm-none-eabi-gcc
# LINK = arm-none-eabi-gcc
LINK = arm-none-eabi-ld
AS = arm-none-eabi-as
OBJCOPY = arm-none-eabi-objcopy
CFLAGS += -Wall -mbig-endian -std=gnu99 -march=armv5 -Os -I$(DEVKITPRO)/libnds/include
LDFLAGS += --script=link.ld -EB -L"$(DEVKITARM)/arm-none-eabi/lib" -Map=output.map

CFILES = $(wildcard source/*.c)
BINFILES = $(wildcard data/*.bin)
OFILES = $(BINFILES:data/%.bin=build/%.bin.o)
OFILES += $(CFILES:source/%.c=build/%.o)
DFILES = $(CFILES:source/%.c=build/%.d)
SFILES = $(wildcard source/*.s)
OFILES += $(SFILES:source/%.s=build/%.o)
PROJECTNAME = ${shell basename "$(CURDIR)"}
CWD = "$(CURDIR)""

#---------------------------------------------------------------------------------
# canned command sequence for binary data, taken from devkitARM
#---------------------------------------------------------------------------------
define bin2o
bin2s $< | $(AS) -o $(@)
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > source/`(echo $(<F) | tr . _)`.h
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> source/`(echo $(<F) | tr . _)`.h
echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> source/`(echo $(<F) | tr . _)`.h
endef

.PHONY:=all dirs

all: dirs $(PROJECTNAME).bin $(PROJECTNAME)_bin.h

dirs:
@mkdir -p build

$(PROJECTNAME).bin: $(PROJECTNAME).elf
# $(OBJCOPY) -O binary $< $@
$(OBJCOPY) -j .text -j .rodata -O binary $< $@

$(PROJECTNAME)_bin.h: $(PROJECTNAME).bin
xxd -i $< | sed "s/unsigned/static const unsigned/g;s/$(PROJECTNAME)$*/$(PROJECTNAME)/g" > $@

$(PROJECTNAME).elf: $(OFILES)
$(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(filter-out build/crt0.o, $(OFILES))

clean:
@rm -rf build
@rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin $(PROJECTNAME)_bin.h output.map
@echo "all cleaned up !"

-include $(DFILES)

build/%.o: source/%.c
$(CC) $(CFLAGS) -c $< -o $@
@$(CC) -MM $< > build/$*.d

build/%.o: source/%.s
$(CC) $(CFLAGS) -xassembler-with-cpp -c $< -o $@
@$(CC) -MM $< > build/$*.d

build/%.bin.o: data/%.bin
@echo $(notdir $<)
@$(bin2o)
18 changes: 18 additions & 0 deletions cfw_booter/arm_kernel/link.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
OUTPUT_ARCH(arm)

MEMORY
{
RAMX (rx) : ORIGIN = 0x08134100, LENGTH = 0x000BF00
}

SECTIONS
{
.text : ALIGN(0x100) {
build/crt0.o(.init)
*(.text)
}
.rodata : {
*(.rodata*)
}
}

12 changes: 12 additions & 0 deletions cfw_booter/arm_kernel/source/crt0.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.section ".init"
.arm
.align 4

.extern _main
.type _main, %function

.extern memset
.type memset, %function

_start:
b _main
124 changes: 124 additions & 0 deletions cfw_booter/arm_kernel/source/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#include "types.h"
#include "utils.h"
#include "../../payload/arm_user_bin.h"

static const char repairData_set_fault_behavior[] = {
0xE1,0x2F,0xFF,0x1E,0xE9,0x2D,0x40,0x30,0xE5,0x93,0x20,0x00,0xE1,0xA0,0x40,0x00,
0xE5,0x92,0x30,0x54,0xE1,0xA0,0x50,0x01,0xE3,0x53,0x00,0x01,0x0A,0x00,0x00,0x02,
0xE1,0x53,0x00,0x00,0xE3,0xE0,0x00,0x00,0x18,0xBD,0x80,0x30,0xE3,0x54,0x00,0x0D,
};
static const char repairData_set_panic_behavior[] = {
0x08,0x16,0x6C,0x00,0x00,0x00,0x18,0x0C,0x08,0x14,0x40,0x00,0x00,0x00,0x9D,0x70,
0x08,0x16,0x84,0x0C,0x00,0x00,0xB4,0x0C,0x00,0x00,0x01,0x01,0x08,0x14,0x40,0x00,
0x08,0x15,0x00,0x00,0x08,0x17,0x21,0x80,0x08,0x17,0x38,0x00,0x08,0x14,0x30,0xD4,
0x08,0x14,0x12,0x50,0x08,0x14,0x12,0x94,0xE3,0xA0,0x35,0x36,0xE5,0x93,0x21,0x94,
0xE3,0xC2,0x2E,0x21,0xE5,0x83,0x21,0x94,0xE5,0x93,0x11,0x94,0xE1,0x2F,0xFF,0x1E,
0xE5,0x9F,0x30,0x1C,0xE5,0x9F,0xC0,0x1C,0xE5,0x93,0x20,0x00,0xE1,0xA0,0x10,0x00,
0xE5,0x92,0x30,0x54,0xE5,0x9C,0x00,0x00,
};
static const char repairData_usb_root_thread[] = {
0xE5,0x8D,0xE0,0x04,0xE5,0x8D,0xC0,0x08,0xE5,0x8D,0x40,0x0C,0xE5,0x8D,0x60,0x10,
0xEB,0x00,0xB2,0xFD,0xEA,0xFF,0xFF,0xC9,0x10,0x14,0x03,0xF8,0x10,0x62,0x4D,0xD3,
0x10,0x14,0x50,0x00,0x10,0x14,0x50,0x20,0x10,0x14,0x00,0x00,0x10,0x14,0x00,0x90,
0x10,0x14,0x00,0x70,0x10,0x14,0x00,0x98,0x10,0x14,0x00,0x84,0x10,0x14,0x03,0xE8,
0x10,0x14,0x00,0x3C,0x00,0x00,0x01,0x73,0x00,0x00,0x01,0x76,0xE9,0x2D,0x4F,0xF0,
0xE2,0x4D,0xDE,0x17,0xEB,0x00,0xB9,0x92,0xE3,0xA0,0x10,0x00,0xE3,0xA0,0x20,0x03,
0xE5,0x9F,0x0E,0x68,0xEB,0x00,0xB3,0x20,
};

/* from smealum's iosuhax: must be placed at 0x05059938 */
static const char os_launch_hook[] = {
0x47, 0x78, 0x00, 0x00, 0xe9, 0x2d, 0x40, 0x0f, 0xe2, 0x4d, 0xd0, 0x08, 0xeb,
0xff, 0xfd, 0xfd, 0xe3, 0xa0, 0x00, 0x00, 0xeb, 0xff, 0xfe, 0x03, 0xe5, 0x9f,
0x10, 0x4c, 0xe5, 0x9f, 0x20, 0x4c, 0xe3, 0xa0, 0x30, 0x00, 0xe5, 0x8d, 0x30,
0x00, 0xe5, 0x8d, 0x30, 0x04, 0xeb, 0xff, 0xfe, 0xf1, 0xe2, 0x8d, 0xd0, 0x08,
0xe8, 0xbd, 0x80, 0x0f, 0x2f, 0x64, 0x65, 0x76, 0x2f, 0x73, 0x64, 0x63, 0x61,
0x72, 0x64, 0x30, 0x31, 0x00, 0x2f, 0x76, 0x6f, 0x6c, 0x2f, 0x73, 0x64, 0x63,
0x61, 0x72, 0x64, 0x00, 0x00, 0x00, 0x2f, 0x76, 0x6f, 0x6c, 0x2f, 0x73, 0x64,
0x63, 0x61, 0x72, 0x64, 0x00, 0x05, 0x11, 0x60, 0x00, 0x05, 0x0b, 0xe0, 0x00,
0x05, 0x0b, 0xcf, 0xfc, 0x05, 0x05, 0x99, 0x70, 0x05, 0x05, 0x99, 0x7e,
};

static const char sd_path[] = "/vol/sdcard";

static unsigned int __attribute__((noinline)) disable_mmu(void)
{
unsigned int control_register = 0;
asm volatile("MRC p15, 0, %0, c1, c0, 0" : "=r" (control_register));
asm volatile("MCR p15, 0, %0, c1, c0, 0" : : "r" (control_register & 0xFFFFEFFA));
return control_register;
}

static void __attribute__((noinline)) restore_mmu(unsigned int control_register)
{
asm volatile("MCR p15, 0, %0, c1, c0, 0" : : "r" (control_register));
}

int _main()
{
int(*disable_interrupts)() = (int(*)())0x0812E778;
int(*enable_interrupts)(int) = (int(*)(int))0x0812E78C;
void(*invalidate_icache)() = (void(*)())0x0812DCF0;
void(*invalidate_dcache)(unsigned int, unsigned int) = (void(*)())0x08120164;
void(*flush_dcache)(unsigned int, unsigned int) = (void(*)())0x08120160;
char* (*kernel_memcpy)(void*, void*, int) = (char*(*)(void*, void*, int))0x08131D04;

flush_dcache(0x081200F0, 0x4001); // giving a size >= 0x4000 flushes all cache

int level = disable_interrupts();

unsigned int control_register = disable_mmu();

/* Save the request handle so we can reply later */
*(volatile u32*)0x0012F000 = *(volatile u32*)0x1016AD18;

/* Patch kernel_error_handler to BX LR immediately */
*(int*)0x08129A24 = 0xE12FFF1E;

void * pset_fault_behavior = (void*)0x081298BC;
kernel_memcpy(pset_fault_behavior, (void*)repairData_set_fault_behavior, sizeof(repairData_set_fault_behavior));

void * pset_panic_behavior = (void*)0x081296E4;
kernel_memcpy(pset_panic_behavior, (void*)repairData_set_panic_behavior, sizeof(repairData_set_panic_behavior));

void * pusb_root_thread = (void*)0x10100174;
kernel_memcpy(pusb_root_thread, (void*)repairData_usb_root_thread, sizeof(repairData_usb_root_thread));

void * pUserBinSource = (void*)0x00148000;
void * pUserBinDest = (void*)0x101312D0;
kernel_memcpy(pUserBinDest, (void*)pUserBinSource, sizeof(arm_user_bin));

int i;
for (i = 0; i < 32; i++)
if (i < 11)
((char*)(0x050663B4 - 0x05000000 + 0x081C0000))[i] = sd_path[i];
else
((char*)(0x050663B4 - 0x05000000 + 0x081C0000))[i] = (char)0;

*(int*)(0x050282AE - 0x05000000 + 0x081C0000) = 0xF031FB43; // bl launch_os_hook

*(int*)(0x05052C44 - 0x05000000 + 0x081C0000) = 0xE3A00000; // mov r0, #0
*(int*)(0x05052C48 - 0x05000000 + 0x081C0000) = 0xE12FFF1E; // bx lr

*(int*)(0x0500A818 - 0x05000000 + 0x081C0000) = 0x20002000; // mov r0, #0; mov r0, #0

*(int*)(0x040017E0 - 0x04000000 + 0x08280000) = 0xE3A00000;
*(int*)(0x040019C4 - 0x04000000 + 0x08280000) = 0xE3A00000;
*(int*)(0x04001BB0 - 0x04000000 + 0x08280000) = 0xE3A00000;
*(int*)(0x04001D40 - 0x04000000 + 0x08280000) = 0xE3A00000;

for (i = 0; i < sizeof(os_launch_hook); i++)
((char*)(0x05059938 - 0x05000000 + 0x081C0000))[i] = os_launch_hook[i];

*(int*)(0x1555500) = 0;

/* REENABLE MMU */
restore_mmu(control_register);

invalidate_dcache(0x081298BC, 0x4001); // giving a size >= 0x4000 invalidates all cache
invalidate_icache();

enable_interrupts(level);

return 0;
}
16 changes: 16 additions & 0 deletions cfw_booter/arm_kernel/source/types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef _TYPES_H
#define _TYPES_H

#include <stdint.h>

typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;

typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;

#endif
Loading

0 comments on commit be37e6d

Please sign in to comment.