rewrote parsing of firmware arguments

This commit is contained in:
Steffen Vogel 2016-04-03 17:36:06 +02:00
parent 08b0e29280
commit ba3470efd3
5 changed files with 55 additions and 63 deletions

View file

@ -97,6 +97,5 @@ struct loader_callbacks {
const char * (*getenv)(void *arg, int num);
};
void fbsd_init(char *userboot_path, char *bootvolume_path, char *kernelenv,
char *cons);
int fbsd_init(char *opts[]);
uint64_t fbsd_load(void);

View file

@ -85,5 +85,5 @@ struct zero_page {
} __attribute__((packed));
#pragma clang diagnostic pop
void kexec_init(char *kernel_path, char *initrd_path, char *cmdline);
int kexec_init(char *opts[]);
uint64_t kexec(void);

View file

@ -929,14 +929,15 @@ disk_open(char *path)
return (err);
}
void
fbsd_init(char *userboot_path, char *bootvolume_path, char *kernelenv,
char *cons)
int
fbsd_init(char *opts[])
{
config.userboot = userboot_path;
config.bootvolume = bootvolume_path;
config.kernelenv = kernelenv;
config.cons = cons;
config.userboot = opts[0];
config.bootvolume = opts[1];
config.kernelenv = opts[2];
config.cons = opts[3];
return 0;
}
uint64_t

View file

@ -211,11 +211,13 @@ kexec_load_ramdisk(char *path) {
return 0;
}
void
kexec_init(char *kernel_path, char *initrd_path, char *cmdline) {
config.kernel = kernel_path;
config.initrd = initrd_path;
config.cmdline = cmdline;
int
kexec_init(char *opts[]) {
config.kernel = opts[0];
config.initrd = opts[1];
config.cmdline = opts[2];
return 0;
}
uint64_t

View file

@ -112,6 +112,15 @@ static struct bhyvestats {
uint64_t cpu_switch_direct;
} stats;
static const struct loader {
char *name;
int (*init)(char *opts[]);
uint64_t (*load)();
} *fw_loader, fw_loaders[] = {
{ "kexec", kexec_init, kexec },
{ "fbsd", fbsd_init, fbsd_load }
};
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
static struct mt_vmm_info {
@ -120,8 +129,6 @@ static struct mt_vmm_info {
} mt_vmm_info[VM_MAXCPU];
#pragma clang diagnostic pop
static uint64_t (*fw_func)(void);
__attribute__ ((noreturn)) static void
usage(int code)
{
@ -257,7 +264,7 @@ vcpu_thread(void *param)
assert(error == 0);
if (vcpu == BSP) {
rip_entry = fw_func();
rip_entry = fw_loader->load();
} else {
rip_entry = vmexit[vcpu].rip;
spinup_ap_realmode(vcpu, &rip_entry);
@ -723,50 +730,37 @@ parse_memsize(const char *opt, size_t *ret_memsize)
static int
firmware_parse(const char *opt) {
char *fw, *opt1, *opt2, *opt3, *cp;
int ret, i;
char *cp, *opts[16] = { NULL };
fw = strdup(opt);
if (strncmp(fw, "kexec", strlen("kexec")) == 0) {
fw_func = kexec;
} else if (strncmp(fw, "fbsd", strlen("fbsd")) == 0) {
fw_func = fbsd_load;
} else {
cp = strdup(opt);
/* Find method */
for (i = 0; i < (int) nitems(fw_loaders); i++) {
if (strncmp(cp, fw_loaders[i].name, strlen(fw_loaders[i].name)) == 0) {
fw_loader = &fw_loaders[i];
break;
}
}
if (fw_loader == NULL)
goto fail;
/* Split arguments */
for (i = 0; i < (int) nitems(opts) - 1; i++) {
cp = strchr(cp, ',');
if (cp != NULL) {
*cp = '\0';
opts[i] = ++cp;
}
else
break;
}
if ((cp = strchr(fw, ',')) != NULL) {
*cp = '\0';
opt1 = cp + 1;
} else {
goto fail;
}
if ((cp = strchr(opt1, ',')) != NULL) {
*cp = '\0';
opt2 = cp + 1;
} else {
goto fail;
}
if ((cp = strchr(opt2, ',')) != NULL) {
*cp = '\0';
opt3 = cp + 1;
} else {
goto fail;
}
opt2 = strlen(opt2) ? opt2 : NULL;
opt3 = strlen(opt3) ? opt3 : NULL;
if (fw_func == kexec) {
kexec_init(opt1, opt2, opt3);
} else if (fw_func == fbsd_load) {
/* FIXME: let user set boot-loader serial device */
fbsd_init(opt1, opt2, opt3, NULL);
} else {
/* Initialize loader */
ret = fw_loader->init(opts);
if (ret)
goto fail;
}
return 0;
@ -836,7 +830,7 @@ fail:
int
main(int argc, char *argv[])
{
int c, error, gdb_port, bvmcons, fw;
int c, error, gdb_port, bvmcons;
int dump_guest_memory, max_vcpus, mptgen;
int rtc_localtime;
uint64_t rip;
@ -851,7 +845,6 @@ main(int argc, char *argv[])
memsize = 256 * MB;
mptgen = 1;
rtc_localtime = 1;
fw = 0;
while ((c = getopt(argc, argv, "behvuwxMACHPWY:f:F:g:c:s:m:l:U:")) != -1) {
switch (c) {
@ -870,9 +863,6 @@ main(int argc, char *argv[])
case 'f':
if (firmware_parse(optarg) != 0) {
exit (1);
} else {
fw = 1;
break;
}
case 'F':
pidfile = optarg;
@ -935,7 +925,7 @@ main(int argc, char *argv[])
}
}
if (fw != 1)
if (fw_loader == NULL)
usage(1);
error = xh_vm_create();