Skip to content

Commit c62d231

Browse files
authored
Merge pull request #534 from RinHizakura/embed-dtb
Customize bootargs for system emulation
2 parents 81dd26e + 4c73b1a commit c62d231

File tree

10 files changed

+256
-15
lines changed

10 files changed

+256
-15
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ build/linux-x86-softfp/
2020
build/riscv32/
2121
build/sail_cSim/
2222
build/sha1sum-*
23+
build/bin2c
24+
build/minimal.dtb
2325
*.a
2426
*.o
2527
*.o.d
@@ -29,3 +31,4 @@ tests/arch-test-target/sail_cSim/riscv_sim_RV32
2931
tests/scimark2/
3032
__pycache__/
3133
src/rv32_jit.c
34+
src/minimal_dtb.h

.gitmodules

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,7 @@
3131
path = tests/quake
3232
url = https://github.com/sysprog21/quake-embedded
3333
shallow = true
34+
[submodule "src/dtc"]
35+
path = src/dtc
36+
url = https://git.kernel.org/pub/scm/utils/dtc/dtc.git
37+
shallow = true

Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ include mk/artifact.mk
241241
include mk/wasm.mk
242242
include mk/system.mk
243243

244-
all: config $(BUILD_DTB) $(BIN)
244+
all: config $(BUILD_DTB) $(BUILD_DTB2C) $(BIN)
245245

246246
OBJS := \
247247
map.o \
@@ -269,6 +269,7 @@ $(OBJS): $(GDBSTUB_LIB)
269269
endif
270270

271271
$(OUT)/%.o: src/%.c $(deps_emcc)
272+
$(Q)mkdir -p $(shell dirname $@)
272273
$(VECHO) " CC\t$@\n"
273274
$(Q)$(CC) -o $@ $(CFLAGS) $(CFLAGS_emcc) -c -MMD -MF $@.d $<
274275

@@ -369,7 +370,7 @@ endif
369370
endif
370371

371372
clean:
372-
$(RM) $(BIN) $(OBJS) $(DEV_OBJS) $(BUILD_DTB) $(HIST_BIN) $(HIST_OBJS) $(deps) $(WEB_FILES) $(CACHE_OUT) src/rv32_jit.c
373+
$(RM) $(BIN) $(OBJS) $(DEV_OBJS) $(BUILD_DTB) $(BUILD_DTB2C) $(HIST_BIN) $(HIST_OBJS) $(deps) $(WEB_FILES) $(CACHE_OUT) src/rv32_jit.c
373374
distclean: clean
374375
-$(RM) $(DOOM_DATA) $(QUAKE_DATA) $(BUILDROOT_DATA) $(LINUX_DATA)
375376
$(RM) -r $(OUT)/linux-image

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ $ make ENABLE_SYSTEM=1 system
7777
Build using run using specified images:
7878
```shell
7979
$ make ENABLE_SYSTEM=1
80-
$ build/rv32emu -k <kernel_img_path> -i <rootfs_img_path> -b <dtb_path>
80+
$ build/rv32emu -k <kernel_img_path> -i <rootfs_img_path>
8181
```
8282

8383
#### Build Linux image

mk/system.mk

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
# Peripherals for system emulation
22
ifeq ($(call has, SYSTEM), 1)
33

4+
CFLAGS += -Isrc/dtc/libfdt
5+
LIBFDT_HACK := $(shell git submodule update --init src/dtc)
6+
47
DEV_SRC := src/devices
58

69
DTC ?= dtc
7-
$(OUT)/minimal.dtb: $(DEV_SRC)/minimal.dts
10+
BUILD_DTB := $(OUT)/minimal.dtb
11+
$(BUILD_DTB): $(DEV_SRC)/minimal.dts
812
$(VECHO) " DTC\t$@\n"
913
$(Q)$(DTC) $^ -o $@
10-
BUILD_DTB := $(OUT)/minimal.dtb
14+
15+
BIN_TO_C := $(OUT)/bin2c
16+
$(BIN_TO_C): tools/bin2c.c
17+
$(Q)$(CC) -Wall -o $@ $^
18+
19+
BUILD_DTB2C := src/minimal_dtb.h
20+
$(BUILD_DTB2C): $(BIN_TO_C) $(BUILD_DTB)
21+
$(BIN_TO_C) $(BUILD_DTB) > $(BUILD_DTB2C)
1122

1223
$(DEV_OUT)/%.o: $(DEV_SRC)/%.c $(deps_emcc)
1324
$(Q)mkdir -p $(DEV_OUT)
@@ -17,11 +28,12 @@ DEV_OBJS := $(patsubst $(DEV_SRC)/%.c, $(DEV_OUT)/%.o, $(wildcard $(DEV_SRC)/*.c
1728
deps := $(DEV_OBJS:%.o=%.o.d)
1829

1930
OBJS_EXT += system.o
31+
OBJS_EXT += dtc/libfdt/fdt.o dtc/libfdt/fdt_ro.o dtc/libfdt/fdt_rw.o
2032

2133
# system target execution by using default dependencies
2234
LINUX_IMAGE_DIR := linux-image
23-
system_action := ($(BIN) -k $(OUT)/$(LINUX_IMAGE_DIR)/Image -i $(OUT)/$(LINUX_IMAGE_DIR)/rootfs.cpio -b $(OUT)/minimal.dtb)
24-
system_deps += artifact $(BUILD_DTB) $(BIN)
35+
system_action := ($(BIN) -k $(OUT)/$(LINUX_IMAGE_DIR)/Image -i $(OUT)/$(LINUX_IMAGE_DIR)/rootfs.cpio)
36+
system_deps += artifact $(BUILD_DTB) $(BUILD_DTB2C) $(BIN)
2537
system: $(system_deps)
2638
$(system_action)
2739

src/dtc

Submodule dtc added at 18f4f30

src/main.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static char *prof_out_file;
5555
/* Linux kernel data */
5656
static char *opt_kernel_img;
5757
static char *opt_rootfs_img;
58-
static char *opt_dtb;
58+
static char *opt_bootargs;
5959
#endif
6060

6161
static void print_usage(const char *filename)
@@ -73,7 +73,7 @@ static void print_usage(const char *filename)
7373
#if RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER)
7474
" -k <image> : use <image> as kernel image\n"
7575
" -i <image> : use <image> as rootfs\n"
76-
" -b <dtb> : use <dtb> as device tree blob\n"
76+
" -b <bootargs> : use customized <bootargs> for the kernel\n"
7777
#endif
7878
" -d [filename]: dump registers as JSON to the "
7979
"given file or `-` (STDOUT)\n"
@@ -115,7 +115,7 @@ static bool parse_args(int argc, char **args)
115115
emu_argc++;
116116
break;
117117
case 'b':
118-
opt_dtb = optarg;
118+
opt_bootargs = optarg;
119119
emu_argc++;
120120
break;
121121
#endif
@@ -263,7 +263,7 @@ int main(int argc, char **args)
263263
#if RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER)
264264
attr.data.system.kernel = opt_kernel_img;
265265
attr.data.system.initrd = opt_rootfs_img;
266-
attr.data.system.dtb = opt_dtb;
266+
attr.data.system.bootargs = opt_bootargs;
267267
#else
268268
attr.data.user.elf_program = opt_prog_name;
269269
#endif

src/riscv.c

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#if RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER)
1616
#include <termios.h>
17+
#include "dtc/libfdt/libfdt.h"
1718
#endif
1819

1920
#if !defined(_WIN32) && !defined(_WIN64)
@@ -259,6 +260,64 @@ static void map_file(char **ram_loc, const char *name)
259260
exit(EXIT_FAILURE);
260261
}
261262

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)
288+
{
289+
#include "minimal_dtb.h"
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;
318+
return;
319+
}
320+
262321
/*
263322
* The control mode flag for keyboard.
264323
*
@@ -294,6 +353,7 @@ static void capture_keyboard_input()
294353
term.c_lflag &= ~TERMIOS_C_CFLAG;
295354
tcsetattr(0, TCSANOW, &term);
296355
}
356+
297357
#endif
298358

299359
/*
@@ -409,7 +469,7 @@ riscv_t *rv_create(riscv_user_t rv_attr)
409469

410470
uint32_t dtb_addr = attr->mem->mem_size - (1 * 1024 * 1024);
411471
ram_loc = ((char *) attr->mem->mem_base) + dtb_addr;
412-
map_file(&ram_loc, attr->data.system.dtb);
472+
load_dtb(&ram_loc, attr->data.system.bootargs);
413473
/*
414474
* Load optional initrd image at last 8 MiB before the dtb region to
415475
* prevent kernel from overwritting it
@@ -517,8 +577,7 @@ void rv_run(riscv_t *rv)
517577
vm_attr_t *attr = PRIV(rv);
518578
assert(attr &&
519579
#if RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER)
520-
attr->data.system.kernel && attr->data.system.initrd &&
521-
attr->data.system.dtb
580+
attr->data.system.kernel && attr->data.system.initrd
522581
#else
523582
attr->data.user.elf_program
524583
#endif

src/riscv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ typedef struct {
551551
typedef struct {
552552
char *kernel;
553553
char *initrd;
554-
char *dtb;
554+
char *bootargs;
555555
} vm_system_t;
556556
#endif /* RV32_HAS(SYSTEM) */
557557

0 commit comments

Comments
 (0)