#include "vxBoot/terminal.h" #include "vxBoot/fs/smemfs.h" #include "vxBoot/hardware.h" #include "vxBoot/loader.h" #include #include #include #include static int dump_reloc(struct kernel_info *kernel) { int handle; int size; size = kernel->memory.program.size + 1; BFile_Remove(u"\\\\fls0\\reloc_dump.s"); BFile_Create(u"\\\\fls0\\reloc_dump.s", BFile_File, &size); handle = BFile_Open(u"\\\\fls0\\reloc_dump.s", BFile_WriteOnly); BFile_Write( handle, (void*)kernel->memory.program.start, kernel->memory.program.size ); return (0); } /* loader_inode: Load a ELF programm (PIE) */ int loader(struct smemfs_inode const * restrict const inode, int mode) { struct kernel_info kernel; Elf32_Ehdr header; int err; if (inode == NULL) return (-1); terminal_write("> try to load ELF file \"%s\"\n", inode->name); terminal_write("> check header information...\n"); err = loader_header_get(inode, &header); if (err != 0) { loader_header_error(err); return (-2); } if (mode == LOADER_INFO) return loader_info(inode, &header); terminal_write("> generate kernel geometry...\n"); memset(&kernel, 0x00, sizeof(struct kernel_info)); hardware_get_info(&kernel.hardware); terminal_write("> load image...\n"); err = loader_image_load(inode, &kernel, &header); if (err != 0) { loader_image_error(err); return (-3); } terminal_write("> path the GOT table...\n"); loader_got_patch(inode, &kernel, &header); //FIXME: check returned value if (mode == LOADER_CHECK) return (0); terminal_write("%s successfully loaded !\n", inode->name); if (mode == LOADER_DUMP) { 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 ); gint_world_switch(GINT_CALL((void*)&dump_reloc, (void*)&kernel)); 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); }