Voy a empezar una serie de posts explicando el funcionamiento interno del HBL, por si a alguien le interesa desarrollar y ayudar, o bien simplemente por curiosear. El HBL puede considerarse un firmware ligero en modo usuario, así que si lográis comprender el HBL, comprenderéis mucho mejor la PSP.
Iré desde lo más genérico hasta el detalle, dentro de lo posible
Cómo ver el código fuente sin descargarlo
En el directorio del código fuente, desplegamos trunk, y luego eLoader. A la derecha veremos deplegarse todos los ficheros del HBL.
Secuencia básica de arranque
Como muchos sabréis, los exploits generalmente cargan un fichero h.bin (aunque el nombre podría ser cualquiera) en memoria. Este fichero es código binario que la PSP puede ejecutar directamente desde la memoria. Esto se hace así porque generalmente los exploits disponen de poco espacio dentro del fichero trampa, y no podrían incluir algo tan gordo como el HBL.
Entonces el exploit del juego carga un h.bin, que en HBL es el fichero loader.c, como podéis ver en la línea del fichero Makefile (hay más ficheros que se compilan con él, pero son utilidades genéricas). El loader.c se encarga de cargar el HBL en memoria (el hbl.bin). El hbl.bin es el HBL en sí (como su nombre indica), es lo que contiene la "chicha". Su punto de entrada (donde se empieza a ejecutar) se encuentra en eloader.c.
Una vez cargado, el hbl.bin se ocupa de cerrar todos los recursos del juego en cuestión para liberar memoria, y carga el menú. Una vez elegido el juego desde el menú, el HBL descarga el menú y carga el juego, y lo lanza. Cuando el usuario sale, el HBL detecta esta salida, libera la memoria del juego y carga de nuevo el menú HBL. Y así hasta que se salga del HBL.
Función principal del HBL
Lo podemos encontrar aquí. Voy a ir recorriendo la función y explicando:
Código: Seleccionar todo
tGlobals * g = get_globals();
Obtiene un puntero a las variables globales.
Código: Seleccionar todo
init_malloc();
Inicializa el sistema de reserva de memoria del HBL.
Código: Seleccionar todo
num_nids = build_nid_table();
Recoge todos los syscalls que se pueden encontrar en memoria de usuario.
Código: Seleccionar todo
resolve_missing_stubs();
Resuelve los importes vacíos del propio HBL. Esto significa que el HBL debe cerciorarse de que todas las funciones que va a utilizar han sido resueltas por el cargador (el loader.c o h.bin). Lo más probable es que no lo estén. Esto se hace así porque el cargador no puede estimar syscalls. Otra opción sería incluir la estimación de syscalls en el cargador.
Código: Seleccionar todo
free_game_memory();
Libera la memoria del juego.
Código: Seleccionar todo
// Start Callback Thread
Aquí se arranca el hilo de callback del HBL. Es algo característico de la programación para PSP, y cualquier desarrollador de PSP en C sabe que esto siempre se pone
Código: Seleccionar todo
if (file_exists(EBOOT_PATH))
Aquí el HBL mira si hay que arrancar directamente un homebrew. Si no, lanza el menú.
Código: Seleccionar todo
//...otherwise launch the menu
while (!exit)
Este bucle es el que carga el menú y luego el juego elegido por el usuario a través del menú. Cuando se acaba el juego, vuelve a cargar el menú y así hasta que exit es distinto de 0 (cuando el usuario sale del HBL). Sigo con el interior del bucle.
Código: Seleccionar todo
loadGlobalConfig();
Carga la configuración.
Código: Seleccionar todo
run_menu();
wait_for_eboot_end();
cleanup(num_lib);
Carga el menú, lo arranca, espera a que acabe y limpia la memoria
Código: Seleccionar todo
if (strcmp("quit", g->hb_filename) == 0 || g->exit_callback_called)
Comprueba si se ha mandado la orden de salir.
Código: Seleccionar todo
run_eboot(filename, 1);
wait_for_eboot_end();
cleanup(num_lib);
Carga el eboot elegido en el menu, lo arranca, espera a que acabe y limpia la memoria.
Como véis no es nada del otro mundo (aunque esperad a ver los detalles de las funciones ). Seguimos en el próximo hilo con más entrañas del HBL.
Saludos y animaos a modificarlo
Siguiente >>