#include "vxBoot/terminal.h" #include "vxBoot/fs/smemfs.h" #include "vxBoot/hardware.h" #include "vxBoot/loader.h" #include #include #include #include /* dump_reloc() : dump the relocalized image */ static int dump_reloc(struct kernel *kernel) { int handle; int size; size = kernel->memory.program.size + 1; BFile_Remove(u"\\\\fls0\\dump_reloc.bin"); BFile_Create(u"\\\\fls0\\dump_reloc.bin", BFile_File, &size); handle = BFile_Open(u"\\\\fls0\\dump_reloc.bin", BFile_WriteOnly); BFile_Write( handle, (void*)kernel->memory.program.start, kernel->memory.program.size ); return (0); } /* dump_ilram() : dump the on-chip IL-memory */ static int dump_xram(void) { int handle; int size; size = 4069; BFile_Remove(u"\\\\fls0\\dump_xram.bin"); BFile_Create(u"\\\\fls0\\dump_xram.bin", BFile_File, &size); handle = BFile_Open(u"\\\\fls0\\dump_xram.bin", BFile_WriteOnly); BFile_Write( handle, (void*)0xe5007000, 4096 ); return (0); } /* loader_inode: Load a ELF programm (PIE) */ int loader(struct smemfs_inode const * restrict const inode, int mode) { struct kernel kernel; int err; if (inode == NULL) return (-1); terminal_write("> try to load ELF file \"%s\"\n", inode->name); memset(&kernel, 0x00, sizeof(struct kernel)); kernel.inode = inode; terminal_write("> check header information...\n"); err = loader_header_check(&kernel); if (err != 0) { loader_header_error(err); return (-2); } terminal_write("> generate kernel geometry...\n"); hardware_get_info(&kernel.hardware); terminal_write("> load image...\n"); err = loader_image_load(&kernel); if (err != 0) { loader_image_error(err); return (-3); } terminal_write("> relocalize symbols...\n"); loader_rela_patch(&kernel); terminal_write("> patch the GOT table...\n"); loader_got_patch(&kernel); terminal_write("> patch the UTLB...\n"); hardware_utlb_patch(); terminal_write("%s successfully loaded !\n", inode->name); if (mode == LOADER_DUMP || mode == LOADER_CHECK) { terminal_write( "kernel information:\n" "|-- kernel entry: %p\n" "`-- memory:\n" " `-- program:\n" " |-- start: %p\n" " |-- size: %do\n" " `-- elf:\n" " |-- vmin: %p\n" " `-- vmax: %p\n", kernel.entry, kernel.memory.program.start, kernel.memory.program.size, kernel.memory.program.elf.vmin, kernel.memory.program.elf.vmax ); if (mode == LOADER_CHECK) return (0); gint_world_switch(GINT_CALL((void*)&dump_reloc, (void*)&kernel)); gint_world_switch(GINT_CALL((void*)&dump_xram)); return (0); } if (mode == LOADER_TRACE) { struct tsession *session; session = tracer_create_session( (void*)kernel.entry, TRACER_DISASM | TRACER_CONTEXT | TRACER_HEXDUMP ); tracer_set_session(session); } gint_world_switch(GINT_CALL((void*)kernel.entry)); return (0); }