[app][loader] Odds and ends
- Fix a bug when doing bounds checking - Don't run elf if the entrypoint is out of bounds - Allow to specify the memory slot to download (slot is 512K) - Default slot for elf is 1, 3 and for data is 0, 2
This commit is contained in:
@@ -40,13 +40,13 @@
|
||||
#endif
|
||||
|
||||
#if defined(SDRAM_BASE)
|
||||
static unsigned char* download_start = (void*)SDRAM_BASE;
|
||||
#define DOWNLOAD_BASE ((void*)SDRAM_BASE)
|
||||
#else
|
||||
static unsigned char* download_start = NULL;
|
||||
#define DOWNLOAD_BASE ((void*)0)
|
||||
#endif
|
||||
|
||||
#define FNAME_SIZE 64
|
||||
#define DOWNLOAD_SLOT_SIZE (128 * 1024)
|
||||
#define DOWNLOAD_SLOT_SIZE (512 * 1024)
|
||||
|
||||
typedef enum {
|
||||
DOWNLOAD_ANY,
|
||||
@@ -63,15 +63,17 @@ typedef struct {
|
||||
|
||||
static download_t* make_download(const char* name)
|
||||
{
|
||||
download_t* s = malloc(sizeof(download_t));
|
||||
s->start = download_start;
|
||||
s->end = s->start;
|
||||
s->max = download_start + DOWNLOAD_SLOT_SIZE;
|
||||
strncpy(s->name, name, FNAME_SIZE);
|
||||
download_t* d = malloc(sizeof(download_t));
|
||||
memset(d, 0, sizeof(download_t));
|
||||
strncpy(d->name, name, FNAME_SIZE);
|
||||
return d;
|
||||
}
|
||||
|
||||
download_start = s->max;
|
||||
memset(s->start, 0, DOWNLOAD_SLOT_SIZE);
|
||||
return s;
|
||||
static void set_ram_zone(download_t* d, int slot) {
|
||||
d->start = DOWNLOAD_BASE + (DOWNLOAD_SLOT_SIZE * slot);
|
||||
d->end = d->start;
|
||||
d->max = d->end + DOWNLOAD_SLOT_SIZE;
|
||||
memset(d->start, 0, DOWNLOAD_SLOT_SIZE);
|
||||
}
|
||||
|
||||
static size_t output_result(const download_t* download)
|
||||
@@ -95,7 +97,9 @@ static int run_elf(void* entry_point)
|
||||
|
||||
static void process_elf_blob(const void* start, size_t len)
|
||||
{
|
||||
void* entrypt;
|
||||
elf_handle_t elf;
|
||||
|
||||
status_t st = elf_open_handle_memory(&elf, start, len);
|
||||
if (st < 0) {
|
||||
printf("unable to open elf handle\n");
|
||||
@@ -105,13 +109,19 @@ static void process_elf_blob(const void* start, size_t len)
|
||||
st = elf_load(&elf);
|
||||
if (st < 0) {
|
||||
printf("elf processing failed, status : %d\n", st);
|
||||
elf_close_handle(&elf);
|
||||
return;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
entrypt = (void*)elf.entry;
|
||||
if (entrypt < start || entrypt >= (void*)((char*)start + len)) {
|
||||
printf("out of bounds entrypoint for elf : %p\n", entrypt);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
printf("elf looks good\n");
|
||||
thread_resume(thread_create("elf_runner", &run_elf, (void*)elf.entry,
|
||||
thread_resume(thread_create("elf_runner", &run_elf, entrypt,
|
||||
DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
|
||||
exit:
|
||||
elf_close_handle(&elf);
|
||||
}
|
||||
|
||||
@@ -130,7 +140,7 @@ int tftp_callback(void* data, size_t len, void* arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((download->start + len) > download->max) {
|
||||
if ((download->end + len) > download->max) {
|
||||
printf("transfer too big, aborting\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -143,17 +153,22 @@ int tftp_callback(void* data, size_t len, void* arg)
|
||||
|
||||
static int loader(int argc, const cmd_args *argv)
|
||||
{
|
||||
download_t* download;
|
||||
static int any_slot = 0;
|
||||
static int elf_slot = 1;
|
||||
|
||||
if (!download_start) {
|
||||
download_t* download;
|
||||
int slot;
|
||||
|
||||
if (!DOWNLOAD_BASE) {
|
||||
printf("loader not available. it needs sdram\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc != 3) {
|
||||
if (argc < 3) {
|
||||
usage:
|
||||
printf("load any [filename]\n" \
|
||||
"load elf [filename]\n");
|
||||
printf("load any [filename] <slot>\n"
|
||||
"load elf [filename] <slot>\n"
|
||||
"protocol is tftp and <slot> is optional\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -161,14 +176,23 @@ usage:
|
||||
|
||||
if (strcmp(argv[1].str, "any") == 0) {
|
||||
download->type = DOWNLOAD_ANY;
|
||||
slot = any_slot;
|
||||
any_slot += 2;
|
||||
} else if (strcmp(argv[1].str, "elf") == 0) {
|
||||
download->type = DOWNLOAD_ELF;
|
||||
slot = elf_slot;
|
||||
elf_slot += 2;
|
||||
} else {
|
||||
goto usage;
|
||||
}
|
||||
|
||||
if (argc == 4) {
|
||||
slot = argv[3].i;
|
||||
}
|
||||
|
||||
set_ram_zone(download, slot);
|
||||
tftp_set_write_client(download->name, &tftp_callback, download);
|
||||
printf("ready for %s over tftp\n", argv[2].str);
|
||||
printf("ready for %s over tftp (at %p)\n", argv[2].str, download->start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user