mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-16 23:37:11 +00:00
Downsize wii/app_booter
This commit is contained in:
parent
dfeefc0e16
commit
10ec315a43
@ -30,7 +30,7 @@ CFLAGS += -Wall -O2 -ffreestanding -std=gnu99 $(MACHDEP) $(INCLUDE)
|
|||||||
|
|
||||||
LDFLAGS := -T link.ld
|
LDFLAGS := -T link.ld
|
||||||
|
|
||||||
OBJ = crt0.o dolloader.o elfloader.o main.o ../../libretro-common/crt/string.o sync.o
|
OBJ = crt0.o main.o ../../libretro-common/crt/string.o
|
||||||
|
|
||||||
all: $(BIN_TARGET)
|
all: $(BIN_TARGET)
|
||||||
|
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
#include <gctypes.h>
|
|
||||||
#include "string.h"
|
|
||||||
#include "dolloader.h"
|
|
||||||
#include "sync.h"
|
|
||||||
|
|
||||||
#define ARENA1_HI_LIMIT 0x81800000
|
|
||||||
|
|
||||||
typedef struct _dolheade
|
|
||||||
{
|
|
||||||
u32 text_pos[7];
|
|
||||||
u32 data_pos[11];
|
|
||||||
u32 text_start[7];
|
|
||||||
u32 data_start[11];
|
|
||||||
u32 text_size[7];
|
|
||||||
u32 data_size[11];
|
|
||||||
u32 bss_start;
|
|
||||||
u32 bss_size;
|
|
||||||
u32 entry_point;
|
|
||||||
} dolheader;
|
|
||||||
|
|
||||||
u32 load_dol_image(const void *dolstart)
|
|
||||||
{
|
|
||||||
u32 i;
|
|
||||||
dolheader *dolfile = NULL;
|
|
||||||
if(!dolstart)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
dolfile = (dolheader *) dolstart;
|
|
||||||
|
|
||||||
for (i = 0; i < 7; i++)
|
|
||||||
{
|
|
||||||
if ((!dolfile->text_size[i]) || (dolfile->text_start[i] < 0x100))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
memcpy((void *) dolfile->text_start[i], dolstart + dolfile->text_pos[i], dolfile->text_size[i]);
|
|
||||||
sync_before_exec((void *) dolfile->text_start[i], dolfile->text_size[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 11; i++)
|
|
||||||
{
|
|
||||||
if ((!dolfile->data_size[i]) || (dolfile->data_start[i] < 0x100))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
memcpy((void *) dolfile->data_start[i], dolstart + dolfile->data_pos[i], dolfile->data_size[i]);
|
|
||||||
sync_before_exec((void *) dolfile->data_start[i], dolfile->data_size[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dolfile->entry_point;
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
#ifndef _DOLLOADER_H_
|
|
||||||
#define _DOLLOADER_H_
|
|
||||||
|
|
||||||
typedef void (*entrypoint) (void);
|
|
||||||
|
|
||||||
u32 load_dol_image(const void *dolstart);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2001 William L. Pitts
|
|
||||||
* Modifications (c) 2004 Felix Domke
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms are freely
|
|
||||||
* permitted provided that the above copyright notice and this
|
|
||||||
* paragraph and the following disclaimer are duplicated in all
|
|
||||||
* such forms.
|
|
||||||
*
|
|
||||||
* This software is provided "AS IS" and without any express or
|
|
||||||
* implied warranties, including, without limitation, the implied
|
|
||||||
* warranties of merchantability and fitness for a particular
|
|
||||||
* purpose.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "elf_abi.h"
|
|
||||||
#include "sync.h"
|
|
||||||
#include "string.h"
|
|
||||||
|
|
||||||
/* ======================================================================
|
|
||||||
* Determine if a valid ELF image exists at the given memory location.
|
|
||||||
* First looks at the ELF header magic field, the makes sure that it is
|
|
||||||
* executable and makes sure that it is for a PowerPC.
|
|
||||||
* ====================================================================== */
|
|
||||||
s32 valid_elf_image (void *addr)
|
|
||||||
{
|
|
||||||
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
|
|
||||||
|
|
||||||
if (!IS_ELF (*ehdr))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (ehdr->e_type != ET_EXEC)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (ehdr->e_machine != EM_PPC)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ======================================================================
|
|
||||||
* A very simple elf loader, assumes the image is valid, returns the
|
|
||||||
* entry point address.
|
|
||||||
* ====================================================================== */
|
|
||||||
|
|
||||||
u32 load_elf_image (void *elfstart)
|
|
||||||
{
|
|
||||||
u8 *image;
|
|
||||||
int i;
|
|
||||||
Elf32_Phdr *phdrs = NULL;
|
|
||||||
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) elfstart;
|
|
||||||
|
|
||||||
if(ehdr->e_phoff == 0 || ehdr->e_phnum == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(ehdr->e_phentsize != sizeof(Elf32_Phdr))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
phdrs = (Elf32_Phdr*)(elfstart + ehdr->e_phoff);
|
|
||||||
|
|
||||||
for (i = 0; i < ehdr->e_phnum; i++)
|
|
||||||
{
|
|
||||||
if(phdrs[i].p_type != PT_LOAD)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
phdrs[i].p_paddr &= 0x3FFFFFFF;
|
|
||||||
phdrs[i].p_paddr |= 0x80000000;
|
|
||||||
|
|
||||||
if(phdrs[i].p_filesz > phdrs[i].p_memsz)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(!phdrs[i].p_filesz)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
image = (u8 *) (elfstart + phdrs[i].p_offset);
|
|
||||||
memcpy ((void *) phdrs[i].p_paddr, (const void *) image, phdrs[i].p_filesz);
|
|
||||||
|
|
||||||
sync_before_exec ((void *) phdrs[i].p_paddr, phdrs[i].p_memsz);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((ehdr->e_entry & 0x3FFFFFFF) | 0x80000000);
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
#ifndef _ELFLOADER_H_
|
|
||||||
#define _ELFLOADER_H_
|
|
||||||
|
|
||||||
s32 valid_elf_image (void *addr);
|
|
||||||
u32 load_elf_image (void *addr);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,25 +1,147 @@
|
|||||||
/* Copyright 2011 Dimok
|
/* Copyright 2011 Dimok
|
||||||
This code is licensed to you under the terms of the GNU GPL, version 2;
|
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 */
|
see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt */
|
||||||
#include <gccore.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
#include "dolloader.h"
|
#include <gccore.h>
|
||||||
#include "elfloader.h"
|
|
||||||
#include "sync.h"
|
#include "elf_abi.h"
|
||||||
|
|
||||||
#define EXECUTABLE_MEM_ADDR 0x91800000
|
#define EXECUTABLE_MEM_ADDR 0x91800000
|
||||||
#define SYSTEM_ARGV ((struct __argv *) 0x93200000)
|
#define SYSTEM_ARGV ((struct __argv *) 0x93200000)
|
||||||
|
|
||||||
|
#define ARENA1_HI_LIMIT 0x81800000
|
||||||
|
|
||||||
|
typedef struct _dolheade
|
||||||
|
{
|
||||||
|
u32 text_pos[7];
|
||||||
|
u32 data_pos[11];
|
||||||
|
u32 text_start[7];
|
||||||
|
u32 data_start[11];
|
||||||
|
u32 text_size[7];
|
||||||
|
u32 data_size[11];
|
||||||
|
u32 bss_start;
|
||||||
|
u32 bss_size;
|
||||||
|
u32 entry_point;
|
||||||
|
} dolheader;
|
||||||
|
|
||||||
|
typedef void (*entrypoint)(void);
|
||||||
|
|
||||||
|
static void sync_before_exec(const void *p, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t a = (uint32_t)p & ~0x1f;
|
||||||
|
uint32_t b = ((uint32_t)p + len + 0x1f) & ~0x1f;
|
||||||
|
|
||||||
|
for ( ; a < b; a += 32)
|
||||||
|
asm("dcbst 0,%0 ; sync ; icbi 0,%0" : : "b"(a));
|
||||||
|
|
||||||
|
asm("sync ; isync");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ======================================================================
|
||||||
|
* Determine if a valid ELF image exists at the given memory location.
|
||||||
|
* First looks at the ELF header magic field, the makes sure that it is
|
||||||
|
* executable and makes sure that it is for a PowerPC.
|
||||||
|
* ====================================================================== */
|
||||||
|
static int32_t valid_elf_image (void *addr)
|
||||||
|
{
|
||||||
|
Elf32_Ehdr *ehdr = (Elf32_Ehdr*)addr;
|
||||||
|
|
||||||
|
if (!IS_ELF (*ehdr))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (ehdr->e_type != ET_EXEC)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (ehdr->e_machine != EM_PPC)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ======================================================================
|
||||||
|
* A very simple elf loader, assumes the image is valid, returns the
|
||||||
|
* entry point address.
|
||||||
|
* ====================================================================== */
|
||||||
|
|
||||||
|
static uint32_t load_elf_image (void *elfstart)
|
||||||
|
{
|
||||||
|
u8 *image;
|
||||||
|
int i;
|
||||||
|
Elf32_Phdr *phdrs = NULL;
|
||||||
|
Elf32_Ehdr *ehdr = (Elf32_Ehdr*) elfstart;
|
||||||
|
|
||||||
|
if(ehdr->e_phoff == 0 || ehdr->e_phnum == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(ehdr->e_phentsize != sizeof(Elf32_Phdr))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
phdrs = (Elf32_Phdr*)(elfstart + ehdr->e_phoff);
|
||||||
|
|
||||||
|
for (i = 0; i < ehdr->e_phnum; i++)
|
||||||
|
{
|
||||||
|
if(phdrs[i].p_type != PT_LOAD)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
phdrs[i].p_paddr &= 0x3FFFFFFF;
|
||||||
|
phdrs[i].p_paddr |= 0x80000000;
|
||||||
|
|
||||||
|
if(phdrs[i].p_filesz > phdrs[i].p_memsz)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(!phdrs[i].p_filesz)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
image = (u8 *) (elfstart + phdrs[i].p_offset);
|
||||||
|
memcpy ((void *) phdrs[i].p_paddr, (const void *) image, phdrs[i].p_filesz);
|
||||||
|
|
||||||
|
sync_before_exec ((void *) phdrs[i].p_paddr, phdrs[i].p_memsz);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((ehdr->e_entry & 0x3FFFFFFF) | 0x80000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t load_dol_image(const void *dolstart)
|
||||||
|
{
|
||||||
|
u32 i;
|
||||||
|
dolheader *dolfile = NULL;
|
||||||
|
|
||||||
|
if(!dolstart)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
dolfile = (dolheader *) dolstart;
|
||||||
|
|
||||||
|
for (i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
if ((!dolfile->text_size[i]) || (dolfile->text_start[i] < 0x100))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
memcpy((void *) dolfile->text_start[i], dolstart + dolfile->text_pos[i], dolfile->text_size[i]);
|
||||||
|
sync_before_exec((void *) dolfile->text_start[i], dolfile->text_size[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 11; i++)
|
||||||
|
{
|
||||||
|
if ((!dolfile->data_size[i]) || (dolfile->data_start[i] < 0x100))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
memcpy((void *) dolfile->data_start[i], dolstart + dolfile->data_pos[i], dolfile->data_size[i]);
|
||||||
|
sync_before_exec((void *) dolfile->data_start[i], dolfile->data_size[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dolfile->entry_point;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* if we name this main, GCC inserts the __eabi symbol,
|
/* if we name this main, GCC inserts the __eabi symbol,
|
||||||
* even when we specify -mno-eabi.
|
* even when we specify -mno-eabi. */
|
||||||
*/
|
|
||||||
|
|
||||||
void app_booter_main(void)
|
void app_booter_main(void)
|
||||||
{
|
{
|
||||||
void *exeBuffer = (void *) EXECUTABLE_MEM_ADDR;
|
void *exeBuffer = (void*)EXECUTABLE_MEM_ADDR;
|
||||||
u32 exeEntryPointAddress = 0;
|
u32 exeEntryPointAddress = 0;
|
||||||
entrypoint exeEntryPoint;
|
entrypoint exeEntryPoint;
|
||||||
|
|
||||||
@ -40,5 +162,5 @@ void app_booter_main(void)
|
|||||||
sync_before_exec(new_argv, sizeof(struct __argv));
|
sync_before_exec(new_argv, sizeof(struct __argv));
|
||||||
}
|
}
|
||||||
|
|
||||||
exeEntryPoint ();
|
exeEntryPoint();
|
||||||
}
|
}
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
// 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 <gctypes.h>
|
|
||||||
|
|
||||||
void sync_before_exec(const void *p, u32 len)
|
|
||||||
{
|
|
||||||
u32 a = (u32)p & ~0x1f;
|
|
||||||
u32 b = ((u32)p + len + 0x1f) & ~0x1f;
|
|
||||||
|
|
||||||
for ( ; a < b; a += 32)
|
|
||||||
asm("dcbst 0,%0 ; sync ; icbi 0,%0" : : "b"(a));
|
|
||||||
|
|
||||||
asm("sync ; isync");
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
#ifndef __SYNC_H_
|
|
||||||
#define __SYNC_H_
|
|
||||||
|
|
||||||
void sync_before_read(void *p, u32 len);
|
|
||||||
|
|
||||||
void sync_after_write(const void *p, u32 len);
|
|
||||||
|
|
||||||
void sync_before_exec(const void *p, u32 len);
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue
Block a user