[RFC/PATCH 1/2] kvm tools, seabios: Add "--bios" option to "vm run"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds a "--bios" command line option to "vm run". You can use this to
try to boot with SeaBIOS, for example:

  ./vm run --bios=/usr/share/seabios/bios.bin \
	 --disk $HOME/images/debian_lenny_amd64_standard.qcow2

This doesn't boot yet for obvious reasons but at least people can now start to
play with external BIOS images easily.

Cc: Yang Bai <hamo.by@xxxxxxxxx>
Cc: Matt Evans <matt@xxxxxxxxxx>
Cc: Ron Minnich <rminnich@xxxxxxxxx>
Cc: Anthony Liguori <aliguori@xxxxxxxxxx>
Cc: John Floren <john@xxxxxxxxxxx>
Cc: Sasha Levin <levinsasha928@xxxxxxxxx>
Cc: Cyrill Gorcunov <gorcunov@xxxxxxxxxx>
Cc: Asias He <asias.hejun@xxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxx>
Signed-off-by: Pekka Enberg <penberg@xxxxxxxxxx>
---
 tools/kvm/Makefile               |    2 +
 tools/kvm/builtin-run.c          |   32 +++++++++++++++++++----------
 tools/kvm/include/kvm/kvm.h      |    1 +
 tools/kvm/powerpc/boot.c         |    8 +++++++
 tools/kvm/x86/boot.c             |   41 ++++++++++++++++++++++++++++++++++++++
 tools/kvm/x86/include/kvm/bios.h |    3 +-
 6 files changed, 75 insertions(+), 12 deletions(-)
 create mode 100644 tools/kvm/powerpc/boot.c
 create mode 100644 tools/kvm/x86/boot.c

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index cfa5547..0a9c2cc 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -113,6 +113,7 @@ LIBFDT_OBJS = $(patsubst %,../../scripts/dtc/libfdt/%,$(LIBFDT_SRC))
 #x86
 ifeq ($(ARCH),x86)
 	DEFINES += -DCONFIG_X86
+	OBJS	+= x86/boot.o
 	OBJS	+= x86/cpuid.o
 	OBJS	+= x86/interrupt.o
 	OBJS	+= x86/ioport.o
@@ -129,6 +130,7 @@ endif
 # POWER/ppc:  Actually only support ppc64 currently.
 ifeq ($(uname_M), ppc64)
 	DEFINES += -DCONFIG_PPC
+	OBJS	+= powerpc/boot.o
 	OBJS	+= powerpc/ioport.o
 	OBJS	+= powerpc/irq.o
 	OBJS	+= powerpc/kvm.o
diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 466169e..f96c581 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -76,6 +76,7 @@ static const char *kernel_cmdline;
 static const char *kernel_filename;
 static const char *vmlinux_filename;
 static const char *initrd_filename;
+static const char *bios_filename;
 static const char *image_filename[MAX_DISK_IMAGES];
 static const char *console;
 static const char *dev;
@@ -458,6 +459,8 @@ static const struct option options[] = {
 			"Initial RAM disk image"),
 	OPT_STRING('p', "params", &kernel_cmdline, "params",
 			"Kernel command line arguments"),
+	OPT_STRING('b', "bios", &bios_filename, "bios",
+			"BIOS to boot in virtual machine"),
 
 	OPT_GROUP("Networking options:"),
 	OPT_CALLBACK_DEFAULT('n', "network", NULL, "network params",
@@ -1110,14 +1113,16 @@ static int kvm_cmd_run_init(int argc, const char **argv)
 	printf("  # %s run -k %s -m %Lu -c %d --name %s\n", KVM_BINARY_NAME,
 		kernel_filename, ram_size / 1024 / 1024, nrcpus, guest_name);
 
-	if (!kvm__load_kernel(kvm, kernel_filename, initrd_filename,
-				real_cmdline, vidmode))
-		die("unable to load kernel %s", kernel_filename);
+	if (!bios_filename) {
+		if (!kvm__load_kernel(kvm, kernel_filename,
+				initrd_filename, real_cmdline, vidmode))
+			die("unable to load kernel %s", kernel_filename);
 
-	kvm->vmlinux = vmlinux_filename;
-	r = symbol_init(kvm);
-	if (r < 0)
-		pr_debug("symbol_init() failed with error %d\n", r);
+		kvm->vmlinux = vmlinux_filename;
+		r = symbol_init(kvm);
+		if (r < 0)
+			pr_debug("symbol_init() failed with error %d\n", r);
+	}
 
 	ioport__setup_arch();
 
@@ -1218,10 +1223,15 @@ static int kvm_cmd_run_init(int argc, const char **argv)
 
 	kvm__start_timer(kvm);
 
-	kvm__arch_setup_firmware(kvm);
-	if (r < 0) {
-		pr_err("kvm__arch_setup_firmware() failed with error %d\n", r);
-		goto fail;
+	if (bios_filename) {
+		if (!kvm__load_bios(kvm, bios_filename))
+			die("unable to load bios %s: %s", bios_filename, strerror(errno));
+	} else {
+		kvm__arch_setup_firmware(kvm);
+		if (r < 0) {
+			pr_err("kvm__arch_setup_firmware() failed with error %d\n", r);
+			goto fail;
+		}
 	}
 
 	for (i = 0; i < nrcpus; i++) {
diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index 7870118..258d11a 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -39,6 +39,7 @@ int kvm__recommended_cpus(struct kvm *kvm);
 int kvm__max_cpus(struct kvm *kvm);
 void kvm__init_ram(struct kvm *kvm);
 int kvm__exit(struct kvm *kvm);
+bool kvm__load_bios(struct kvm *kvm, const char *bios_filename);
 bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
 			const char *initrd_filename, const char *kernel_cmdline, u16 vidmode);
 void kvm__start_timer(struct kvm *kvm);
diff --git a/tools/kvm/powerpc/boot.c b/tools/kvm/powerpc/boot.c
new file mode 100644
index 0000000..8c99831
--- /dev/null
+++ b/tools/kvm/powerpc/boot.c
@@ -0,0 +1,8 @@
+#include "kvm/kvm.h"
+
+#include <stdbool.h>
+
+bool kvm__load_bios(struct kvm *kvm, const char *bios_filename)
+{
+	return false;
+}
diff --git a/tools/kvm/x86/boot.c b/tools/kvm/x86/boot.c
new file mode 100644
index 0000000..383d9f7
--- /dev/null
+++ b/tools/kvm/x86/boot.c
@@ -0,0 +1,41 @@
+#include "kvm/kvm.h"
+
+#include "kvm/util.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdbool.h>
+#include <fcntl.h>
+
+#define BIOS_SELECTOR	0xf000
+#define BIOS_IP		0xfff0
+#define BIOS_SP		0x8000
+
+bool kvm__load_bios(struct kvm *kvm, const char *bios_filename)
+{
+	struct stat st;
+	void *p;
+	int fd;
+	int nr;
+
+	fd = open(bios_filename, O_RDONLY);
+	if (fd < 0)
+		return false;
+
+	if (fstat(fd, &st))
+		return false;
+
+	if (st.st_size > MB_BIOS_SIZE)
+		die("BIOS image %s is too big to fit in memory (%lu KB).\n", bios_filename, st.st_size / 1024);
+
+	p = guest_flat_to_host(kvm, MB_BIOS_BEGIN);
+
+	while ((nr = read(fd, p, st.st_size)) > 0)
+		p += nr;
+
+	kvm->boot_selector	= BIOS_SELECTOR;
+	kvm->boot_ip		= BIOS_IP;
+	kvm->boot_sp		= BIOS_SP;
+
+	return true;
+}
diff --git a/tools/kvm/x86/include/kvm/bios.h b/tools/kvm/x86/include/kvm/bios.h
index de569bc..9d677ae 100644
--- a/tools/kvm/x86/include/kvm/bios.h
+++ b/tools/kvm/x86/include/kvm/bios.h
@@ -26,8 +26,9 @@
 
 #define E820_MAP_START			EBDA_START
 
-#define MB_BIOS_BEGIN			0x000f0000
+#define MB_BIOS_BEGIN			0x000e0000
 #define MB_BIOS_END			0x000fffff
+#define MB_BIOS_SIZE			(MB_BIOS_END - MB_BIOS_BEGIN + 1)
 
 #define VGA_RAM_BEGIN			0x000a0000
 #define VGA_RAM_END			0x000bffff
-- 
1.7.6.5

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux