|
14 | 14 |
|
15 | 15 | #if RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER) |
16 | 16 | #include <termios.h> |
| 17 | +#include "dtc/libfdt/libfdt.h" |
17 | 18 | #endif |
18 | 19 |
|
19 | 20 | #if !defined(_WIN32) && !defined(_WIN64) |
@@ -259,11 +260,61 @@ static void map_file(char **ram_loc, const char *name) |
259 | 260 | exit(EXIT_FAILURE); |
260 | 261 | } |
261 | 262 |
|
262 | | -static void load_dtb(char **ram_loc) |
| 263 | +#define ALIGN_FDT(x) (((x) + (FDT_TAGSIZE) - 1) & ~((FDT_TAGSIZE) - 1)) |
| 264 | +static char *realloc_property(char *fdt, |
| 265 | + int nodeoffset, |
| 266 | + const char *name, |
| 267 | + int newlen) |
| 268 | +{ |
| 269 | + int delta = 0; |
| 270 | + int oldlen = 0; |
| 271 | + |
| 272 | + if (!fdt_get_property(fdt, nodeoffset, name, &oldlen)) |
| 273 | + /* strings + property header */ |
| 274 | + delta = sizeof(struct fdt_property) + strlen(name) + 1; |
| 275 | + |
| 276 | + if (newlen > oldlen) |
| 277 | + /* actual value in off_struct */ |
| 278 | + delta += ALIGN_FDT(newlen) - ALIGN_FDT(oldlen); |
| 279 | + |
| 280 | + int new_sz = fdt_totalsize(fdt) + delta; |
| 281 | + /* Assume the pre-allocated RAM is enough here, so we |
| 282 | + * don't realloc any memory for fdt */ |
| 283 | + fdt_open_into(fdt, fdt, new_sz); |
| 284 | + return fdt; |
| 285 | +} |
| 286 | + |
| 287 | +static void load_dtb(char **ram_loc, char *bootargs) |
263 | 288 | { |
264 | 289 | #include "minimal_dtb.h" |
265 | | - memcpy(*ram_loc, minimal, sizeof(minimal)); |
266 | | - *ram_loc += sizeof(minimal); |
| 290 | + char *blob = *ram_loc; |
| 291 | + char *buf; |
| 292 | + size_t len; |
| 293 | + int node, err; |
| 294 | + int totalsize; |
| 295 | + |
| 296 | + memcpy(blob, minimal, sizeof(minimal)); |
| 297 | + |
| 298 | + if (bootargs) { |
| 299 | + node = fdt_path_offset(blob, "/chosen"); |
| 300 | + assert(node > 0); |
| 301 | + |
| 302 | + len = strlen(bootargs) + 1; |
| 303 | + buf = malloc(len); |
| 304 | + assert(buf); |
| 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; |
267 | 318 | return; |
268 | 319 | } |
269 | 320 |
|
@@ -418,7 +469,7 @@ riscv_t *rv_create(riscv_user_t rv_attr) |
418 | 469 |
|
419 | 470 | uint32_t dtb_addr = attr->mem->mem_size - (1 * 1024 * 1024); |
420 | 471 | ram_loc = ((char *) attr->mem->mem_base) + dtb_addr; |
421 | | - load_dtb(&ram_loc); |
| 472 | + load_dtb(&ram_loc, attr->data.system.bootargs); |
422 | 473 | /* |
423 | 474 | * Load optional initrd image at last 8 MiB before the dtb region to |
424 | 475 | * prevent kernel from overwritting it |
|
0 commit comments