bios/boot: add bootargs support on netboot/sdcardboot to optionally specify r1/r2/r3/addr.

For example:
{
	"Image":  "0x40000000",
	"bootargs": {
		"r1":  "0x12345678",
	}
}

will copy Image to 0x40000000 and set r1 to 0x12345678.

By default, r1,r2,r3 are set to 0 and addr is the address if the last loaded image, so:

{
	"Image":         "0x40000000",
	"rootfs.cpio":   "0x40800000",
	"rv32.dtb":      "0x41000000",
	"emulator.bin":  "0x41100000",
}

is equivalent to:

{
	"Image":         "0x40000000",
	"rootfs.cpio":   "0x40800000",
	"rv32.dtb":      "0x41000000",
	"emulator.bin":  "0x41100000",
	"bootargs": {
		"r1":   "0x00000000",
		"r2":   "0x00000000",
		"r3":   "0x00000000",
		"addr": "0x00000000",
	}
}
This commit is contained in:
Florent Kermarrec 2020-07-16 18:09:18 +02:00
parent ee4b1d81a7
commit ac35e158c1
1 changed files with 103 additions and 41 deletions

View File

@ -156,7 +156,7 @@ int serialboot(void)
printf("Booting from serial...\n"); printf("Booting from serial...\n");
printf("Press Q or ESC to abort boot completely.\n"); printf("Press Q or ESC to abort boot completely.\n");
/* send the serialboot "magic" request to Host */ /* Send the serialboot "magic" request to Host */
c = str; c = str;
while(*c) { while(*c) {
uart_write(*c); uart_write(*c);
@ -171,7 +171,7 @@ int serialboot(void)
printf("Cancelled\n"); printf("Cancelled\n");
return 0; return 0;
} }
/* assume ACK_OK */ /* Assume ACK_OK */
failed = 0; failed = 0;
while(1) { while(1) {
@ -239,7 +239,7 @@ int serialboot(void)
addr = get_uint32(&frame.payload[0]); addr = get_uint32(&frame.payload[0]);
for (i = 4; i < frame.payload_length; i++) { for (i = 4; i < frame.payload_length; i++) {
// erase page at sector boundaries before writing /* Erase page at sector boundaries before writing */
if ((addr & (SPIFLASH_SECTOR_SIZE - 1)) == 0) { if ((addr & (SPIFLASH_SECTOR_SIZE - 1)) == 0) {
erase_flash_sector(addr); erase_flash_sector(addr);
} }
@ -314,10 +314,17 @@ static void netboot_from_json(const char * filename, unsigned int ip, unsigned s
uint8_t count; uint8_t count;
/* FIXME: modify/increase if too limiting */ /* FIXME: modify/increase if too limiting */
char json_buffer[256]; char json_buffer[1024];
char image_filename[32]; char json_name[32];
char image_address[32]; char json_value[32];
uint8_t image_found;
unsigned long boot_r1 = 0;
unsigned long boot_r2 = 0;
unsigned long boot_r3 = 0;
unsigned long boot_addr = 0;
uint8_t image_found = 0;
uint8_t boot_addr_found = 0;
/* Read JSON file */ /* Read JSON file */
size = tftp_get(ip, tftp_port, filename, json_buffer); size = tftp_get(ip, tftp_port, filename, json_buffer);
@ -325,31 +332,55 @@ static void netboot_from_json(const char * filename, unsigned int ip, unsigned s
return; return;
/* Parse JSON file */ /* Parse JSON file */
jsmntok_t t[16]; jsmntok_t t[32];
jsmn_parser p; jsmn_parser p;
jsmn_init(&p); jsmn_init(&p);
image_found = 0;
count = jsmn_parse(&p, json_buffer, strlen(json_buffer), t, sizeof(t)/sizeof(*t)); count = jsmn_parse(&p, json_buffer, strlen(json_buffer), t, sizeof(t)/sizeof(*t));
for (i=0; i<count-1; i++) { for (i=0; i<count-1; i++) {
/* Images are JSON strings with 1 children */ memset(json_name, 0, sizeof(json_name));
memset(json_value, 0, sizeof(json_value));
/* Elements are JSON strings with 1 children */
if ((t[i].type == JSMN_STRING) && (t[i].size == 1)) { if ((t[i].type == JSMN_STRING) && (t[i].size == 1)) {
/* Get Image filename */ /* Get Element's filename */
memset(image_filename, 0, sizeof(image_filename)); memcpy(json_name, json_buffer + t[i].start, t[i].end - t[i].start);
memcpy(image_filename, json_buffer+t[i].start, t[i].end - t[i].start); /* Get Element's address */
/* Get Image address */ memcpy(json_value, json_buffer + t[i+1].start, t[i+1].end - t[i+1].start);
memset(image_address, 0, sizeof(image_address)); /* Skip bootargs (optional) */
memcpy(image_address, json_buffer+t[i+1].start, t[i+1].end - t[i+1].start); if (strncmp(json_name, "bootargs", 8) == 0) {
continue;
}
/* Get boot addr (optional) */
else if (strncmp(json_name, "addr", 4) == 0) {
boot_addr = strtoul(json_value, NULL, 0);
boot_addr_found = 1;
}
/* Get boot r1 (optional) */
else if (strncmp(json_name, "r1", 2) == 0) {
memcpy(json_name, json_buffer + t[i].start, t[i].end - t[i].start);
boot_r1 = strtoul(json_value, NULL, 0);
}
/* Get boot r2 (optional) */
else if (strncmp(json_name, "r2", 2) == 0) {
boot_r2 = strtoul(json_value, NULL, 0);
}
/* Get boot r3 (optional) */
else if (strncmp(json_name, "r3", 2) == 0) {
boot_r3 = strtoul(json_value, NULL, 0);
/* Copy Image from Network to address */ /* Copy Image from Network to address */
size = copy_file_from_tftp_to_ram(ip, tftp_port, image_filename, (void *)strtoul(image_address, NULL, 0)); } else {
size = copy_file_from_tftp_to_ram(ip, tftp_port, json_name, (void *)strtoul(json_value, NULL, 0));
if (size <= 0) if (size <= 0)
return; return;
image_found = 1; image_found = 1;
if (boot_addr_found == 0) /* Boot to last Image address if no bootargs.addr specified */
boot_addr = strtoul(json_value, NULL, 0);
}
} }
} }
/* Boot to last Image address */ /* Boot */
if (image_found) if (image_found)
boot(0, 0, 0, strtoul(image_address, NULL, 0)); boot(boot_r1, boot_r2, boot_r3, boot_addr);
} }
static void netboot_from_bin(const char * filename, unsigned int ip, unsigned short tftp_port) static void netboot_from_bin(const char * filename, unsigned int ip, unsigned short tftp_port)
@ -532,10 +563,17 @@ static void sdcardboot_from_json(const char * filename)
uint32_t result; uint32_t result;
/* FIXME: modify/increase if too limiting */ /* FIXME: modify/increase if too limiting */
char json_buffer[256]; char json_buffer[1024];
char image_filename[32]; char json_name[32];
char image_address[32]; char json_value[32];
uint8_t image_found;
unsigned long boot_r1 = 0;
unsigned long boot_r2 = 0;
unsigned long boot_r3 = 0;
unsigned long boot_addr = 0;
uint8_t image_found = 0;
uint8_t boot_addr_found = 0;
/* Read JSON file */ /* Read JSON file */
fr = f_mount(&fs, "", 1); fr = f_mount(&fs, "", 1);
@ -555,31 +593,55 @@ static void sdcardboot_from_json(const char * filename)
f_mount(0, "", 0); f_mount(0, "", 0);
/* Parse JSON file */ /* Parse JSON file */
jsmntok_t t[16]; jsmntok_t t[32];
jsmn_parser p; jsmn_parser p;
jsmn_init(&p); jsmn_init(&p);
image_found = 0;
count = jsmn_parse(&p, json_buffer, strlen(json_buffer), t, sizeof(t)/sizeof(*t)); count = jsmn_parse(&p, json_buffer, strlen(json_buffer), t, sizeof(t)/sizeof(*t));
for (i=0; i<count-1; i++) { for (i=0; i<count-1; i++) {
/* Images are JSON strings with 1 children */ memset(json_name, 0, sizeof(json_name));
memset(json_value, 0, sizeof(json_value));
/* Elements are JSON strings with 1 children */
if ((t[i].type == JSMN_STRING) && (t[i].size == 1)) { if ((t[i].type == JSMN_STRING) && (t[i].size == 1)) {
/* Get Image filename */ /* Get Element's filename */
memset(image_filename, 0, sizeof(image_filename)); memcpy(json_name, json_buffer + t[i].start, t[i].end - t[i].start);
memcpy(image_filename, json_buffer+t[i].start, t[i].end - t[i].start); /* Get Element's address */
/* Get Image address */ memcpy(json_value, json_buffer + t[i+1].start, t[i+1].end - t[i+1].start);
memset(image_address, 0, sizeof(image_address)); /* Skip bootargs (optional) */
memcpy(image_address, json_buffer+t[i+1].start, t[i+1].end - t[i+1].start); if (strncmp(json_name, "bootargs", 8) == 0) {
continue;
}
/* Get boot addr (optional) */
else if (strncmp(json_name, "addr", 4) == 0) {
boot_addr = strtoul(json_value, NULL, 0);
boot_addr_found = 1;
}
/* Get boot r1 (optional) */
else if (strncmp(json_name, "r1", 2) == 0) {
memcpy(json_name, json_buffer + t[i].start, t[i].end - t[i].start);
boot_r1 = strtoul(json_value, NULL, 0);
}
/* Get boot r2 (optional) */
else if (strncmp(json_name, "r2", 2) == 0) {
boot_r2 = strtoul(json_value, NULL, 0);
}
/* Get boot r3 (optional) */
else if (strncmp(json_name, "r3", 2) == 0) {
boot_r3 = strtoul(json_value, NULL, 0);
/* Copy Image from SDCard to address */ /* Copy Image from SDCard to address */
result = copy_file_from_sdcard_to_ram(image_filename, strtoul(image_address, NULL, 0)); } else {
result = copy_file_from_sdcard_to_ram(json_name, strtoul(json_value, NULL, 0));
if (result == 0) if (result == 0)
return; return;
image_found = 1; image_found = 1;
if (boot_addr_found == 0) /* Boot to last Image address if no bootargs.addr specified */
boot_addr = strtoul(json_value, NULL, 0);
}
} }
} }
/* Boot to last Image address */ /* Boot */
if (image_found) if (image_found)
boot(0, 0, 0, strtoul(image_address, NULL, 0)); boot(boot_r1, boot_r2, boot_r3, boot_addr);
} }
static void sdcardboot_from_bin(const char * filename) static void sdcardboot_from_bin(const char * filename)