|
16 | 16 |
|
17 | 17 | #if RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER) |
18 | 18 | #include <termios.h> |
| 19 | +#include "dtc/libfdt/libfdt.h" |
19 | 20 | #endif |
20 | 21 |
|
21 | 22 | #if !defined(_WIN32) && !defined(_WIN64) |
@@ -261,11 +262,59 @@ static void map_file(char **ram_loc, const char *name) |
261 | 262 | exit(EXIT_FAILURE); |
262 | 263 | } |
263 | 264 |
|
264 | | -static void load_dtb(char **ram_loc) |
| 265 | +#define ALIGN_FDT(x) (((x) + (FDT_TAGSIZE) - 1) & ~((FDT_TAGSIZE) - 1)) |
| 266 | +static char *realloc_property(char *fdt, |
| 267 | + int nodeoffset, |
| 268 | + const char *name, |
| 269 | + int newlen) |
| 270 | +{ |
| 271 | + /* FIXME: assume RAM is enough */ |
| 272 | + int delta = 0; |
| 273 | + int oldlen = 0; |
| 274 | + |
| 275 | + if (!fdt_get_property(fdt, nodeoffset, name, &oldlen)) |
| 276 | + /* strings + property header */ |
| 277 | + delta = sizeof(struct fdt_property) + strlen(name) + 1; |
| 278 | + |
| 279 | + if (newlen > oldlen) |
| 280 | + /* actual value in off_struct */ |
| 281 | + delta += ALIGN_FDT(newlen) - ALIGN_FDT(oldlen); |
| 282 | + |
| 283 | + int new_sz = fdt_totalsize(fdt) + delta; |
| 284 | + fdt_open_into(fdt, fdt, new_sz); |
| 285 | + return fdt; |
| 286 | +} |
| 287 | + |
| 288 | +static void load_dtb(char **ram_loc, char *bootargs) |
265 | 289 | { |
266 | 290 | #include "minimal_dtb.h" |
267 | | - memcpy(*ram_loc, minimal, sizeof(minimal)); |
268 | | - *ram_loc += sizeof(minimal); |
| 291 | + char *blob = *ram_loc; |
| 292 | + char *buf; |
| 293 | + size_t len; |
| 294 | + int node, err; |
| 295 | + int totalsize; |
| 296 | + |
| 297 | + memcpy(blob, minimal, sizeof(minimal)); |
| 298 | + |
| 299 | + if (bootargs) { |
| 300 | + node = fdt_path_offset(blob, "/chosen"); |
| 301 | + assert(node > 0); |
| 302 | + |
| 303 | + len = strlen(bootargs) + 1; |
| 304 | + buf = malloc(len); |
| 305 | + memcpy(buf, bootargs, len - 1); |
| 306 | + buf[len] = 0; |
| 307 | + err = fdt_setprop(blob, node, "bootargs", buf, len + 1); |
| 308 | + if (err == -FDT_ERR_NOSPACE) { |
| 309 | + blob = realloc_property(blob, node, "bootargs", len); |
| 310 | + err = fdt_setprop(blob, node, "bootargs", buf, len); |
| 311 | + } |
| 312 | + free(buf); |
| 313 | + assert(!err); |
| 314 | + } |
| 315 | + |
| 316 | + totalsize = fdt_totalsize(blob); |
| 317 | + *ram_loc += totalsize; |
269 | 318 | return; |
270 | 319 | } |
271 | 320 |
|
@@ -420,7 +469,7 @@ riscv_t *rv_create(riscv_user_t rv_attr) |
420 | 469 |
|
421 | 470 | uint32_t dtb_addr = attr->mem->mem_size - (1 * 1024 * 1024); |
422 | 471 | ram_loc = ((char *) attr->mem->mem_base) + dtb_addr; |
423 | | - load_dtb(&ram_loc); |
| 472 | + load_dtb(&ram_loc, attr->data.system.bootargs); |
424 | 473 | /* |
425 | 474 | * Load optional initrd image at last 8 MiB before the dtb region to |
426 | 475 | * prevent kernel from overwritting it |
|
0 commit comments