Skip to content

Commit 5dbd74a

Browse files
committed
Support loading initrd image
In this commit, the `rootfs.cpio` provided by the buildroot can be passed to semu with -i option. In order to achieve such function, the following modifcations are conducted: 1. Reserve 8 MiB of memory at the end of the guest OS before the dtb region, and map initrd image to the new reserved area. 2. Adjust device tree source by specifying `initrd-start` and `initrd-end`. 3. Support passing initrd image with -i option.
1 parent 0c43584 commit 5dbd74a

File tree

4 files changed

+36
-11
lines changed

4 files changed

+36
-11
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ ext4.img:
8282

8383
check: $(BIN) minimal.dtb $(KERNEL_DATA) $(DISKIMG_FILE)
8484
@$(call notice, Ready to launch Linux kernel. Please be patient.)
85-
$(Q)./$(BIN) -k $(KERNEL_DATA) -b minimal.dtb $(OPTS)
85+
$(Q)./$(BIN) -k $(KERNEL_DATA) -b minimal.dtb -i rootfs.cpio $(OPTS)
8686

8787
build-image:
8888
scripts/build-image.sh

device.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
/* RAM */
77

88
#define RAM_SIZE (512 * 1024 * 1024)
9+
#define DTB_SIZE (1 * 1024 * 1024)
10+
#define INITRD_SIZE (8 * 1024 * 1024)
911

1012
void ram_read(vm_t *core,
1113
uint32_t *mem,

main.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -291,35 +291,40 @@ static void map_file(char **ram_loc, const char *name)
291291

292292
static void usage(const char *execpath)
293293
{
294-
fprintf(stderr, "Usage: %s -k linux-image [-b dtb] [-d disk-image]\n",
295-
execpath);
294+
fprintf(
295+
stderr,
296+
"Usage: %s -k linux-image [-b dtb] [-i initrd-image] [-d disk-image]\n",
297+
execpath);
296298
}
297299

298300
static void handle_options(int argc,
299301
char **argv,
300302
char **kernel_file,
301303
char **dtb_file,
304+
char **initrd_file,
302305
char **disk_file)
303306
{
304-
*kernel_file = *dtb_file = *disk_file = NULL;
307+
*kernel_file = *dtb_file = *initrd_file = *disk_file = NULL;
305308

306309
int optidx = 0;
307310
struct option opts[] = {
308-
{"kernel", 1, NULL, 'k'},
309-
{"dtb", 1, NULL, 'b'},
310-
{"disk", 1, NULL, 'd'},
311+
{"kernel", 1, NULL, 'k'}, {"dtb", 1, NULL, 'b'},
312+
{"initrd", 1, NULL, 'i'}, {"disk", 1, NULL, 'd'},
311313
{"help", 0, NULL, 'h'},
312314
};
313315

314316
int c;
315-
while ((c = getopt_long(argc, argv, "k:b:d:h", opts, &optidx)) != -1) {
317+
while ((c = getopt_long(argc, argv, "k:b:i:d:h", opts, &optidx)) != -1) {
316318
switch (c) {
317319
case 'k':
318320
*kernel_file = optarg;
319321
break;
320322
case 'b':
321323
*dtb_file = optarg;
322324
break;
325+
case 'i':
326+
*initrd_file = optarg;
327+
break;
323328
case 'd':
324329
*disk_file = optarg;
325330
break;
@@ -347,8 +352,10 @@ static int semu_start(int argc, char **argv)
347352
{
348353
char *kernel_file;
349354
char *dtb_file;
355+
char *initrd_file;
350356
char *disk_file;
351-
handle_options(argc, argv, &kernel_file, &dtb_file, &disk_file);
357+
handle_options(argc, argv, &kernel_file, &dtb_file, &initrd_file,
358+
&disk_file);
352359

353360
/* Initialize the emulator */
354361
emu_state_t emu;
@@ -371,13 +378,27 @@ static int semu_start(int argc, char **argv)
371378
}
372379
assert(!(((uintptr_t) emu.ram) & 0b11));
373380

381+
/* *-----------------------------------------*
382+
* | Memory layout |
383+
* *----------------*----------------*-------*
384+
* | kernel image | initrd image | dtb |
385+
* *----------------*----------------*-------*
386+
*/
374387
char *ram_loc = (char *) emu.ram;
375388
/* Load Linux kernel image */
376389
map_file(&ram_loc, kernel_file);
377-
/* Load at last 1 MiB to prevent kernel / initrd from overwriting it */
378-
uint32_t dtb_addr = RAM_SIZE - 1024 * 1024; /* Device tree */
390+
/* Load at last 1 MiB to prevent kernel from overwriting it */
391+
uint32_t dtb_addr = RAM_SIZE - DTB_SIZE; /* Device tree */
379392
ram_loc = ((char *) emu.ram) + dtb_addr;
380393
map_file(&ram_loc, dtb_file);
394+
/* Load optional initrd image at last 8 MiB before the dtb region to
395+
* prevent kernel from overwritting it
396+
*/
397+
if (initrd_file) {
398+
uint32_t initrd_addr = dtb_addr - INITRD_SIZE; /* Init RAM disk */
399+
ram_loc = ((char *) emu.ram) + initrd_addr;
400+
map_file(&ram_loc, initrd_file);
401+
}
381402

382403
/* Hook for unmapping files */
383404
atexit(unmap_files);

minimal.dts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
chosen {
1313
bootargs = "earlycon console=ttyS0";
1414
stdout-path = "serial0";
15+
linux,initrd-start = <0x1f700000>; /* @403 MiB (503 * 1024 * 1024) */
16+
linux,initrd-end = <0x1fefffff>; /* @511 MiB (511 * 1024 * 1024 - 1) */
1517
};
1618

1719
cpus {

0 commit comments

Comments
 (0)