mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
xen/arm: probe domU kernels and initrds
Find addresses, sizes on device tree from kernel_probe. Find the cmdline from the bootcmdlines array. Introduce a new boot_module_find_by_addr_and_kind function to match not just on boot module kind, but also by address so that we can support multiple domains. Introduce a boot_cmdline_find_by_name function to find the right struct cmdline based on the device tree node name of the "xen,domain" compatible node. Set command line for dom0 in kernel_probe for consistency. Signed-off-by: Stefano Stabellini <stefanos@xilinx.com> Acked-by: Julien Grall <julien.grall@arm.com>
This commit is contained in:
1 parent
9270e83846
commit
93ff7f1242
5 files changed
+93
-11
No files matched your search
@@ -2107,7 +2107,6 @@ static void __init find_gnttab_region(struct domain *d,
|
||||
|
||||
int __init construct_dom0(struct domain *d)
|
||||
{
|
||||
const struct bootcmdline *kernel = boot_cmdline_find_by_kind(BOOTMOD_KERNEL);
|
||||
struct kernel_info kinfo = {};
|
||||
struct vcpu *saved_current;
|
||||
int rc, i, cpu;
|
||||
@@ -2135,7 +2134,7 @@ int __init construct_dom0(struct domain *d)
|
||||
kinfo.unassigned_mem = dom0_mem;
|
||||
kinfo.d = d;
|
||||
|
||||
rc = kernel_probe(&kinfo);
|
||||
rc = kernel_probe(&kinfo, NULL);
|
||||
if ( rc < 0 )
|
||||
return rc;
|
||||
|
||||
@@ -2153,7 +2152,6 @@ int __init construct_dom0(struct domain *d)
|
||||
|
||||
#endif
|
||||
|
||||
kinfo.cmdline = (kernel != NULL) ? &kernel->cmdline[0] : NULL;
|
||||
allocate_memory(d, &kinfo);
|
||||
find_gnttab_region(d, &kinfo);
|
||||
|
||||
|
||||
+57
-7
@@ -421,22 +421,72 @@ static int __init kernel_zimage32_probe(struct kernel_info *info,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init kernel_probe(struct kernel_info *info)
|
||||
int __init kernel_probe(struct kernel_info *info,
|
||||
const struct dt_device_node *domain)
|
||||
{
|
||||
struct bootmodule *mod = boot_module_find_by_kind(BOOTMOD_KERNEL);
|
||||
struct bootmodule *mod = NULL;
|
||||
struct bootcmdline *cmd = NULL;
|
||||
struct dt_device_node *node;
|
||||
u64 kernel_addr, initrd_addr, size;
|
||||
int rc;
|
||||
|
||||
/* domain is NULL only for the hardware domain */
|
||||
if ( domain == NULL )
|
||||
{
|
||||
ASSERT(is_hardware_domain(info->d));
|
||||
|
||||
mod = boot_module_find_by_kind(BOOTMOD_KERNEL);
|
||||
|
||||
info->kernel_bootmodule = mod;
|
||||
info->initrd_bootmodule = boot_module_find_by_kind(BOOTMOD_RAMDISK);
|
||||
|
||||
cmd = boot_cmdline_find_by_kind(BOOTMOD_KERNEL);
|
||||
if ( cmd )
|
||||
info->cmdline = &cmd->cmdline[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *name = NULL;
|
||||
|
||||
dt_for_each_child_node(domain, node)
|
||||
{
|
||||
if ( dt_device_is_compatible(node, "multiboot,kernel") )
|
||||
{
|
||||
u32 len;
|
||||
const __be32 *val;
|
||||
|
||||
val = dt_get_property(node, "reg", &len);
|
||||
dt_get_range(&val, node, &kernel_addr, &size);
|
||||
mod = boot_module_find_by_addr_and_kind(
|
||||
BOOTMOD_KERNEL, kernel_addr);
|
||||
info->kernel_bootmodule = mod;
|
||||
}
|
||||
else if ( dt_device_is_compatible(node, "multiboot,ramdisk") )
|
||||
{
|
||||
u32 len;
|
||||
const __be32 *val;
|
||||
|
||||
val = dt_get_property(node, "reg", &len);
|
||||
dt_get_range(&val, node, &initrd_addr, &size);
|
||||
info->initrd_bootmodule = boot_module_find_by_addr_and_kind(
|
||||
BOOTMOD_RAMDISK, initrd_addr);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
name = dt_node_name(domain);
|
||||
cmd = boot_cmdline_find_by_name(name);
|
||||
if ( cmd )
|
||||
info->cmdline = &cmd->cmdline[0];
|
||||
}
|
||||
if ( !mod || !mod->size )
|
||||
{
|
||||
printk(XENLOG_ERR "Missing kernel boot module?\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
info->kernel_bootmodule = mod;
|
||||
|
||||
printk("Loading kernel from boot module @ %"PRIpaddr"\n", mod->start);
|
||||
|
||||
info->initrd_bootmodule = boot_module_find_by_kind(BOOTMOD_RAMDISK);
|
||||
printk("Loading Dom%pd kernel from boot module @ %"PRIpaddr"\n",
|
||||
info->d, info->kernel_bootmodule->start);
|
||||
if ( info->initrd_bootmodule )
|
||||
printk("Loading ramdisk from boot module @ %"PRIpaddr"\n",
|
||||
info->initrd_bootmodule->start);
|
||||
|
||||
@@ -55,7 +55,7 @@ struct kernel_info {
|
||||
* ->type
|
||||
* ->load hook, and sets loader specific variables ->zimage
|
||||
*/
|
||||
int kernel_probe(struct kernel_info *info);
|
||||
int kernel_probe(struct kernel_info *info, const struct dt_device_node *domain);
|
||||
|
||||
/*
|
||||
* Loads the kernel into guest RAM.
|
||||
|
||||
@@ -297,6 +297,37 @@ struct bootcmdline * __init boot_cmdline_find_by_kind(bootmodule_kind kind)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct bootcmdline * __init boot_cmdline_find_by_name(const char *name)
|
||||
{
|
||||
struct bootcmdlines *mods = &bootinfo.cmdlines;
|
||||
struct bootcmdline *mod;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0 ; i < mods->nr_mods ; i++ )
|
||||
{
|
||||
mod = &mods->cmdline[i];
|
||||
if ( strcmp(mod->dt_name, name) == 0 )
|
||||
return mod;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct bootmodule * __init boot_module_find_by_addr_and_kind(bootmodule_kind kind,
|
||||
paddr_t start)
|
||||
{
|
||||
struct bootmodules *mods = &bootinfo.modules;
|
||||
struct bootmodule *mod;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0 ; i < mods->nr_mods ; i++ )
|
||||
{
|
||||
mod = &mods->module[i];
|
||||
if ( mod->kind == kind && mod->start == start )
|
||||
return mod;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char * __init boot_module_kind_as_string(bootmodule_kind kind)
|
||||
{
|
||||
switch ( kind )
|
||||
|
||||
@@ -101,9 +101,12 @@ const char *boot_fdt_cmdline(const void *fdt);
|
||||
struct bootmodule *add_boot_module(bootmodule_kind kind,
|
||||
paddr_t start, paddr_t size, bool domU);
|
||||
struct bootmodule *boot_module_find_by_kind(bootmodule_kind kind);
|
||||
struct bootmodule * boot_module_find_by_addr_and_kind(bootmodule_kind kind,
|
||||
paddr_t start);
|
||||
void add_boot_cmdline(const char *name, const char *cmdline,
|
||||
bootmodule_kind kind, bool domU);
|
||||
struct bootcmdline *boot_cmdline_find_by_kind(bootmodule_kind kind);
|
||||
struct bootcmdline * boot_cmdline_find_by_name(const char *name);
|
||||
const char *boot_module_kind_as_string(bootmodule_kind kind);
|
||||
|
||||
extern uint32_t hyp_traps_vector[];
|
||||
|
||||