-fixed wii game and channel booting by creating a small loader for the booter, this could possibly fix other problems on game bootup as well

This commit is contained in:
fix94.1 2014-03-23 17:40:31 +00:00
parent b3b5b0948b
commit 368cfc2b7d
18 changed files with 244 additions and 31 deletions

View File

@ -2,6 +2,9 @@
CURDIR_TMP := $(CURDIR) CURDIR_TMP := $(CURDIR)
all: all:
@echo Make WiiFlow Loader
@$(MAKE) --no-print-directory -C $(CURDIR_TMP)/resources/extldr \
-f $(CURDIR_TMP)/resources/extldr/Makefile
@echo Make WiiFlow Booter @echo Make WiiFlow Booter
@$(MAKE) --no-print-directory -C $(CURDIR_TMP)/resources/wiiflow_game_booter \ @$(MAKE) --no-print-directory -C $(CURDIR_TMP)/resources/wiiflow_game_booter \
-f $(CURDIR_TMP)/resources/wiiflow_game_booter/Makefile -f $(CURDIR_TMP)/resources/wiiflow_game_booter/Makefile
@ -10,6 +13,9 @@ all:
@echo Make WiiFlow Main @echo Make WiiFlow Main
@$(MAKE) --no-print-directory -C $(CURDIR_TMP) -f $(CURDIR_TMP)/Makefile.main @$(MAKE) --no-print-directory -C $(CURDIR_TMP) -f $(CURDIR_TMP)/Makefile.main
clean: clean:
@echo Cleanup WiiFlow Loader
@$(MAKE) --no-print-directory -C $(CURDIR_TMP)/resources/extldr \
-f $(CURDIR_TMP)/resources/extldr/Makefile clean
@echo Cleanup WiiFlow Booter @echo Cleanup WiiFlow Booter
@$(MAKE) --no-print-directory -C $(CURDIR_TMP)/resources/wiiflow_game_booter \ @$(MAKE) --no-print-directory -C $(CURDIR_TMP)/resources/wiiflow_game_booter \
-f $(CURDIR_TMP)/resources/wiiflow_game_booter/Makefile clean -f $(CURDIR_TMP)/resources/wiiflow_game_booter/Makefile clean

50
resources/extldr/Makefile Normal file
View File

@ -0,0 +1,50 @@
PREFIX = powerpc-eabi-
AR = $(PREFIX)ar
AS = $(PREFIX)as
CC = $(PREFIX)gcc
CXX = $(PREFIX)g++
LD = $(PREFIX)ld
OBJCOPY = $(PREFIX)objcopy
RANLIB = $(PREFIX)ranlib
STRIP = $(PREFIX)strip
MACHDEP = -mcpu=750 -mno-eabi -mhard-float
CFLAGS = $(MACHDEP) -O1 -Werror -Wall -pipe -ffunction-sections -finline-functions-called-once -mno-sdata
LDFLAGS = $(MACHDEP) -n -nostartfiles -nostdlib -Wl,-T,link.ld -L.
ASFLAGS = -D_LANGUAGE_ASSEMBLY -DHW_RVL
TARGET_LINKED = boot.elf
TARGET = ../../data/extldr.bin
CFILES = string.c sync.c main.c
OBJS = crt0.o string.o sync.o main.o
DEPDIR = .deps
all: $(TARGET)
%.o: %.s
@echo "$<"
@$(CC) $(CFLAGS) $(DEFINES) $(ASFLAGS) -c $< -o $@
%.o: %.S
@echo "$<"
@$(CC) $(CFLAGS) $(DEFINES) $(ASFLAGS) -c $< -o $@
%.o: %.c
@echo "$<"
@$(CC) $(CFLAGS) $(DEFINES) -c $< -o $@
$(TARGET_LINKED): $(OBJS)
@echo "linking ... $@"
@$(CC) -g -o $@ $(LDFLAGS) $(OBJS) $(LIBS)
$(TARGET): $(TARGET_LINKED)
@echo "output ... $@"
@$(OBJCOPY) -O binary $< $@
clean:
@echo "clean ..."
@rm -rf $(TARGET_LINKED) $(TARGET) $(OBJS) $(DEPDIR)

22
resources/extldr/crt0.s Normal file
View File

@ -0,0 +1,22 @@
# Copyright 2008-2009 Segher Boessenkool <segher@kernel.crashing.org>
# This code is licensed to you under the terms of the GNU GPL, version 2;
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
.extern _main
.globl _start
_start:
# Disable interrupts, enable FP.
mfmsr 3 ; rlwinm 3,3,0,17,15 ; ori 3,3,0x2000 ; mtmsr 3 ; isync
# Setup stack.
lis 1,_stack_top@ha ; addi 1,1,_stack_top@l ; li 0,0 ; stwu 0,-64(1)
# Clear BSS.
lis 3,__bss_start@ha ; addi 3,3,__bss_start@l
li 4,0
lis 5,__bss_end@ha ; addi 5,5,__bss_end@l ; sub 5,5,3
bl memset
# Go!
bl _main

27
resources/extldr/link.ld Normal file
View File

@ -0,0 +1,27 @@
/* Copyright 2008-2009 Segher Boessenkool <segher@kernel.crashing.org>
This code is licensed to you under the terms of the GNU GPL, version 2;
see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt */
OUTPUT_FORMAT("elf32-powerpc")
OUTPUT_ARCH(powerpc:common)
ENTRY(_start)
SECTIONS {
. = 0x93300000;
.start : { crt0.o(*) }
.text : { *(.text) }
.rodata : { *(.rodata .rodata.*)}
.data : { *(.data) }
__bss_start = .;
.bss : { *(.bss) }
__bss_end = .;
. = ALIGN(0x40);
.stack : {
. += 0x8000;
_stack_top = .;
}
}

15
resources/extldr/main.c Normal file
View File

@ -0,0 +1,15 @@
#include <stdio.h>
#include <stdarg.h>
#include "string.h"
#include "sync.h"
typedef void (*entrypoint) (void);
unsigned char *cfg = (unsigned char*)0x80A7FFF0;
unsigned char *start = (unsigned char*)0x80A80000;
unsigned char *buffer = (unsigned char*)0x90100000;
void _main(void)
{
entrypoint exeEntryPoint = (entrypoint)start;
memcpy(cfg, buffer, 0x01000000); //1mb safe copying of cfg and booter
sync_before_exec(cfg, 0x01000000);
exeEntryPoint();
}

25
resources/extldr/string.c Normal file
View File

@ -0,0 +1,25 @@
// Copyright 2008-2009 Segher Boessenkool <segher@kernel.crashing.org>
// This code is licensed to you under the terms of the GNU GPL, version 2;
// see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
#include <stdio.h>
void *memset(void *b, int c, size_t len)
{
size_t i;
for (i = 0; i < len; i++)
((unsigned char *)b)[i] = c;
return b;
}
void *memcpy(void *dst, const void *src, size_t len)
{
size_t i;
for (i = 0; i < len; i++)
((unsigned char *)dst)[i] = ((unsigned char *)src)[i];
return dst;
}

View File

@ -0,0 +1,9 @@
#ifndef STRING_H_
#define STRING_H_
#include <stdio.h>
void *memcpy(void *dst, const void *src, size_t len);
void *memset(void *b, int c, size_t len);
#endif

16
resources/extldr/sync.c Normal file
View File

@ -0,0 +1,16 @@
// Copyright 2008-2009 Segher Boessenkool <segher@kernel.crashing.org>
// This code is licensed to you under the terms of the GNU GPL, version 2;
// see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
void sync_before_exec(const void *p, unsigned int len)
{
unsigned int a, b;
a = (unsigned int)p & ~0x1f;
b = ((unsigned int)p + len + 0x1f) & ~0x1f;
for ( ; a < b; a += 32)
asm("dcbst 0,%0 ; sync ; icbi 0,%0" : : "b"(a));
asm("sync ; isync");
}

6
resources/extldr/sync.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __SYNC_H_
#define __SYNC_H_
void sync_before_exec(const void *p, unsigned int len);
#endif

View File

@ -23,9 +23,9 @@ INCLUDES := source
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # options for code generation
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
CFLAGS = -g -ggdb -Ofast -Wall -Wextra $(MACHDEP) $(INCLUDE) -DHAVE_CONFIG_H CFLAGS = -g -ggdb -O1 -Wall -Wextra $(MACHDEP) $(INCLUDE) -DHAVE_CONFIG_H
CXXFLAGS = $(CFLAGS) CXXFLAGS = $(CFLAGS)
LDFLAGS = -g -ggdb $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80B00000 LDFLAGS = -g -ggdb $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80A80000
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project # any extra libraries we wish to link with the project

View File

@ -258,6 +258,15 @@ void Disc_SetVMode(GXRModeObj *rmode, u32 rmode_reg)
s32 wbfsDev = 0; s32 wbfsDev = 0;
u32 wbfs_part_idx = 0; u32 wbfs_part_idx = 0;
FragList *frag_list = NULL; FragList *frag_list = NULL;
void copy_frag_list(FragList *src)
{
if(src == NULL)
return;
frag_list = malloc(sizeof(FragList)); //internal copy
memcpy(frag_list, src, sizeof(FragList));
}
static int set_frag_list() static int set_frag_list()
{ {
// (+1 for header which is same size as fragment) // (+1 for header which is same size as fragment)

View File

@ -16,6 +16,9 @@ void Disc_SetLowMemChan();
GXRModeObj *Disc_SelectVMode(u8 videoselected, u32 *rmode_reg); GXRModeObj *Disc_SelectVMode(u8 videoselected, u32 *rmode_reg);
void Disc_SetVMode(GXRModeObj *rmode, u32 rmode_reg); void Disc_SetVMode(GXRModeObj *rmode, u32 rmode_reg);
//just for frag copy
void copy_frag_list(FragList *src);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -59,8 +59,11 @@ extern const u32 wpadbuttonsdown2hooks[4];
void app_gameconfig_set(u32 *gameconfig, u32 tempgameconfsize) void app_gameconfig_set(u32 *gameconfig, u32 tempgameconfsize)
{ {
if(gameconfig == NULL)
return;
gameconfsize = tempgameconfsize; gameconfsize = tempgameconfsize;
gameconf = gameconfig; gameconf = malloc(gameconfsize); //internal copy
memcpy(gameconf, gameconfig, gameconfsize);
} }
u8 *code_buf = NULL; u8 *code_buf = NULL;
@ -70,23 +73,24 @@ void ocarina_set_codes(void *list, u8 *listend, u8 *cheats, u32 cheatSize)
{ {
codelist = list; codelist = list;
codelistend = listend; codelistend = listend;
code_buf = cheats; if(cheatSize <= 0 || cheats == NULL)
code_size = cheatSize;
if(code_size <= 0)
{ {
//gprintf("Ocarina: No codes found\n"); gprintf("Ocarina: No codes found\n");
code_buf = NULL; code_buf = NULL;
code_size = 0; code_size = 0;
return; return;
} }
if (code_size > (u32)codelistend - (u32)codelist) if (cheatSize > (u32)codelistend - (u32)codelist)
{ {
gprintf("Ocarina: Too many codes found.\n"); gprintf("Ocarina: Too many codes found.\n");
code_buf = NULL; code_buf = NULL;
code_size = 0; code_size = 0;
return; return;
} }
//gprintf("Ocarina: Codes found.\n"); code_size = cheatSize;
code_buf = malloc(code_size); //internal copy
memcpy(code_buf, cheats, code_size);
gprintf("Ocarina: Codes found.\n");
} }
void app_pokevalues() void app_pokevalues()
@ -242,6 +246,8 @@ int ocarina_do_code()
{ {
memcpy(codelist, code_buf, code_size); memcpy(codelist, code_buf, code_size);
DCFlushRange(codelist, (u32)codelistend - (u32)codelist); DCFlushRange(codelist, (u32)codelistend - (u32)codelist);
free(code_buf);
code_buf = NULL;
} }
// TODO What's this??? // TODO What's this???

View File

@ -33,6 +33,7 @@
#include "wdvd.h" #include "wdvd.h"
#include "gecko.h" #include "gecko.h"
#define EXT_ADDR_CFG ((vu32*)0x80A7FFF0)
using namespace std; using namespace std;
IOS_Info CurrentIOS; IOS_Info CurrentIOS;
@ -55,7 +56,7 @@ int main()
{ {
InitGecko(); InitGecko();
gprintf("WiiFlow External Booter by FIX94\n"); gprintf("WiiFlow External Booter by FIX94\n");
memcpy(&normalCFG, (void*)0x93100000, sizeof(the_CFG)); memcpy(&normalCFG, ((void*)*EXT_ADDR_CFG), sizeof(the_CFG));
VIDEO_Init(); VIDEO_Init();
video_init(); video_init();
prog10(); prog10();
@ -68,7 +69,7 @@ int main()
set_wip_list(normalCFG.wip_list, normalCFG.wip_count); set_wip_list(normalCFG.wip_list, normalCFG.wip_count);
app_gameconfig_set(normalCFG.gameconf, normalCFG.gameconfsize); app_gameconfig_set(normalCFG.gameconf, normalCFG.gameconfsize);
ocarina_set_codes(normalCFG.codelist, normalCFG.codelistend, normalCFG.cheats, normalCFG.cheatSize); ocarina_set_codes(normalCFG.codelist, normalCFG.codelistend, normalCFG.cheats, normalCFG.cheatSize);
frag_list = normalCFG.fragments; copy_frag_list(normalCFG.fragments);
wbfsDev = normalCFG.wbfsDevice; wbfsDev = normalCFG.wbfsDevice;
wbfs_part_idx = normalCFG.wbfsPart; wbfs_part_idx = normalCFG.wbfsPart;
prog10(); prog10();

View File

@ -60,7 +60,7 @@ bool set_wip_list(WIP_Code *list, int size)
{ {
if(CodeList == NULL && size > 0) if(CodeList == NULL && size > 0)
{ {
WIP_Code *newlist = malloc(size * sizeof(WIP_Code)); WIP_Code *newlist = malloc(size * sizeof(WIP_Code)); //internal copy
memcpy(newlist, list, size * sizeof(WIP_Code)); memcpy(newlist, list, size * sizeof(WIP_Code));
DCFlushRange(newlist, size * sizeof(WIP_Code)); DCFlushRange(newlist, size * sizeof(WIP_Code));
CodeList = newlist; CodeList = newlist;

View File

@ -37,9 +37,14 @@
#include "plugin/crc32.h" #include "plugin/crc32.h"
/* External WiiFlow Game Booter */ /* External WiiFlow Game Booter */
static the_CFG *BooterConfig = (the_CFG*)0x93100000; the_CFG normalCFG;
#define EXT_ADDR ((u8*)0x80B00000) #define EXT_ADDR_CFG ((vu32*)0x90100000) //later for 0x80A7FFF0
#define EXT_ENTRY ((entry)EXT_ADDR) #define EXT_ADDR ((u8*)0x90100010) //later for 0x80A80000
#define LDR_ADDR ((u8*)0x93300000)
#define LDR_ENTRY ((entry)LDR_ADDR)
extern const u8 extldr_bin[];
extern const u32 extldr_bin_size;
extern "C" { extern "C" {
u8 configbytes[2]; u8 configbytes[2];
@ -55,7 +60,6 @@ extern u32 *gameconf;
u8 *booter_ptr = NULL; u8 *booter_ptr = NULL;
size_t booter_size = 0; size_t booter_size = 0;
the_CFG normalCFG;
void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode,
int aspectRatio, u32 returnTo, u8 BootType, bool use_led) int aspectRatio, u32 returnTo, u8 BootType, bool use_led)
@ -81,20 +85,26 @@ void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 pat
normalCFG.use_led = use_led; normalCFG.use_led = use_led;
normalCFG.wip_list = get_wip_list(); normalCFG.wip_list = get_wip_list();
normalCFG.wip_count = get_wip_count(); normalCFG.wip_count = get_wip_count();
/* Copy CFG Into lower MEM1 so it doesnt get destroyed */
DCFlushRange(&normalCFG, sizeof(the_CFG));
the_CFG *lowCFG = (the_CFG*)MEM1_lo_alloc(sizeof(the_CFG));
memcpy(lowCFG, &normalCFG, sizeof(the_CFG));
DCFlushRange(&lowCFG, sizeof(the_CFG));
*EXT_ADDR_CFG = ((u32)lowCFG);
/* Unmount devices etc */ /* Unmount devices etc */
ShutdownBeforeExit(); ShutdownBeforeExit();
/* Copy in booter */
memcpy(EXT_ADDR, booter_ptr, booter_size);
DCFlushRange(EXT_ADDR, booter_size);
/* Copy CFG into new memory region */
memcpy(BooterConfig, &normalCFG, sizeof(the_CFG));
DCFlushRange(BooterConfig, sizeof(the_CFG));
/* Wii Games will need it */ /* Wii Games will need it */
net_wc24cleanup(); net_wc24cleanup();
/* Set proper time */ /* Set proper time */
settime(secs_to_ticks(time(NULL) - 946684800)); settime(secs_to_ticks(time(NULL) - 946684800));
/* Copy in booter */
memcpy(EXT_ADDR, booter_ptr, booter_size);
DCFlushRange(EXT_ADDR, booter_size);
/* Loader just for the booter */
memcpy(LDR_ADDR, extldr_bin, extldr_bin_size);
DCFlushRange(LDR_ADDR, extldr_bin_size);
/* Boot it */ /* Boot it */
JumpToEntry(EXT_ENTRY); JumpToEntry(LDR_ENTRY);
} }
bool ExternalBooter_LoadBooter(const char *booter_path) bool ExternalBooter_LoadBooter(const char *booter_path)

View File

@ -240,7 +240,7 @@ int get_frag_list(u8 *id, char *path, const u32 hdd_sector_size)
frag_concat(fa, fs); frag_concat(fa, fs);
} }
frag_list = MEM2_lo_alloc(sizeof(FragList)); frag_list = MEM1_lo_alloc(sizeof(FragList)); //completely safe for the booter
if(frag_list == NULL) if(frag_list == NULL)
goto out; goto out;
@ -275,7 +275,7 @@ int get_frag_list(u8 *id, char *path, const u32 hdd_sector_size)
out: out:
if(ret_val && frag_list != NULL) if(ret_val && frag_list != NULL)
{ {
MEM2_lo_free(frag_list); MEM1_lo_free(frag_list);
frag_list = NULL; frag_list = NULL;
} }
if(fs != NULL) if(fs != NULL)

View File

@ -59,7 +59,7 @@ int app_gameconfig_load(const char *discid, u8 *tempgameconf, u32 tempgameconfsi
{ {
if (gameconf == NULL) if (gameconf == NULL)
{ {
gameconf = (u32*) MEM2_alloc(65536); gameconf = (u32*) MEM1_lo_alloc(65536);
if (gameconf == NULL) if (gameconf == NULL)
return -1; return -1;
} }
@ -254,17 +254,25 @@ int ocarina_load_code(const u8 *cheat, u32 cheatSize)
codelist = (u8 *) 0x800028B8; codelist = (u8 *) 0x800028B8;
codelistend = (u8 *) 0x80003000; codelistend = (u8 *) 0x80003000;
code_buf = (u8 *)cheat; if(cheatSize <= 0)
code_size = cheatSize;
if(code_size <= 0)
{ {
//gprintf("Ocarina: No codes found\n"); //gprintf("Ocarina: No codes found\n");
code_buf = NULL; code_buf = NULL;
code_size = 0; code_size = 0;
return 0; return 0;
} }
//gprintf("Ocarina: Codes found.\n"); code_size = cheatSize;
code_buf = (u8*)MEM1_lo_alloc(code_size);
if(code_buf == NULL)
{
gprintf("Ocarina: Couldnt allocate buffer!\n");
code_buf = NULL;
code_size = 0;
return 0;
}
memcpy(code_buf, cheat, code_size);
gprintf("Ocarina: Codes found.\n");
DCFlushRange(code_buf, code_size); DCFlushRange(code_buf, code_size);
return code_size; return code_size;
} }