diff mbox

[3/3] kvm tools, ui: Add support for SDL framebuffer output target

Message ID 1307116779-572-3-git-send-email-penberg@kernel.org (mailing list archive)
State New, archived
Headers show

Commit Message

Pekka Enberg June 3, 2011, 3:59 p.m. UTC
This patch adds support for SDL based framebuffer. Use the '--sdl' command line
option to enable the feature.

Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: John Floren <john@jfloren.net>
Cc: Sasha Levin <levinsasha928@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
---
 tools/kvm/Makefile                 |    8 ++++
 tools/kvm/config/feature-tests.mak |   10 +++++
 tools/kvm/include/kvm/sdl.h        |   14 +++++++
 tools/kvm/kvm-run.c                |   17 +++++++--
 tools/kvm/ui/sdl.c                 |   71 ++++++++++++++++++++++++++++++++++++
 5 files changed, 116 insertions(+), 4 deletions(-)
 create mode 100644 tools/kvm/include/kvm/sdl.h
 create mode 100644 tools/kvm/ui/sdl.c

Comments

Ingo Molnar June 3, 2011, 4:26 p.m. UTC | #1
* Pekka Enberg <penberg@kernel.org> wrote:

> This patch adds support for SDL based framebuffer. Use the '--sdl' command line
> option to enable the feature.

Very nice!

I tried them out - but i'm unsure how to activate the feature.

Right now 'kvm run' will run the guest and it outputs to the serial 
console. If i try 'kvm run --sdl' i get:

 linux/tools/kvm> ./kvm run --sdl
  # kvm run -k ../../arch/x86/boot/bzImage -m 1216 -c 16
  Warning: Unable to open /dev/net/tun
 Undefined video mode number: 312
 Press <ENTER> to see video modes available, <SPACE> to continue, or wait 30 sec

What kind of options should i select on the guest kernel image side 
to be able to boot via the SDL framebuffer?

	Ingo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ingo Molnar June 3, 2011, 4:28 p.m. UTC | #2
* Ingo Molnar <mingo@elte.hu> wrote:

> Right now 'kvm run' will run the guest and it outputs to the serial 
> console. If i try 'kvm run --sdl' i get:
> 
>  linux/tools/kvm> ./kvm run --sdl
>   # kvm run -k ../../arch/x86/boot/bzImage -m 1216 -c 16
>   Warning: Unable to open /dev/net/tun
>  Undefined video mode number: 312
>  Press <ENTER> to see video modes available, <SPACE> to continue, or wait 30 sec
> 
> What kind of options should i select on the guest kernel image side 
> to be able to boot via the SDL framebuffer?

Ok, found it, the guest kernel needs CONFIG_FB_VESA=y set.

Thanks,

	Ingo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pekka Enberg June 3, 2011, 4:30 p.m. UTC | #3
On Fri, 3 Jun 2011, Ingo Molnar wrote:
> Very nice!
>
> I tried them out - but i'm unsure how to activate the feature.
>
> Right now 'kvm run' will run the guest and it outputs to the serial
> console. If i try 'kvm run --sdl' i get:
>
> linux/tools/kvm> ./kvm run --sdl

That's correct.

>  # kvm run -k ../../arch/x86/boot/bzImage -m 1216 -c 16
>  Warning: Unable to open /dev/net/tun
> Undefined video mode number: 312
> Press <ENTER> to see video modes available, <SPACE> to continue, or wait 30 sec
>
> What kind of options should i select on the guest kernel image side
> to be able to boot via the SDL framebuffer?

That's not related to the SDL code but to the VESA code. I suppose you 
never tried the VNC version so you need to make sure the following config 
options are there:

From: John Floren <john@jfloren.net>
Date: Mon, 23 May 2011 12:15:18 +0000 (+0300)
Subject: kvm tools: Initialize and use VESA and VNC
X-Git-Url: 
http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fpenberg%2Fslab-2.6.git;a=commitdiff_plain;h=20a2b9bbed84df6d734f5566709b0501467e3c68

kvm tools: Initialize and use VESA and VNC

Requirements - Kernel compiled with:
CONFIG_FB_BOOT_VESA_SUPPORT=y
CONFIG_FB_VESA=y
CONFIG_FRAMEBUFFER_CONSOLE=y

Start VNC server by starting kvm tools with "--vnc".
Connect to the VNC server by running: "vncviewer :0".

Since there is no support for input devices at this time,
it may be useful starting kvm tools with an additional
' -p "console=ttyS0" ' parameter so that it would be possible
to use a serial console alongside with a graphic one.

Signed-off-by: John Floren <john@jfloren.net>
[ turning code into patches and cleanup ]
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>

 			Pekka
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ingo Molnar June 3, 2011, 4:33 p.m. UTC | #4
i don't seem to be able to get the SDL window to inizialize over ssh 
X-forwarding:

 linux/tools/kvm> ./kvm run --sdl
  # kvm run -k ../../arch/x86/boot/bzImage -m 1216 -c 16
  Warning: Unable to open /dev/net/tun
 ???

Thanks,

	Ingo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pekka Enberg June 3, 2011, 4:37 p.m. UTC | #5
On Fri, 3 Jun 2011, Ingo Molnar wrote:

>
> i don't seem to be able to get the SDL window to inizialize over ssh
> X-forwarding:
>
> linux/tools/kvm> ./kvm run --sdl
>  # kvm run -k ../../arch/x86/boot/bzImage -m 1216 -c 16
>  Warning: Unable to open /dev/net/tun
> ?????????

Please pass

   -p "console=ttyS0"

to 'kvm' to see if there's error messages in dmesg. I suppose we should 
enable that by default.

 			Pekka
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ingo Molnar June 3, 2011, 4:40 p.m. UTC | #6
* Pekka Enberg <penberg@kernel.org> wrote:

> Please pass
> 
>   -p "console=ttyS0"
> 
> to 'kvm' to see if there's error messages in dmesg. I suppose we
> should enable that by default.

It says:

[    0.639000] vesafb: mode is 640x480x32, linelength=2560, pages=0
[    0.640000] vesafb: scrolling: redraw
[    0.641000] vesafb: Truecolor: size=8:8:8:8, shift=24:0:8:16
[    0.642000] vesafb: framebuffer at 0xd0000000, mapped to 0xffffc90000900000, using 1200k, total 1200k
[    1.899000] Console: switching to colour frame buffer device 80x30
[    3.955000] fb0: VESA VGA frame buffer device
[    4.681000] virtio-pci 0000:00:01.0: enabling device (0000 -> 0001)

An SDL window should have been created at that point, right? But it 
does not show up.

Thanks,

	Ingo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pekka Enberg June 3, 2011, 4:44 p.m. UTC | #7
On Fri, 3 Jun 2011, Ingo Molnar wrote:
> It says:
>
> [    0.639000] vesafb: mode is 640x480x32, linelength=2560, pages=0
> [    0.640000] vesafb: scrolling: redraw
> [    0.641000] vesafb: Truecolor: size=8:8:8:8, shift=24:0:8:16
> [    0.642000] vesafb: framebuffer at 0xd0000000, mapped to 0xffffc90000900000, using 1200k, total 1200k
> [    1.899000] Console: switching to colour frame buffer device 80x30
> [    3.955000] fb0: VESA VGA frame buffer device
> [    4.681000] virtio-pci 0000:00:01.0: enabling device (0000 -> 0001)
>
> An SDL window should have been created at that point, right? But it
> does not show up.

Yup. I tried

   ssh -X localhost

and ran 'kvm run --sdl' there and it worked fine. Hmm.

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

Patch

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 17c795b..55949aa 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -71,6 +71,14 @@  ifeq ($(has_vncserver),y)
 	LIBS	+= -lvncserver
 endif
 
+FLAGS_SDL=$(CFLAGS) -lSDL
+has_SDL := $(call try-cc,$(SOURCE_SDL),$(FLAGS_SDL))
+ifeq ($(has_SDL),y)
+	OBJS	+= ui/sdl.o
+	CFLAGS	+= -DCONFIG_HAS_SDL
+	LIBS	+= -lSDL
+endif
+
 DEPS	:= $(patsubst %.o,%.d,$(OBJS))
 
 # Exclude BIOS object files from header dependencies.
diff --git a/tools/kvm/config/feature-tests.mak b/tools/kvm/config/feature-tests.mak
index 0801b54..bfd10ca 100644
--- a/tools/kvm/config/feature-tests.mak
+++ b/tools/kvm/config/feature-tests.mak
@@ -136,3 +136,13 @@  int main(void)
 	return 0;
 }
 endef
+
+define SOURCE_SDL
+#include <SDL/SDL.h>
+
+int main(void)
+{
+	SDL_Init(SDL_INIT_VIDEO);
+	return 0;
+}
+endef
diff --git a/tools/kvm/include/kvm/sdl.h b/tools/kvm/include/kvm/sdl.h
new file mode 100644
index 0000000..7057770
--- /dev/null
+++ b/tools/kvm/include/kvm/sdl.h
@@ -0,0 +1,14 @@ 
+#ifndef KVM__SDL_H
+#define KVM__SDL_H
+
+struct framebuffer;
+
+#ifdef CONFIG_HAS_SDL
+void sdl__init(struct framebuffer *fb);
+#else
+static inline void sdl__init(struct framebuffer *fb)
+{
+}
+#endif
+
+#endif /* KVM__SDL_H */
diff --git a/tools/kvm/kvm-run.c b/tools/kvm/kvm-run.c
index e6e180b..8398287 100644
--- a/tools/kvm/kvm-run.c
+++ b/tools/kvm/kvm-run.c
@@ -32,6 +32,7 @@ 
 #include <kvm/ioeventfd.h>
 #include <kvm/i8042.h>
 #include <kvm/vnc.h>
+#include <kvm/sdl.h>
 #include <kvm/framebuffer.h>
 
 /* header files for gitish interface  */
@@ -72,6 +73,7 @@  static const char *virtio_9p_dir;
 static bool single_step;
 static bool readonly_image[MAX_DISK_IMAGES];
 static bool vnc;
+static bool sdl;
 extern bool ioport_debug;
 extern int  active_console;
 
@@ -117,6 +119,7 @@  static const struct option options[] = {
 	OPT_STRING('\0', "virtio-9p", &virtio_9p_dir, "root dir",
 			"Enable 9p over virtio"),
 	OPT_BOOLEAN('\0', "vnc", &vnc, "Enable VNC framebuffer"),
+	OPT_BOOLEAN('\0', "sdl", &sdl, "Enable SDL framebuffer"),
 
 	OPT_GROUP("Kernel options:"),
 	OPT_STRING('k', "kernel", &kernel_filename, "kernel",
@@ -538,7 +541,7 @@  int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	memset(real_cmdline, 0, sizeof(real_cmdline));
 	strcpy(real_cmdline, "notsc noapic noacpi pci=conf1");
-	if (vnc) {
+	if (vnc || sdl) {
 		strcat(real_cmdline, " video=vesafb console=tty0");
 		vidmode = 0x312;
 	} else {
@@ -630,13 +633,19 @@  int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	kvm__init_ram(kvm);
 
+	if (vnc || sdl)
+		fb = vesa__init(kvm);
+
 	if (vnc) {
 		kbd__init(kvm);
-		fb = vesa__init(kvm);
+		if (fb)
+			vnc__init(fb);
 	}
 
-	if (fb)
-		vnc__init(fb);
+	if (sdl) {
+		if (fb)
+			sdl__init(fb);
+	}
 
 	fb__start();
 
diff --git a/tools/kvm/ui/sdl.c b/tools/kvm/ui/sdl.c
new file mode 100644
index 0000000..8bc3f68
--- /dev/null
+++ b/tools/kvm/ui/sdl.c
@@ -0,0 +1,71 @@ 
+#include "kvm/sdl.h"
+
+#include "kvm/framebuffer.h"
+#include "kvm/util.h"
+
+#include <SDL/SDL.h>
+#include <pthread.h>
+
+static void sdl__write(struct framebuffer *fb, u64 addr, u8 *data, u32 len)
+{
+	memcpy(&fb->mem[addr - fb->mem_addr], data, len);
+}
+
+static void *sdl__thread(void *p)
+{
+	Uint32 rmask, gmask, bmask, amask;
+	struct framebuffer *fb = p;
+	SDL_Surface *guest_screen;
+	SDL_Surface *screen;
+	SDL_Event ev;
+
+	if (SDL_Init(SDL_INIT_VIDEO) != 0)
+		die("Unable to initialize SDL");
+
+	rmask = 0x000000ff;
+	gmask = 0x0000ff00;
+	bmask = 0x00ff0000;
+	amask = 0x00000000;
+
+	guest_screen = SDL_CreateRGBSurfaceFrom(fb->mem, fb->width, fb->height, fb->depth, fb->width * fb->depth / 8, rmask, gmask, bmask, amask);
+	if (!guest_screen)
+		die("Unable to create SDL RBG surface");
+
+	screen = SDL_SetVideoMode(fb->width, fb->height, fb->depth, SDL_SWSURFACE);
+	if (!screen)
+		die("Unable to set SDL video mode");
+
+	for (;;) {
+		SDL_BlitSurface(guest_screen, NULL, screen, NULL);
+		SDL_Flip(screen);
+
+		while (SDL_PollEvent(&ev)) {
+			switch (ev.type) {
+			case SDL_QUIT:
+				goto exit;
+			}
+		}
+	}
+exit:
+	return NULL;
+}
+
+static int sdl__start(struct framebuffer *fb)
+{
+	pthread_t thread;
+
+	if (pthread_create(&thread, NULL, sdl__thread, fb) != 0)
+		return -1;
+
+	return 0;
+}
+
+static struct fb_target_operations sdl_ops = {
+	.start			= sdl__start,
+	.write			= sdl__write,
+};
+
+void sdl__init(struct framebuffer *fb)
+{
+	fb__attach(fb, &sdl_ops);
+}