Thyl-Thalion escribió:Hermes escribió:¿Os imagináis .....?
Esto es la bomba !!! Ya os seguí a ti y a rodries con lo de libfat, pero esto SI QUE ES FUERTE !!!
Pues si, mola cantidad y es bastante complicado... porque en el Starlet no se puede modificar posiciones de memoria porque si y yo lo he tenido que aprender todo de sopetón (¿veis porque no quería? porque sabía que me iba a liar y liar
)
De momento, he jugado un par de horas al Mario Galaxy para probar: he tenido una tres interrupciones de sonido, que eso antes significaba muerte, pero todo perfecto.
Lo bueno de que la Wii tenga esa forma de trabajar, tan diferente a la PS2 (en el IOP de PS2, podías acceder a toda la memoria
sin hacer virguerías), es que estoy seguro que esto que he metido, no molesta: las zonas de memoria que he pillado, están
sin asignar y los modulos que hay en el starlet, los pone Nintendo y no el desarrollador (en PS2 SONY metía lo necesario, pero también el desarrollador podía meter sus módulos a su antojo... y eso complicaba la cosa)
Aquí parece que salvo algún IOS "raro" precisamente, para añadir esas cosas que en PS2 eran tan fáciles, no tiene porqué haber complicaciones.
Os muestro las funciones de referencia con las que trabaja dev/mload :
/*--------------------------------------------------------------------------------------------------------------*/
// to init/test if the device is running
int mload_init();
/*--------------------------------------------------------------------------------------------------------------*/
// to close the device (remember call it when rebooting the IOS!)
int mload_close();
/*--------------------------------------------------------------------------------------------------------------*/
// get the base and the size of the memory readable/writable to load modules
int mload_get_load_base(u32 *starlet_base, int *size);
/*--------------------------------------------------------------------------------------------------------------*/
// load and run a module from starlet (it need to allocate MEM2 to send the elf file)
// the module must be a elf made with stripios
int mload_module(void *addr, int len);
/*--------------------------------------------------------------------------------------------------------------*/
// load a module from the PPC
// the module must be a elf made with stripios
int mload_elf(void *my_elf, data_elf *data_elf);
/*--------------------------------------------------------------------------------------------------------------*/
// run one thread (you can use to load modules or binary files)
int mload_run_thread(void *starlet_addr, void *starlet_top_stack, int stack_size, int priority);
/*--------------------------------------------------------------------------------------------------------------*/
// fix starlet address to read/write (uses SEEK_SET, etc as mode)
int mload_seek(int offset, int mode);
/*--------------------------------------------------------------------------------------------------------------*/
// read bytes from starlet (it update the offset)
int mload_read(void* buf, u32 size);
/*--------------------------------------------------------------------------------------------------------------*/
// write bytes from starlet (it update the offset)
int mload_write(const void * buf, u32 size);
/*--------------------------------------------------------------------------------------------------------------*/
// fill a block (similar to memset)
int mload_memset(void *starlet_addr, int set, int len);
/*--------------------------------------------------------------------------------------------------------------*/
// get the ehci datas ( ehcmodule.elf uses this address)
void * mload_get_ehci_data();
/*--------------------------------------------------------------------------------------------------------------*/
// set the dev/es ioctlv input routine
int mload_set_ES_ioctlv_vector(void *starlet_addr);
/*--------------------------------------------------------------------------------------------------------------*/
Hay dos procedimientos para cargar módulos: uno los carga y ejecuta directamente desde el Starlet,
sin mas preámbulos compuesto de dos llamadas . El otro permite cargar elfs en memoria desde el PPC y creo que nos ahorra un pico de MEM2 en el proceso. Luego solo es cuestión de pasarle los datos de la estructura de ejecución para que se cree el hilo necesario.
Para el cargador de juegos hay dos parches bypass, que no hacen nada en absoluto, salvo cuando se les activa reprogramando la dirección deseada: mload_set_ES_ioctlv_vector() fija la función que tratará todas las entradas ioctvl de dev/es y que podemos usar para "saltarnos" un cambio de IOS (función que por defecto, no usaremos, porque se cuelga si tratas de volver al sistema, claro: podemos ignorar un reboot pero no proporcionamos el entorno necesario
). Esto será un flag que podremos activar desde uloader.
Por cierto que mload no hace nada perverso con esto: simplemente, recibe un salto y lo conmuta de vuelta si una variable (que es la que cambiamos con la llamada anterior), está a 0 o salta a la dirección programada en caso contrario.
Desde un punto de vista de homebrew, podría ser interesante investigarlo para conseguir cosas que ahora mismo solo podemos conseguir a base de custom IOS reprogramando títulos.
El dip_plugin se activa simplemente, escribiendo la dirección de entrada de la rutina (los primeros 4 bytes) en una zona de memoria accesible que contiene la rutina bypass.
Tambien se puede reprogramar con las direcciones clave que necesita... pero eso ya es cosa de expertos:
Ejemplo de activación en IOS 38:
static u32 ios_38[16] ATTRIBUTE_ALIGN(32)=
{
0, // DI_EmulateCmd
0,
0x2022cdac, // dvd_read_controlling_data
0x20200d38+1, // handle_di_cmd_reentry (thumb)
0x202008c4+1, // ios_shared_alloc_aligned (thumb)
0x20200898+1, // ios_shared_free (thumb)
0x20205b80+1, // ios_memcpy (thumb)
0x20200048+1, // ios_fatal_di_error (thumb)
0x20202874+1, // ios_doReadHashEncryptedState (thumb)
0x2020365c+1, // ios_printf (thumb)
};
if(is_ios==38)
{
// IOS 38
memcpy(ios_38, dip_plugin, 4); // copy the entry_point
memcpy(dip_plugin, ios_38, 4*10); // copy the adresses from the array
mload_seek(0x1377E000, SEEK_SET); // copy dip_plugin in the starlet
mload_write(dip_plugin,size_dip_plugin);
// enables DIP plugin
mload_seek(0x20208030, SEEK_SET);
mload_write(ios_38, 4);
}
El método que yo uso, tiene dos cosas positivas: si teneis un cIOS antiguo funcinará igual, tirando de lo viejo y saltandose todo esto (porque al no existir dev/mload, todas las llamadas devolverán error y retornará).
Y la segunda, es que nos facilitará mucho la vida a la hora de probar algo y será mas permeable para vosotros (parece que Wiigator no quiere que se haga público el código fuente). El binario se carga justo al final de la RAM operativa, (8KB finales, pensando un poco en posibles ampliaciones).
Un problema que tenemos con los módulos, es que no son reubicables como en PS2, por lo que hay que tener muy claro que es lo que se pone y donde (por eso el módulo ehcmodule, está al principio y el dip_plugin que no se usa en homebrew, al final)
Tenemos 512KB de memoria, aunque podemos asignar unos 640KB más utilizando el heap handle 0. Así que hay mas que suficiente para trabajar
Saludos