[Tutorial] Explicando el HBL (II)

Moderadores: Kravenbcn, largeroliker, fidelcastro, cerealkiller, pspCaracas, dark_sasuke, m0skit0, LnD, ka69, zacky06

Responder
Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

[Tutorial] Explicando el HBL (II)

Mensaje por m0skit0 »

<< Anterior Siguiente >>

Cómo se lanza un homebrew

Una de las partes más interesantes del HBL es cómo se carga y se arranca un EBOOT.PBP. La función que realiza esto se llama run_eboot. No voy a ver run_menu ya que básciamente es run_eboot con una serie de pruebas previas (comprobad como llama a run_eboot).

Código: Seleccionar todo

void run_eboot(const char *path, int is_eboot)

Recibe la ruta del EBOOT a cargar (path), y si es un PBP (is_eboot). Esto se debe a que un principio el HBL sólo cargaba ELFs, y si is_eboot es 0, se trata como un ELF, si es 1, como un EBOOT.

Código: Seleccionar todo

//Load Game config overrides

Carga los ajustes específicos para el homebrew elegido.

Código: Seleccionar todo

if (is_eboot)

Lo que comentaba antes. Si es un EBOOT, se debe llamar a elf_eboot_extract_open para localizar el ELF dentro del EBOOT. Si es un ELF, simplemente se abre.

Código: Seleccionar todo

memset(sceGeEdramGetAddr(), 0, sceGeEdramGetSize()); 

Limpia la memoria de vídeo.

Código: Seleccionar todo

mod_id = load_module(elf_file, path, (void*)PRX_LOAD_ADDRESS, offset);

Carga el ELF, ya sea el que se encuentra dentro de un EBOOT o uno suelto (como un PRX por ejemplo).

Código: Seleccionar todo

mod_id = start_module(mod_id);

Lanza el ELF.

Código: Seleccionar todo

return;

Hemos acabado.

Como recordaréis, es wait_for_eboot_end();, que vimos en el capítulo anterior, la que se encarga de detectar cuando acaba el EBOOT y luego cleanup de limpiar la memoria.

Tablas de estado del sistema (I): exportes

En tables.h se encuentra la definición de algunas de las tablas de estado del sistema que maneja HBL, concretamente las relacionadas con importes (syscalls y librerías). Vamos a echarles un vistazo.

Código: Seleccionar todo

typedef struct
{
        u32 nid;                    // NID
        u32 call;                   // Syscall/jump associated to the NID
        unsigned int lib_index; // Index to the library descriptor tSceLibrary
} tNIDResolver;

Ésta es posiblemente la primera (y única en su momento) tabla del sistema de HBL.

  • nid identifica la función en cuestión. En PSP cada función exportada (accesible desde otros módulos) se le debe asignar un NID, que no es más que un número de 32 bits sin signo.
  • call es el syscall asociado a dicho NID (qué syscall debe usar el homebrew para llamar a la función identificada por el NID).
  • lib_index es un índice a otra tabla, que indica a qué librería pertenece este NID. Las funciones exportadas por un módulo siempre deben pertenecer a una librería.

Se usa un array/vector estático (de tamaño fijo) que contiene tantos elementos de éstos como indica la constante NID_TABLE_SIZE. Es la siguiente estructura que nos encontramos, donde table es el mencionado array y num nos indica cuántos elementos de table están rellenados con información.

Código: Seleccionar todo

typedef struct
{
        unsigned int num;                                       // Number of nids on table     
        tNIDResolver table[NID_TABLE_SIZE];     // NID resolver
} HBLNIDTable;


Esta tabla contiene todos los syscalls que el HBL conoce. Los que no se encuentren en esta tabla se deberán de estimar matemáticamente llegado el momento.

Luego tenemos las tablas de librerías, cuyo elemento básico que describe una librería es el siguiente:

Código: Seleccionar todo

typedef struct
{
        char name[MAX_LIBRARY_NAME_LENGTH];                     // Library name
        tCallingMode calling_mode;                                      // Defines how library exports are called
        unsigned int num_library_exports;                       // Number of exported functions in library
        unsigned int num_known_exports;                         // Number of known exported functions (exports we know the syscall of)
        u32 lowest_syscall;                                                     // Lowest syscall number found
        u32 lowest_nid;                                                         // NID associated to lowest syscall
        unsigned int lowest_index;                                      // Lowest NID index nids_table
    u32 highest_syscall;                        // Highest syscall number found
        u32 gap;                                    // Offset between the syscall for the highest and the lowest nid index in 6.20
} tSceLibrary;

  • name guarda el nombre de la librería.
  • calling_mode define de qué modo se llama a la librería (si salto o syscall, no entraré en detalles).
  • num_library_exports guarda cuántas funciones diferentes en total se exportan en esta librería.
  • num_known_exports guarda cuántos syscalls conoce el HBL del total de funciones exportadas (sólo aplica a las librerías syscall).
  • lowest_syscall guarda el syscall más bajo de la librería que conoce el HBL.
  • lowest_nid guarda el NID del syscall más bajo que conoce el HBL.
  • lowest_index indica la posición en la tabla HBLNIDTable del syscall más bajo.
  • highest_syscall indica el syscall más alto de la librería que concoce HBL.
  • gap indica el hueco entre el syscall más bajo y el más alto en 6.20+ (no entraremos en detalles).

A una de estas estructuras es a lo que hace referencia el lib_index de tNIDResolver.

Obviamente esta estructura se argupa en un array, al igual que antes, donde se describen todas las librerías que conoce el HBL, tal que así:

Código: Seleccionar todo

typedef struct
{
        unsigned int num;
        tSceLibrary table[MAX_LIBRARIES];
} HBLLibTable;

donde la constante MAX_LIBRARIES define el número máximo de librerías que puede conocer el HBL.

Estas tablas son rellenadas por la función build_nid_table, que como algunos recordaréis, se llama en el bucle de la función principal del HBL (que vimos en el pasado capítulo).

Bueno, esto es todo por este capítulo, más intestinos en el próximo.

<< Anterior Siguiente >>
Imagen

Avatar de Usuario
j0zu3
Habitual
Habitual
Mensajes: 283
Registrado: 21 Feb 2010, 02:12
Ubicación: Costa Rica

Re: [Tutorial] Explicando el HBL (II)

Mensaje por j0zu3 »

Me tarde media hora leyendo los dos tutos y estan buenos y la verdad entendi mas de lo que creia que iba a entender, buen aporte gracias :oki:

-- Doble Post --

Esto no deberia ir en tutoriales ya que dice tutorial ¿?

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: [Tutorial] Explicando el HBL (II)

Mensaje por m0skit0 »

Es un tutorial sobre cómo funciona el HBL internamente. En mi opinion es algo demasiado avanzado para poner en la sección de Tutoriales a secas. Creo que Desarrollo le viene mejor.
Imagen

Avatar de Usuario
Kravenbcn
Administrador
Administrador
Mensajes: 16291
Registrado: 01 Sep 2009, 21:27
PSN ID: Kravenbcn
Twitter: Kravenbcn
Ubicación: Barcelona
Contactar:

Re: [Tutorial] Explicando el HBL (II)

Mensaje por Kravenbcn »

j0zu3 escribió:Esto no deberia ir en tutoriales ya que dice tutorial ¿?

Si pero por mucho que sea un tutorial es un tutorial de desarrollo, la sección Tutoriales es más destinada a cualquier tipo de usuario.

PD: De este mismo modo, el tutorial que hice ayer sobre como cambiar una pantalla de PSP, por mucho que ponga tutorial, está en Hardware por motivos obvios.
No te pierdas nada, sigue a DaXHordes en Twitter, Facebook, Google+ y Youtube

Imagen
¿Quieres formar parte del equipo de DaXHordes.org? Esta es tu oportunidad.
PS3 · PS Vita · PSP

Avatar de Usuario
~Rdavid~
Experto
Experto
Mensajes: 965
Registrado: 12 Nov 2009, 17:29
Ubicación: Costa Rica

Re: [Tutorial] Explicando el HBL (II)

Mensaje por ~Rdavid~ »

Muy bueno Moskito, esperare los demás :D
Imagen

moikop
Desarrollador
Desarrollador
Mensajes: 16
Registrado: 01 Dic 2009, 18:12
Ubicación: Argentina

Re: [Tutorial] Explicando el HBL (II)

Mensaje por moikop »

Muy buen tuto M0skit0, como siempre, más claro que el agua :P
Sólo una cosa, cuando dices: "calling_mode define de qué modo se llama a la librería (si salto o syscall, no entraré en detalles)", con salto y syscall te refieres a "los comandos" (jump y syscall) de asm mips, no?
Un saludo.

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: [Tutorial] Explicando el HBL (II)

Mensaje por m0skit0 »

moikop escribió:Muy buen tuto M0skit0, como siempre, más claro que el agua :P

Gracias :)

moikop escribió:con salto y syscall te refieres a "los comandos" (jump y syscall) de asm mips, no?

:oki:
Imagen

Responder