125 lines
2.9 KiB
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);
|
|
}
|