import fix94 forwarder v12.7

This commit is contained in:
Christopher Roy Bratusek 2013-01-03 22:30:48 +01:00
parent 671bede5d1
commit 785142ae1e
5 changed files with 522 additions and 19 deletions

View File

@ -15,10 +15,9 @@ include $(DEVKITPPC)/wii_rules
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET := forwarder
TARGET := boot
BUILD := build
SOURCES := source \
../svnrev
SOURCES := source
DATA := data
INCLUDES :=
@ -26,21 +25,26 @@ INCLUDES :=
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE)
CFLAGS = -Os -Wall $(MACHDEP) $(INCLUDE)
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
#---------------------------------------------------------------------------------
# move loader to another location - THANKS CREDIAR - 0x81330000 for HBC
#---------------------------------------------------------------------------------
#LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--section-start,.init=0x81000000
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
#LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--section-start,.init=0x80003f00
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lwiiuse -lbte -logc -lm
LIBS := -lfat -lntfs -lext2fs -lz -lbte -logc -lm -lwiiuse -lbte
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS :=
LIBDIRS := $(PORTLIBS)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
@ -64,7 +68,8 @@ CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
WADFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.wad*)))
DOLFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.dol)))
ELFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.elf)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
@ -75,9 +80,10 @@ else
export LD := $(CXX)
endif
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o)
export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o) \
$(addsuffix .o,$(DOLFILES)) \
$(addsuffix .o,$(ELFFILES)) $(addsuffix .o,$(BINFILES))
#---------------------------------------------------------------------------------
# build a list of include paths
@ -99,7 +105,7 @@ export OUTPUT := $(CURDIR)/$(TARGET)
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@ -111,6 +117,11 @@ run:
wiiload $(TARGET).dol
#---------------------------------------------------------------------------------
pack:
zip -9 loadMii.zip $(TARGET).dol ../icon.png ../meta.xml ../README
#---------------------------------------------------------------------------------
else
@ -123,9 +134,17 @@ $(OUTPUT).dol: $(OUTPUT).elf
$(OUTPUT).elf: $(OFILES)
#---------------------------------------------------------------------------------
# This rule links in binary data with extension
# This rule links in binary data with the .jpg extension
#---------------------------------------------------------------------------------
%.wad.o : %.wad
%.dol.o : %.dol
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
%.elf.o : %.elf
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
%.bin.o : %.bin
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)

Binary file not shown.

View File

@ -0,0 +1,126 @@
#include <gccore.h>
#include <ogc/mutex.h>
#include <ogc/system.h>
#include <ogc/usbstorage.h>
#include <ogc/lwp_watchdog.h>
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#include <fat.h>
#include <ntfs.h>
#include <ext2.h>
#include <sdcard/wiisd_io.h>
#include <unistd.h>
#include <time.h>
#include "devicemounter.h"
#define MAX_SECTOR_SIZE 4096
//these are the only stable and speed is good
#define CACHE 8
#define SECTORS 64
typedef struct _PARTITION_RECORD {
u8 status; /* Partition status; see above */
u8 chs_start[3]; /* Cylinder-head-sector address to first block of partition */
u8 type; /* Partition type; see above */
u8 chs_end[3]; /* Cylinder-head-sector address to last block of partition */
u32 lba_start; /* Local block address to first sector of partition */
u32 block_count; /* Number of blocks in partition */
} __attribute__((__packed__)) PARTITION_RECORD;
typedef struct _MASTER_BOOT_RECORD {
u8 code_area[446]; /* Code area; normally empty */
PARTITION_RECORD partitions[4]; /* 4 primary partitions */
u16 signature; /* MBR signature; 0xAA55 */
} __attribute__((__packed__)) MASTER_BOOT_RECORD;
#define PARTITION_TYPE_LINUX 0x83
#define le32(i) (((((u32) i) & 0xFF) << 24) | ((((u32) i) & 0xFF00) << 8) | \
((((u32) i) & 0xFF0000) >> 8) | ((((u32) i) & 0xFF000000) >> 24))
int USBDevice_Init()
{
time_t start = time(0);
while(time(0) - start < 10) // 10 sec
{
if(__io_usbstorage.startup() && __io_usbstorage.isInserted())
break;
usleep(200000); // 1/5 sec
}
if(!__io_usbstorage.startup() || !__io_usbstorage.isInserted())
return -1;
int i;
MASTER_BOOT_RECORD *mbr = (MASTER_BOOT_RECORD *) malloc(MAX_SECTOR_SIZE);
char *BootSector = (char *) malloc(MAX_SECTOR_SIZE);
if(!mbr || !BootSector)
return -1;
__io_usbstorage.readSectors(0, 1, mbr);
for(i = 0; i < 4; ++i)
{
if(mbr->partitions[i].type == 0)
continue;
__io_usbstorage.readSectors(le32(mbr->partitions[i].lba_start), 1, BootSector);
if(*((u16 *) (BootSector + 0x1FE)) == 0x55AA)
{
//! Partition typ can be missleading the correct partition format. Stupid lazy ass Partition Editors.
if(memcmp(BootSector + 0x36, "FAT", 3) == 0 || memcmp(BootSector + 0x52, "FAT", 3) == 0)
fatMount(DeviceName[USB1+i], &__io_usbstorage, le32(mbr->partitions[i].lba_start), CACHE, SECTORS);
else if (memcmp(BootSector + 0x03, "NTFS", 4) == 0)
ntfsMount(DeviceName[USB1+i], &__io_usbstorage, le32(mbr->partitions[i].lba_start), CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER | NTFS_IGNORE_CASE);
}
else if(mbr->partitions[i].type == PARTITION_TYPE_LINUX)
ext2Mount(DeviceName[USB1+i], &__io_usbstorage, le32(mbr->partitions[i].lba_start), CACHE, SECTORS, EXT2_FLAG_DEFAULT);
}
free(mbr);
free(BootSector);
return -1;
}
void USBDevice_deInit()
{
int dev;
char Name[20];
for(dev = USB1; dev <= USB4; ++dev)
{
sprintf(Name, "%s:/", DeviceName[dev]);
fatUnmount(Name);
ntfsUnmount(Name, true);
ext2Unmount(Name);
}
//Let's not shutdown so it stays awake for the application
__io_usbstorage.shutdown();
USB_Deinitialize();
}
int SDCard_Init()
{
if(!__io_wiisd.startup() || !__io_wiisd.isInserted())
return -1;
if(fatMount(DeviceName[SD], &__io_wiisd, 0, CACHE, SECTORS))
return 1;
return -1;
}
void SDCard_deInit()
{
char Name[20];
sprintf(Name, "%s:/", DeviceName[SD]);
//closing all open Files write back the cache and then shutdown em!
fatUnmount(Name);
//Let's not shutdown so it stays awake for the application
__io_wiisd.shutdown();
}

View File

@ -0,0 +1,37 @@
#ifndef _FATMOUNTER_H_
#define _FATMOUNTER_H_
#ifdef __cplusplus
extern "C"
{
#endif
enum
{
SD = 0,
USB1,
USB2,
USB3,
USB4,
MAXDEVICES
};
static const char DeviceName[MAXDEVICES][6] =
{
"sd",
"usb1",
"usb2",
"usb3",
"usb4"
};
int USBDevice_Init();
void USBDevice_deInit();
int SDCard_Init();
void SDCard_deInit();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,11 +1,332 @@
 /****************************************************************************
* Copyright 2009 The Lemon Man and thanks to luccax, Wiipower, Aurelio and crediar
* Copyright 2010 Dimok
* Copyright 2011 FIX94, oggzee
*
* Original forwarder source by
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#include <gccore.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ogc/machine/processor.h>
#include <wiiuse/wpad.h>
int main(int argc, char **argv)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "devicemounter.h"
#define EXECUTE_ADDR ((u8 *) 0x92000000)
#define BOOTER_ADDR ((u8 *) 0x93000000)
#define ARGS_ADDR ((u8 *) 0x93200000)
#define MAX_CMDLINE 4096
#define MAX_ARGV 1000
struct __argv args;
char *a_argv[MAX_ARGV];
char *meta_buf = NULL;
typedef void (*entrypoint) (void);
extern void __exception_setreload(int t);
extern void __exception_closeall();
extern const u8 app_booter_bin[];
extern const u32 app_booter_bin_size;
static FILE *open_file(const char *dev, char *filepath)
{
VIDEO_Init();
sprintf(filepath, "%s:/apps/usbloader/boot.dol", dev);
FILE *exeFile = fopen(filepath ,"rb");
WII_LaunchTitle(0x0001000154484246);
if (exeFile == NULL)
{
sprintf(filepath, "%s:/apps/usbloader_cfg/boot.dol", dev);
exeFile = fopen(filepath ,"rb");
}
if (exeFile == NULL)
{
sprintf(filepath, "%s:/apps/usbloader/boot.elf", dev);
exeFile = fopen(filepath ,"rb");
}
if (exeFile == NULL)
{
sprintf(filepath, "%s:/apps/usbloader_cfg/boot.elf", dev);
exeFile = fopen(filepath ,"rb");
}
return exeFile;
}
void SystemMenu()
{
*(vu32*)0x8132FFFB = 0x50756e65;
DCFlushRange((void *)(0x8132FFFB), 4);
ICInvalidateRange((void *)(0x8132FFFB), 4);
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
}
bool IsDollZ(u8 *buff)
{
int ret;
u8 dollz_stamp[] = {0x3C};
int dollz_offs = 0x100;
ret = memcmp(&buff[dollz_offs], dollz_stamp, sizeof(dollz_stamp));
if (ret == 0)
return true;
return false;
}
void arg_init()
{
memset(&args, 0, sizeof(args));
memset(a_argv, 0, sizeof(a_argv));
args.argvMagic = ARGV_MAGIC;
args.length = 1; // double \0\0
args.argc = 0;
//! Put the argument into mem2 too, to avoid overwriting it
args.commandLine = (char *) ARGS_ADDR + sizeof(args);
args.argv = a_argv;
args.endARGV = a_argv;
}
char* strcopy(char *dest, const char *src, int size)
{
strncpy(dest,src,size);
dest[size-1] = 0;
return dest;
}
int arg_addl(char *arg, int len)
{
if (args.argc >= MAX_ARGV)
return -1;
if (args.length + len + 1 > MAX_CMDLINE)
return -1;
strcopy(args.commandLine + args.length - 1, arg, len+1);
args.length += len + 1; // 0 term.
args.commandLine[args.length - 1] = 0; // double \0\0
args.argc++;
args.endARGV = args.argv + args.argc;
return 0;
}
}
int arg_add(char *arg)
{
return arg_addl(arg, strlen(arg));
}
int load_file(char *name, void *buf, int size)
{
int fd;
int ret;
fd = open(name, O_RDONLY);
if (fd < 0)
return -1;
ret = read(fd, buf, size);
close(fd);
if (ret != size)
return -2;
return 0;
}
void load_meta(const char *exe_path)
{
char meta_path[200];
const char *p;
struct stat st;
p = strrchr(exe_path, '/');
snprintf(meta_path, sizeof(meta_path), "%.*smeta.xml", p ? p-exe_path+1 : 0, exe_path);
if (stat(meta_path, &st) != 0)
return;
if (st.st_size > 64*1024)
return;
// +1 so that the buf is 0 terminated
meta_buf = calloc(st.st_size + 1, 1);
if (!meta_buf)
return;
load_file(meta_path, meta_buf, st.st_size);
}
void strip_comments(char *buf)
{
char *p = buf; // start of comment
char *e; // end of comment
int len;
while (p && *p)
{
p = strstr(p, "<!--");
if (!p)
break;
e = strstr(p, "-->");
if (!e)
{
*p = 0; // terminate
break;
}
e += 3;
len = strlen(e);
memmove(p, e, len + 1); // +1 for 0 termination
}
}
void parse_meta()
{
char *p;
char *e, *end;
if (meta_buf == NULL)
return;
strip_comments(meta_buf);
if (!strstr(meta_buf, "<app") || !strstr(meta_buf, "</app>"))
return;
p = strstr(meta_buf, "<arguments>");
if (!p)
return;
end = strstr(meta_buf, "</arguments>");
if (!end)
return;
do
{
p = strstr(p, "<arg>");
if (!p)
return;
p += 5; //strlen("<arg>");
e = strstr(p, "</arg>");
if (!e)
return;
arg_addl(p, e-p);
p = e + 6;
}
while (p < end);
if (meta_buf)
{
free(meta_buf);
meta_buf = NULL;
}
}
int main(int argc, char *argv[])
{
u32 cookie;
FILE *exeFile = NULL;
void *exeBuffer = (void *)EXECUTE_ADDR;
u32 exeSize = 0;
entrypoint exeEntryPoint;
__exception_setreload(0);
// initial video
void *xfb = NULL;
GXRModeObj *rmode = NULL;
VIDEO_Init();
rmode = VIDEO_GetPreferredMode(NULL);
xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
VIDEO_Configure(rmode);
VIDEO_SetNextFramebuffer(xfb);
VIDEO_SetBlack(TRUE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(rmode->viTVMode&VI_NON_INTERLACE)
VIDEO_WaitVSync();
char filepath[200];
//init wiimote
WPAD_Init();
// try SD Card First
SDCard_Init();
exeFile = open_file(DeviceName[SD], filepath);
// if app not found on SD Card try USB
if (exeFile == NULL)
{
USBDevice_Init();
int dev;
for(dev = USB1; dev < MAXDEVICES; ++dev)
{
if(!exeFile)
exeFile = open_file(DeviceName[dev], filepath);
}
}
// if nothing found exiting
if (exeFile == NULL)
{
fclose(exeFile);
SDCard_deInit();
USBDevice_deInit();
SystemMenu();
}
fseek(exeFile, 0, SEEK_END);
exeSize = ftell(exeFile);
rewind(exeFile);
if(fread(exeBuffer, 1, exeSize, exeFile) != exeSize)
{
fclose(exeFile);
SDCard_deInit();
USBDevice_deInit();
SystemMenu();
}
fclose(exeFile);
if (IsDollZ(exeBuffer) == false)
{
arg_init();
arg_add(filepath); // argv[0] = filepath
// load meta.xml
load_meta(filepath);
// parse <arguments> in meta.xml
parse_meta();
}
memcpy(BOOTER_ADDR, app_booter_bin, app_booter_bin_size);
DCFlushRange(BOOTER_ADDR, app_booter_bin_size);
memcpy(ARGS_ADDR, &args, sizeof(args));
DCFlushRange(ARGS_ADDR, sizeof(args) + args.length);
SDCard_deInit();
USBDevice_deInit();
exeEntryPoint = (entrypoint)BOOTER_ADDR;
/* cleaning up and load dol */
SYS_ResetSystem(SYS_SHUTDOWN, 0, 0);
_CPU_ISR_Disable(cookie);
__exception_closeall();
exeEntryPoint();
_CPU_ISR_Restore(cookie);
return 0;
}