mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-15 16:05:10 +01:00
makes the forwarder fit for loading the "USB Loader GX" from USB-Device
Strategy to find the boot.dol from "USB Loader GX": 1. looking for "/config/GXGlobal.cfg" first on "SD:/" and then on "USB:/" 2.1. when cfg is found and update_path is set, then searches for "boot.dol"/"boot.elf" in "update_path" 2.2. when cfg isn't found or update_path isn't set, then looking for "boot.dol"/"boot.elf" in "apps/usbloader_gx/" first on "SD:/" and then on "USB:/" 3. if the Loader is found, then LOAD and RUN it. Otherwise exits the for-warder Primarily searched on SD-Card. This makes easier to test new versions.
This commit is contained in:
parent
11e17e07ab
commit
e9423c807e
@ -8,6 +8,8 @@
|
||||
|
||||
#include "cfg.h"
|
||||
|
||||
char update_path[150]="";
|
||||
|
||||
static char *cfg_name, *cfg_val;
|
||||
|
||||
char* strcopy(char *dest, char *src, int size)
|
||||
|
@ -6,7 +6,7 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
char update_path[150];
|
||||
extern char update_path[150];
|
||||
|
||||
void cfg_set(char *name, char *val);
|
||||
bool cfg_parsefile(char * fname, void (*set_func)(char*, char*));
|
||||
|
184
source/fatmounter.c
Normal file
184
source/fatmounter.c
Normal file
@ -0,0 +1,184 @@
|
||||
#include <fat.h>
|
||||
#include <string.h>
|
||||
#include <sys/dir.h>
|
||||
#include <sys/iosupport.h>
|
||||
#include <ogc/lwp_watchdog.h>
|
||||
#include <ogc/mutex.h>
|
||||
#include <ogc/system.h>
|
||||
#include <ogc/usbstorage.h>
|
||||
#include <sdcard/wiisd_io.h>
|
||||
|
||||
//these are the only stable and speed is good
|
||||
#define CACHE 32
|
||||
#define SECTORS 128
|
||||
|
||||
enum BPB {
|
||||
BPB_jmpBoot = 0x00,
|
||||
BPB_OEMName = 0x03,
|
||||
// BIOS Parameter Block
|
||||
BPB_bytesPerSector = 0x0B,
|
||||
BPB_sectorsPerCluster = 0x0D,
|
||||
BPB_reservedSectors = 0x0E,
|
||||
BPB_numFATs = 0x10,
|
||||
BPB_rootEntries = 0x11,
|
||||
BPB_numSectorsSmall = 0x13,
|
||||
BPB_mediaDesc = 0x15,
|
||||
BPB_sectorsPerFAT = 0x16,
|
||||
BPB_sectorsPerTrk = 0x18,
|
||||
BPB_numHeads = 0x1A,
|
||||
BPB_numHiddenSectors = 0x1C,
|
||||
BPB_numSectors = 0x20,
|
||||
// Ext BIOS Parameter Block for FAT16
|
||||
BPB_FAT16_driveNumber = 0x24,
|
||||
BPB_FAT16_reserved1 = 0x25,
|
||||
BPB_FAT16_extBootSig = 0x26,
|
||||
BPB_FAT16_volumeID = 0x27,
|
||||
BPB_FAT16_volumeLabel = 0x2B,
|
||||
BPB_FAT16_fileSysType = 0x36,
|
||||
// Bootcode
|
||||
BPB_FAT16_bootCode = 0x3E,
|
||||
// FAT32 extended block
|
||||
BPB_FAT32_sectorsPerFAT32 = 0x24,
|
||||
BPB_FAT32_extFlags = 0x28,
|
||||
BPB_FAT32_fsVer = 0x2A,
|
||||
BPB_FAT32_rootClus = 0x2C,
|
||||
BPB_FAT32_fsInfo = 0x30,
|
||||
BPB_FAT32_bkBootSec = 0x32,
|
||||
// Ext BIOS Parameter Block for FAT32
|
||||
BPB_FAT32_driveNumber = 0x40,
|
||||
BPB_FAT32_reserved1 = 0x41,
|
||||
BPB_FAT32_extBootSig = 0x42,
|
||||
BPB_FAT32_volumeID = 0x43,
|
||||
BPB_FAT32_volumeLabel = 0x47,
|
||||
BPB_FAT32_fileSysType = 0x52,
|
||||
// Bootcode
|
||||
BPB_FAT32_bootCode = 0x5A,
|
||||
BPB_bootSig_55 = 0x1FE,
|
||||
BPB_bootSig_AA = 0x1FF
|
||||
};
|
||||
|
||||
static const char FAT_SIG[3] = {'F', 'A', 'T'};
|
||||
|
||||
#define BYTES_PER_READ 512
|
||||
|
||||
static bool _FAT_partition_isFAT(const DISC_INTERFACE* disc, sec_t startSector)
|
||||
{
|
||||
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
|
||||
if (!disc->readSectors(startSector, 1, sectorBuffer)) {
|
||||
return false;
|
||||
}
|
||||
// Make sure it is a valid BPB
|
||||
if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now verify that this is indeed a FAT partition
|
||||
if (memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) &&
|
||||
memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// check again for the last two cases to make sure that we really have a FAT filesystem here
|
||||
// and won't corrupt any data
|
||||
if(memcmp(sectorBuffer + BPB_FAT16_fileSysType, "FAT", 3) != 0 && memcmp(sectorBuffer + BPB_FAT32_fileSysType, "FAT32", 5) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static inline uint32_t u8array_to_u32 (const uint8_t* item, int offset) {
|
||||
return ( item[offset] | (item[offset + 1] << 8) | (item[offset + 2] << 16) | (item[offset + 3] << 24));
|
||||
}
|
||||
|
||||
sec_t GetFATPartition(const DISC_INTERFACE* disc)
|
||||
{
|
||||
int i;
|
||||
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
|
||||
sec_t startSector = 0;
|
||||
|
||||
if(!disc->startup())
|
||||
return 0;
|
||||
|
||||
// Read first sector of disc
|
||||
if (!disc->readSectors(0, 1, sectorBuffer))
|
||||
startSector = 0;
|
||||
|
||||
// Make sure it is a valid MBR or boot sector
|
||||
if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA))
|
||||
startSector = 0;
|
||||
|
||||
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
|
||||
{
|
||||
// Check if there is a FAT string, which indicates this is a boot sector
|
||||
startSector = 0;
|
||||
}
|
||||
else if (!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
|
||||
{
|
||||
// Check for FAT32
|
||||
startSector = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is an MBR
|
||||
// Find first valid partition from MBR
|
||||
// First check for an active partition
|
||||
for (i=0x1BE; (i < 0x1FE) && (sectorBuffer[i] != 0x80); i+= 0x10);
|
||||
// If it find an active partition, check for FAT-Partition
|
||||
if ( i != 0x1FE && !_FAT_partition_isFAT(disc, u8array_to_u32(sectorBuffer, 0x8 + i)) )
|
||||
i = 0x1FE;
|
||||
|
||||
// If it didn't find an active partition, search for any valid partition
|
||||
if (i == 0x1FE)
|
||||
{
|
||||
for (i=0x1BE; i < 0x1FE; i+= 0x10)
|
||||
{
|
||||
if ( sectorBuffer[i+0x04] != 0x00 && _FAT_partition_isFAT(disc, u8array_to_u32(sectorBuffer, 0x8 + i)) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i != 0x1FE)
|
||||
startSector = u8array_to_u32(sectorBuffer, 0x8 + i);;
|
||||
}
|
||||
disc->shutdown();
|
||||
return startSector;
|
||||
}
|
||||
|
||||
int USBDevice_Init()
|
||||
{
|
||||
//closing all open Files write back the cache and then shutdown em!
|
||||
fatUnmount("USB:/");
|
||||
//right now mounts first FAT-partition
|
||||
if (fatMount("USB", &__io_usbstorage, GetFATPartition(&__io_usbstorage), CACHE, SECTORS)) {
|
||||
//try first mount with libogc
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void USBDevice_deInit()
|
||||
{
|
||||
//closing all open Files write back the cache and then shutdown em!
|
||||
fatUnmount("USB:/");
|
||||
}
|
||||
|
||||
int isSdInserted()
|
||||
{
|
||||
return __io_wiisd.isInserted();
|
||||
}
|
||||
|
||||
int SDCard_Init()
|
||||
{
|
||||
//closing all open Files write back the cache and then shutdown em!
|
||||
fatUnmount("SD:/");
|
||||
//right now mounts first FAT-partition
|
||||
if (fatMount("SD", &__io_wiisd, GetFATPartition(&__io_wiisd), CACHE, SECTORS))
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void SDCard_deInit()
|
||||
{
|
||||
//closing all open Files write back the cache and then shutdown em!
|
||||
fatUnmount("SD:/");
|
||||
}
|
19
source/fatmounter.h
Normal file
19
source/fatmounter.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef _FATMOUNTER_H_
|
||||
#define _FATMOUNTER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
int USBDevice_Init();
|
||||
void USBDevice_deInit();
|
||||
int isSdInserted();
|
||||
int SDCard_Init();
|
||||
void SDCard_deInit();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
166
source/main.cpp
166
source/main.cpp
@ -31,6 +31,7 @@
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ogc/machine/processor.h>
|
||||
|
||||
#include "pngu/pngu.h"
|
||||
@ -39,6 +40,7 @@
|
||||
#include "dolloader.h"
|
||||
#include "elfloader.h"
|
||||
#include "cfg.h"
|
||||
#include "fatmounter.h"
|
||||
|
||||
|
||||
PNGUPROP imgProp;
|
||||
@ -78,105 +80,123 @@ void Background_Show(int x, int y, int z, u8 * data, int angle, int scaleX, int
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
u32 cookie;
|
||||
FILE *exeFile = NULL;
|
||||
void *exeBuffer = (void *)EXECUTABLE_MEM_ADDR;
|
||||
int exeSize = 0;
|
||||
u32 exeEntryPointAddress = 0;
|
||||
entrypoint exeEntryPoint;
|
||||
/* int videomod */
|
||||
InitVideo();
|
||||
/* get imagedata */
|
||||
u8 * imgdata = GetImageData();
|
||||
/* fadein of image */
|
||||
for(int i = 0; i < 255; i = i+10)
|
||||
{
|
||||
if(i>255) i = 255;
|
||||
Background_Show(0, 0, 0, imgdata, 0, 1, 1, i);
|
||||
Menu_Render();
|
||||
}
|
||||
/* check devices */
|
||||
SDCard_Init();
|
||||
USBDevice_Init();
|
||||
char cfgpath[256];
|
||||
|
||||
|
||||
/* int videomod */
|
||||
InitVideo();
|
||||
|
||||
/* get imagedata */
|
||||
u8 * imgdata = GetImageData();
|
||||
|
||||
/* fadein of image */
|
||||
for(int i = 0; i < 255; i = i+10) {
|
||||
if(i>255) i = 255;
|
||||
Background_Show(0, 0, 0, imgdata, 0, 1, 1, i);
|
||||
Menu_Render();
|
||||
}
|
||||
/* check devices */
|
||||
__io_wiisd.startup();
|
||||
fatMount("SD", &__io_wiisd, 0, 32, 128);
|
||||
|
||||
char cfgpath[40];
|
||||
sprintf(cfgpath, "SD:/config/GXGlobal.cfg");
|
||||
|
||||
if(!cfg_parsefile(cfgpath, &cfg_set)) {
|
||||
/* Open dol File and check exist */
|
||||
exeFile = fopen ("SD:/apps/usbloader_gx/boot.dol" ,"rb");
|
||||
if (exeFile==NULL) {
|
||||
fclose(exeFile);
|
||||
exeFile = fopen ("SD:/apps/usbloader_gx/boot.elf" ,"rb");
|
||||
if (exeFile==NULL) {
|
||||
fclose(exeFile);
|
||||
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sprintf(cfgpath, "%sboot.dol", update_path);
|
||||
/* Open dol File and check exist */
|
||||
exeFile = fopen (cfgpath, "rb");
|
||||
if (exeFile==NULL) {
|
||||
fclose(exeFile);
|
||||
sprintf(cfgpath, "%sboot.elf", update_path);
|
||||
exeFile = fopen (cfgpath,"rb");
|
||||
if (exeFile==NULL) {
|
||||
fclose(exeFile);
|
||||
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
|
||||
}
|
||||
}
|
||||
sprintf(cfgpath, "SD:/config/GXGlobal.cfg");
|
||||
if(!cfg_parsefile(cfgpath, &cfg_set)) //no cfg-File on SD: try USB:
|
||||
{
|
||||
sprintf(cfgpath, "USB:/config/GXGlobal.cfg");
|
||||
cfg_parsefile(cfgpath, &cfg_set);
|
||||
}
|
||||
if(update_path[0] == '\0') // non cfg-File loaded or update_path not set
|
||||
{
|
||||
/* Open dol File and check exist */
|
||||
strcpy(cfgpath, "SD:/apps/usbloader_gx/boot.dol");
|
||||
exeFile = fopen (cfgpath ,"rb");
|
||||
if (exeFile==NULL)
|
||||
{
|
||||
strcpy(cfgpath, "SD:/apps/usbloader_gx/boot.elf");
|
||||
exeFile = fopen (cfgpath ,"rb");
|
||||
}
|
||||
if (exeFile==NULL)
|
||||
{
|
||||
strcpy(cfgpath, "USB:/apps/usbloader_gx/boot.dol");
|
||||
exeFile = fopen (cfgpath ,"rb");
|
||||
}
|
||||
if (exeFile==NULL)
|
||||
{
|
||||
strcpy(cfgpath, "USB:/apps/usbloader_gx/boot.elf");
|
||||
exeFile = fopen (cfgpath ,"rb");
|
||||
}
|
||||
if (exeFile==NULL)
|
||||
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(cfgpath, "%sboot.dol", update_path);
|
||||
/* Open dol File and check exist */
|
||||
exeFile = fopen (cfgpath, "rb");
|
||||
if (exeFile==NULL)
|
||||
{
|
||||
sprintf(cfgpath, "%sboot.elf", update_path);
|
||||
exeFile = fopen (cfgpath,"rb");
|
||||
}
|
||||
if (exeFile==NULL)
|
||||
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
|
||||
}
|
||||
|
||||
fseek (exeFile, 0, SEEK_END);
|
||||
exeSize = ftell(exeFile);
|
||||
fseek (exeFile, 0, SEEK_SET);
|
||||
if(fread (exeBuffer, 1, exeSize, exeFile) != (unsigned int) exeSize) {
|
||||
printf("Can't open DOL File...\n");
|
||||
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);;
|
||||
}
|
||||
|
||||
if(fread (exeBuffer, 1, exeSize, exeFile) != (unsigned int) exeSize)
|
||||
{
|
||||
printf("Can't open DOL File...\n");
|
||||
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
|
||||
}
|
||||
fclose (exeFile);
|
||||
|
||||
/* load entry point */
|
||||
struct __argv args[10];
|
||||
/* load entry point */
|
||||
struct __argv args;
|
||||
bzero(&args, sizeof(args));
|
||||
args.argvMagic = ARGV_MAGIC;
|
||||
args.length = strlen(cfgpath) + 2;
|
||||
args.commandLine = (char*)malloc(args.length);
|
||||
if (!args.commandLine) SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
|
||||
strcpy(args.commandLine, cfgpath);
|
||||
args.commandLine[args.length - 1] = '\x00';
|
||||
args.argc = 1;
|
||||
args.argv = &args.commandLine;
|
||||
args.endARGV = args.argv + 1;
|
||||
|
||||
int ret = valid_elf_image(exeBuffer);
|
||||
if (ret == 1) {
|
||||
exeEntryPointAddress = load_elf_image(exeBuffer);
|
||||
} else {
|
||||
exeEntryPointAddress = load_dol_image(exeBuffer, args);
|
||||
if (ret == 1)
|
||||
exeEntryPointAddress = load_elf_image(exeBuffer);
|
||||
else
|
||||
exeEntryPointAddress = load_dol_image(exeBuffer, &args);
|
||||
|
||||
/* fadeout of image */
|
||||
for(int i = 255; i > 1; i = i-7)
|
||||
{
|
||||
if(i < 0) i = 0;
|
||||
Background_Show(0, 0, 0, imgdata, 0, 1, 1, i);
|
||||
Menu_Render();
|
||||
}
|
||||
|
||||
/* fadeout of image */
|
||||
for(int i = 255; i > 1; i = i-7) {
|
||||
if(i < 0) i = 0;
|
||||
Background_Show(0, 0, 0, imgdata, 0, 1, 1, i);
|
||||
Menu_Render();
|
||||
}
|
||||
|
||||
fatUnmount("SD");
|
||||
__io_wiisd.shutdown();
|
||||
StopGX();
|
||||
|
||||
SDCard_deInit();
|
||||
USBDevice_deInit();
|
||||
StopGX();
|
||||
if (exeEntryPointAddress == 0) {
|
||||
printf("EntryPointAddress failed...\n");
|
||||
printf("EntryPointAddress failed...\n");
|
||||
SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);;
|
||||
}
|
||||
|
||||
exeEntryPoint = (entrypoint) exeEntryPointAddress;
|
||||
|
||||
/* cleaning up and load dol */
|
||||
/* cleaning up and load dol */
|
||||
SYS_ResetSystem(SYS_SHUTDOWN, 0, 0);
|
||||
_CPU_ISR_Disable (cookie);
|
||||
__exception_closeall ();
|
||||
exeEntryPoint ();
|
||||
_CPU_ISR_Restore (cookie);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user