vxBoot/src/loader/entry.c

125 lines
2.9 KiB
C

#include "vxBoot/terminal.h"
#include "vxBoot/fs/smemfs.h"
#include "vxBoot/hardware.h"
#include "vxBoot/loader.h"
#include <gint/gint.h>
#include <gint/bfile.h>
#include <gintrace/tracer.h>
#include <string.h>
/* 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);
}