提交 ec426ff8 编写于 作者: E Edgar E. Iglesias

hw/microblaze: Add support for loading initrd images

Signed-off-by: NEdgar E. Iglesias <edgar.iglesias@gmail.com>
上级 d0b022a0
......@@ -26,6 +26,7 @@
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "qemu-common.h"
#include "sysemu/device_tree.h"
#include "sysemu/sysemu.h"
......@@ -39,6 +40,8 @@ static struct
void (*machine_cpu_reset)(MicroBlazeCPU *);
uint32_t bootstrap_pc;
uint32_t cmdline;
uint32_t initrd_start;
uint32_t initrd_end;
uint32_t fdt;
} boot_info;
......@@ -49,6 +52,7 @@ static void main_cpu_reset(void *opaque)
cpu_reset(CPU(cpu));
env->regs[5] = boot_info.cmdline;
env->regs[6] = boot_info.initrd_start;
env->regs[7] = boot_info.fdt;
env->sregs[SR_PC] = boot_info.bootstrap_pc;
if (boot_info.machine_cpu_reset) {
......@@ -58,6 +62,8 @@ static void main_cpu_reset(void *opaque)
static int microblaze_load_dtb(hwaddr addr,
uint32_t ramsize,
uint32_t initrd_start,
uint32_t initrd_end,
const char *kernel_cmdline,
const char *dtb_filename)
{
......@@ -80,6 +86,14 @@ static int microblaze_load_dtb(hwaddr addr,
}
}
if (initrd_start) {
qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
initrd_start);
qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
initrd_end);
}
cpu_physical_memory_write(addr, fdt, fdt_size);
return fdt_size;
}
......@@ -90,7 +104,9 @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
}
void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
uint32_t ramsize, const char *dtb_filename,
uint32_t ramsize,
const char *initrd_filename,
const char *dtb_filename,
void (*machine_cpu_reset)(MicroBlazeCPU *))
{
QemuOpts *machine_opts;
......@@ -151,6 +167,25 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
high = (ddr_base + kernel_size + 3) & ~3;
}
if (initrd_filename) {
int initrd_size;
uint32_t initrd_offset;
high = ROUND_UP(high + kernel_size, 4);
boot_info.initrd_start = high;
initrd_offset = boot_info.initrd_start - ddr_base;
initrd_size = load_image_targphys(initrd_filename,
boot_info.initrd_start,
ram_size - initrd_offset);
if (initrd_size < 0) {
error_report("qemu: could not load initrd '%s'\n",
initrd_filename);
exit(EXIT_FAILURE);
}
boot_info.initrd_end = boot_info.initrd_start + initrd_size;
high = ROUND_UP(high + initrd_size, 4);
}
boot_info.cmdline = high + 4096;
if (kernel_cmdline && strlen(kernel_cmdline)) {
pstrcpy_targphys("cmdline", boot_info.cmdline, 256, kernel_cmdline);
......@@ -158,6 +193,8 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
/* Provide a device-tree. */
boot_info.fdt = boot_info.cmdline + 4096;
microblaze_load_dtb(boot_info.fdt, ram_size,
boot_info.initrd_start,
boot_info.initrd_end,
kernel_cmdline,
dtb_filename);
}
......
......@@ -4,7 +4,9 @@
#include "hw/hw.h"
void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
uint32_t ramsize, const char *dtb_filename,
uint32_t ramsize,
const char *initrd_filename,
const char *dtb_filename,
void (*machine_cpu_reset)(MicroBlazeCPU *));
#endif /* __MICROBLAZE_BOOT __ */
......@@ -177,6 +177,7 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
}
microblaze_load_kernel(cpu, ddr_base, ram_size,
args->initrd_filename,
BINARY_DEVICE_TREE_FILE,
machine_cpu_reset);
......
......@@ -108,7 +108,9 @@ petalogix_s3adsp1800_init(QEMUMachineInitArgs *args)
xilinx_ethlite_create(&nd_table[0], ETHLITE_BASEADDR, irq[1], 0, 0);
microblaze_load_kernel(cpu, ddr_base, ram_size,
BINARY_DEVICE_TREE_FILE, machine_cpu_reset);
args->initrd_filename,
BINARY_DEVICE_TREE_FILE,
machine_cpu_reset);
}
static QEMUMachine petalogix_s3adsp1800_machine = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册