Skip to content

Commit 1fd6cc7

Browse files
committed
Generate DTB in runtime
1 parent 81dd26e commit 1fd6cc7

File tree

8 files changed

+182
-19
lines changed

8 files changed

+182
-19
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/bin_to_c
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

Makefile

Lines changed: 2 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 \
@@ -369,7 +369,7 @@ endif
369369
endif
370370

371371
clean:
372-
$(RM) $(BIN) $(OBJS) $(DEV_OBJS) $(BUILD_DTB) $(HIST_BIN) $(HIST_OBJS) $(deps) $(WEB_FILES) $(CACHE_OUT) src/rv32_jit.c
372+
$(RM) $(BIN) $(OBJS) $(DEV_OBJS) $(BUILD_DTB) $(BUILD_DTB2C) $(HIST_BIN) $(HIST_OBJS) $(deps) $(WEB_FILES) $(CACHE_OUT) src/rv32_jit.c
373373
distclean: clean
374374
-$(RM) $(DOOM_DATA) $(QUAKE_DATA) $(BUILDROOT_DATA) $(LINUX_DATA)
375375
$(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: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,18 @@ ifeq ($(call has, SYSTEM), 1)
44
DEV_SRC := src/devices
55

66
DTC ?= dtc
7-
$(OUT)/minimal.dtb: $(DEV_SRC)/minimal.dts
7+
BUILD_DTB := $(OUT)/minimal.dtb
8+
$(BUILD_DTB): $(DEV_SRC)/minimal.dts
89
$(VECHO) " DTC\t$@\n"
910
$(Q)$(DTC) $^ -o $@
10-
BUILD_DTB := $(OUT)/minimal.dtb
11+
12+
BIN_TO_C := $(OUT)/bin_to_c
13+
$(BIN_TO_C): tools/bin_to_c.c
14+
$(Q)$(CC) -Wall -o $@ $^
15+
16+
BUILD_DTB2C := src/minimal_dtb.h
17+
$(BUILD_DTB2C): $(BIN_TO_C) $(BUILD_DTB)
18+
$(BIN_TO_C) $(BUILD_DTB) > $(BUILD_DTB2C)
1119

1220
$(DEV_OUT)/%.o: $(DEV_SRC)/%.c $(deps_emcc)
1321
$(Q)mkdir -p $(DEV_OUT)
@@ -20,8 +28,8 @@ OBJS_EXT += system.o
2028

2129
# system target execution by using default dependencies
2230
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)
31+
system_action := ($(BIN) -k $(OUT)/$(LINUX_IMAGE_DIR)/Image -i $(OUT)/$(LINUX_IMAGE_DIR)/rootfs.cpio)
32+
system_deps += artifact $(BUILD_DTB) $(BUILD_DTB2C) $(BIN)
2533
system: $(system_deps)
2634
$(system_action)
2735

src/main.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ static char *opt_prog_name;
4242
/* target argc and argv */
4343
static int prog_argc;
4444
static char **prog_args;
45-
static const char *optstr = "tgqmhpd:a:k:i:b:";
45+
static const char *optstr = "tgqmhpd:a:k:i:";
4646

4747
/* enable misaligned memory access */
4848
static bool opt_misaligned = false;
@@ -55,7 +55,6 @@ 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;
5958
#endif
6059

6160
static void print_usage(const char *filename)
@@ -73,7 +72,6 @@ static void print_usage(const char *filename)
7372
#if RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER)
7473
" -k <image> : use <image> as kernel image\n"
7574
" -i <image> : use <image> as rootfs\n"
76-
" -b <dtb> : use <dtb> as device tree blob\n"
7775
#endif
7876
" -d [filename]: dump registers as JSON to the "
7977
"given file or `-` (STDOUT)\n"
@@ -114,10 +112,6 @@ static bool parse_args(int argc, char **args)
114112
opt_rootfs_img = optarg;
115113
emu_argc++;
116114
break;
117-
case 'b':
118-
opt_dtb = optarg;
119-
emu_argc++;
120-
break;
121115
#endif
122116
case 'q':
123117
opt_quiet_outputs = true;
@@ -263,7 +257,6 @@ int main(int argc, char **args)
263257
#if RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER)
264258
attr.data.system.kernel = opt_kernel_img;
265259
attr.data.system.initrd = opt_rootfs_img;
266-
attr.data.system.dtb = opt_dtb;
267260
#else
268261
attr.data.user.elf_program = opt_prog_name;
269262
#endif

src/riscv.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,14 @@ static void map_file(char **ram_loc, const char *name)
259259
exit(EXIT_FAILURE);
260260
}
261261

262+
static void load_dtb(char **ram_loc)
263+
{
264+
#include "minimal_dtb.h"
265+
memcpy(*ram_loc, minimal, sizeof(minimal));
266+
*ram_loc += sizeof(minimal);
267+
return;
268+
}
269+
262270
/*
263271
* The control mode flag for keyboard.
264272
*
@@ -294,6 +302,7 @@ static void capture_keyboard_input()
294302
term.c_lflag &= ~TERMIOS_C_CFLAG;
295303
tcsetattr(0, TCSANOW, &term);
296304
}
305+
297306
#endif
298307

299308
/*
@@ -409,7 +418,7 @@ riscv_t *rv_create(riscv_user_t rv_attr)
409418

410419
uint32_t dtb_addr = attr->mem->mem_size - (1 * 1024 * 1024);
411420
ram_loc = ((char *) attr->mem->mem_base) + dtb_addr;
412-
map_file(&ram_loc, attr->data.system.dtb);
421+
load_dtb(&ram_loc);
413422
/*
414423
* Load optional initrd image at last 8 MiB before the dtb region to
415424
* prevent kernel from overwritting it
@@ -517,8 +526,7 @@ void rv_run(riscv_t *rv)
517526
vm_attr_t *attr = PRIV(rv);
518527
assert(attr &&
519528
#if RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER)
520-
attr->data.system.kernel && attr->data.system.initrd &&
521-
attr->data.system.dtb
529+
attr->data.system.kernel && attr->data.system.initrd
522530
#else
523531
attr->data.user.elf_program
524532
#endif

src/riscv.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,6 @@ typedef struct {
551551
typedef struct {
552552
char *kernel;
553553
char *initrd;
554-
char *dtb;
555554
} vm_system_t;
556555
#endif /* RV32_HAS(SYSTEM) */
557556

tools/bin_to_c.c

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
//
2+
// bin_to_c - convert binary data into c-compatible data tables
3+
//
4+
// Written by Larry Bank
5+
// Copyright (c) 2009 BitBank Software, Inc.
6+
// Change history
7+
// 2/1/09 - Started the project
8+
// 11/6/15 - converted to Linux
9+
// 7/29/20 - tailored to Arduino FLASH data output
10+
//
11+
#include <stdint.h>
12+
#include <string.h>
13+
#include <stdio.h>
14+
#include <stdlib.h>
15+
FILE * ihandle;
16+
void MakeC(unsigned char *, int, int);
17+
void GetLeafName(char *fname, char *leaf);
18+
void FixName(char *name);
19+
20+
int main(int argc, char *argv[])
21+
{
22+
int iSize, iData;
23+
unsigned char *p;
24+
char szLeaf[256];
25+
26+
if (argc != 2)
27+
{
28+
printf("bin_to_c Copyright (c) 2013 BitBank Software, Inc.\n");
29+
printf("Usage: bin_to_c <filename>\n");
30+
printf("output is written to stdout\n");
31+
return 0; // no filename passed
32+
}
33+
ihandle = fopen(argv[1],"rb"); // open input file
34+
if (ihandle == NULL)
35+
{
36+
printf("Unable to open file: %s\n", argv[1]);
37+
return -1; // bad filename passed
38+
}
39+
40+
fseek(ihandle, 0L, SEEK_END); // get the file size
41+
iSize = (int)ftell(ihandle);
42+
fseek(ihandle, 0, SEEK_SET);
43+
p = (unsigned char *)malloc(0x10000); // allocate 64k to play with
44+
GetLeafName(argv[1], szLeaf);
45+
printf("//\n// %s\n//\n", szLeaf); // comment header with filename
46+
FixName(szLeaf); // remove unusable characters
47+
printf("const uint8_t %s[] = {", szLeaf); // start of data array
48+
while (iSize)
49+
{
50+
iData = fread(p, 1, 0x10000, ihandle); // try to read 64k
51+
MakeC(p, iData, iSize == iData); // create the output data
52+
iSize -= iData;
53+
}
54+
free(p);
55+
fclose(ihandle);
56+
printf("};\n"); // final closing brace
57+
return 0;
58+
} /* main() */
59+
//
60+
// Generate C hex characters from each byte of file data
61+
//
62+
void MakeC(unsigned char *p, int iLen, int bLast)
63+
{
64+
int i, j, iCount;
65+
char szTemp[256], szOut[256];
66+
67+
iCount = 0;
68+
for (i=0; i<iLen>>4; i++) // do lines of 16 bytes
69+
{
70+
strcpy(szOut, "\t");
71+
for (j=0; j<16; j++)
72+
{
73+
if (iCount == iLen-1 && bLast) // last one, skip the comma
74+
sprintf(szTemp, "0x%02x", p[(i*16)+j]);
75+
else
76+
sprintf(szTemp, "0x%02x,", p[(i*16)+j]);
77+
strcat(szOut, szTemp);
78+
iCount++;
79+
}
80+
if (!bLast || iCount != iLen)
81+
strcat(szOut, "\n");
82+
printf("%s",szOut);
83+
}
84+
p += (iLen & 0xfff0); // point to last section
85+
if (iLen & 0xf) // any remaining characters?
86+
{
87+
strcpy(szOut, "\t");
88+
for (j=0; j<(iLen & 0xf); j++)
89+
{
90+
if (iCount == iLen-1 && bLast)
91+
sprintf(szTemp, "0x%02x", p[j]);
92+
else
93+
sprintf(szTemp, "0x%02x,", p[j]);
94+
strcat(szOut, szTemp);
95+
iCount++;
96+
}
97+
if (!bLast)
98+
strcat(szOut, "\n");
99+
printf("%s",szOut);
100+
}
101+
} /* MakeC() */
102+
//
103+
// Make sure the name can be used in C/C++ as a variable
104+
// replace invalid characters and make sure it starts with a letter
105+
//
106+
void FixName(char *name)
107+
{
108+
char c, *d, *s, szTemp[256];
109+
int i, iLen;
110+
111+
iLen = strlen(name);
112+
d = szTemp;
113+
s = name;
114+
if (s[0] >= '0' && s[0] <= '9') // starts with a digit
115+
*d++ = '_'; // Insert an underscore
116+
for (i=0; i<iLen; i++)
117+
{
118+
c = *s++;
119+
// these characters can't be in a variable name
120+
if (c < ' ' || (c >= '!' && c < '0') || (c > 'Z' && c < 'a'))
121+
c = '_'; // convert all to an underscore
122+
*d++ = c;
123+
}
124+
*d++ = 0;
125+
strcpy(name, szTemp);
126+
} /* FixName() */
127+
//
128+
// Trim off the leaf name from a fully
129+
// formed file pathname
130+
//
131+
void GetLeafName(char *fname, char *leaf)
132+
{
133+
int i, iLen;
134+
135+
iLen = strlen(fname);
136+
for (i=iLen-1; i>=0; i--)
137+
{
138+
if (fname[i] == '\\' || fname[i] == '/') // Windows or Linux
139+
break;
140+
}
141+
strcpy(leaf, &fname[i+1]);
142+
// remove the filename extension
143+
iLen = strlen(leaf);
144+
for (i=iLen-1; i>=0; i--)
145+
{
146+
if (leaf[i] == '.')
147+
{
148+
leaf[i] = 0;
149+
break;
150+
}
151+
}
152+
} /* GetLeafName() */

0 commit comments

Comments
 (0)