public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* x11-fb driver
@ 2006-03-31 17:14 Robert Schwebel
  2006-03-31 17:16 ` Robert Schwebel
  2006-04-03  7:00 ` Gerd Hoffmann
  0 siblings, 2 replies; 3+ messages in thread
From: Robert Schwebel @ 2006-03-31 17:14 UTC (permalink / raw)
  To: Jeff Dike, Gerd Knorr; +Cc: linux-kernel

Hi, 

here's an updated patch of Gerd Knorr's x11-fb patch, taken from here: 
http://user-mode-linux.sourceforge.net/work/current/2.6/2.6.16/patches/x11-fb

It compiles on 2.6.16 and works at least a little bit. I get some
initial output, see the screenshot here:

http://www.pengutronix.de/uml-x11.gif

However, the window is never redrawn and I didn't manage to make input
working, but it may be a start for others. It was a little bit messy to
find the right kconfig switches which had to be enabled, because the
uml's kconfig structure is very different from the mainstream one. 

Gerd, are you still actively working on this driver?

Robert
-- 
 Dipl.-Ing. Robert Schwebel | http://www.pengutronix.de
 Pengutronix - Linux Solutions for Science and Industry
   Handelsregister:  Amtsgericht Hildesheim, HRA 2686
     Hannoversche Str. 2, 31134 Hildesheim, Germany
   Phone: +49-5121-206917-0 |  Fax: +49-5121-206917-9


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: x11-fb driver
  2006-03-31 17:14 x11-fb driver Robert Schwebel
@ 2006-03-31 17:16 ` Robert Schwebel
  2006-04-03  7:00 ` Gerd Hoffmann
  1 sibling, 0 replies; 3+ messages in thread
From: Robert Schwebel @ 2006-03-31 17:16 UTC (permalink / raw)
  To: Jeff Dike, Gerd Knorr; +Cc: linux-kernel

On Fri, Mar 31, 2006 at 07:14:18PM +0200, Robert Schwebel wrote:
> here's an updated patch [...]

# X11 framebuffer driver from Gerd Knorr.
# You have to enable CONFIG_FB (UML-specific options/Graphics support/
# Support for frabe buffer devices), disable CONFIG_VGA_CONSOLE
# (UML-specific options/Graphics support/Console display driver support/
# VGA text console), and enable Framebuffer Console support (in the same 
# place), plus some fonts.  You also seem to have to put
# 'x11=<width>x<height>
# on the command line.
#
# Ported to 2.6.16 by Robert Schwebel.
#
diff -urN linux-2.6.16/arch/um/defconfig linux-2.6.16-x11-uml/arch/um/defconfig
--- linux-2.6.16/arch/um/defconfig	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-x11-uml/arch/um/defconfig	2006-03-31 17:48:27.000000000 +0200
@@ -33,6 +33,56 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_LD_SCRIPT_DYN=y
 CONFIG_NET=y
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
 # CONFIG_HOSTFS is not set
@@ -437,7 +487,6 @@
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
-# CONFIG_INPUT is not set
 
 #
 # Kernel hacking
diff -urN linux-2.6.16/arch/um/drivers/Makefile linux-2.6.16-x11-uml/arch/um/drivers/Makefile
--- linux-2.6.16/arch/um/drivers/Makefile	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-x11-uml/arch/um/drivers/Makefile	2006-03-31 17:48:27.000000000 +0200
@@ -1,4 +1,4 @@
-# 
+#
 # Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
 # Licensed under the GPL
 #
@@ -16,6 +16,10 @@
 ubd-objs := ubd_kern.o ubd_user.o
 port-objs := port_kern.o port_user.o
 harddog-objs := harddog_kern.o harddog_user.o
+x11-objs := x11_kern.o x11_user.o \
+	../../../drivers/video/cfbfillrect.o \
+	../../../drivers/video/cfbcopyarea.o \
+	../../../drivers/video/cfbimgblt.o
 
 LDFLAGS_pcap.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libpcap.a)
 
@@ -36,18 +40,19 @@
 
 obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o
 obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
-obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 
-obj-$(CONFIG_UML_NET_MCAST) += mcast.o 
+obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
+obj-$(CONFIG_UML_NET_MCAST) += mcast.o
 obj-$(CONFIG_UML_NET_PCAP) += pcap.o
-obj-$(CONFIG_UML_NET) += net.o 
+obj-$(CONFIG_UML_NET) += net.o
 obj-$(CONFIG_MCONSOLE) += mconsole.o
-obj-$(CONFIG_MMAPPER) += mmapper_kern.o 
-obj-$(CONFIG_BLK_DEV_UBD) += ubd.o 
+obj-$(CONFIG_MMAPPER) += mmapper_kern.o
+obj-$(CONFIG_BLK_DEV_UBD) += ubd.o
 obj-$(CONFIG_HOSTAUDIO) += hostaudio.o
-obj-$(CONFIG_NULL_CHAN) += null.o 
+obj-$(CONFIG_NULL_CHAN) += null.o
 obj-$(CONFIG_PORT_CHAN) += port.o
 obj-$(CONFIG_PTY_CHAN) += pty.o
-obj-$(CONFIG_TTY_CHAN) += tty.o 
+obj-$(CONFIG_TTY_CHAN) += tty.o
+obj-$(CONFIG_X11_FB) += x11.o
 obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
 obj-$(CONFIG_UML_WATCHDOG) += harddog.o
 obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
diff -urN linux-2.6.16/arch/um/drivers/x11_kern.c linux-2.6.16-x11-uml/arch/um/drivers/x11_kern.c
--- linux-2.6.16/arch/um/drivers/x11_kern.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.16-x11-uml/arch/um/drivers/x11_kern.c	2006-03-31 18:12:31.000000000 +0200
@@ -0,0 +1,530 @@
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/input.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/console.h>
+#include <linux/pagemap.h>
+#include <linux/mm.h>
+
+#include "irq_kern.h"
+#include "irq_user.h"
+#include "x11_kern.h"
+#include "x11_user.h"
+
+/* ---------------------------------------------------------------------------- */
+
+extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
+
+static int x11_enable  = 0;
+static int x11_fps     = 5;
+static int x11_width;
+static int x11_height;
+
+struct x11_kerndata {
+	/* common stuff */
+	struct x11_window         *win;
+	struct task_struct        *kthread;
+	wait_queue_head_t         wq;
+	int                       has_data;
+
+	/* framebuffer driver */
+	struct fb_fix_screeninfo  *fix;
+	struct fb_var_screeninfo  *var;
+	struct fb_info            *info;
+	struct timer_list         refresh;
+	int                       dirty, x1, x2, y1, y2;
+
+	/* fb mapping */
+	struct semaphore          mm_lock;
+	struct vm_area_struct     *vma;
+	atomic_t                  map_refs;
+	int                       faults;
+	int                       nr_pages;
+	struct page               **pages;
+	int                       *mapped;
+
+	/* input drivers */
+	struct input_dev          kbd;
+	struct input_dev          mouse;
+};
+
+void x11_mmap_update(struct x11_kerndata *kd)
+{
+	int i, off, len;
+	char *src;
+
+	zap_page_range(kd->vma, kd->vma->vm_start,
+		       kd->vma->vm_end - kd->vma->vm_start, NULL);
+	kd->faults = 0;
+	for (i = 0; i < kd->nr_pages; i++) {
+		if (NULL == kd->pages[i])
+			continue;
+		if (0 == kd->mapped[i])
+			continue;
+		kd->mapped[i] = 0;
+		off = i << PAGE_SHIFT;
+		len = PAGE_SIZE;
+		if (len > kd->fix->smem_len - off)
+			len = kd->fix->smem_len - off;
+		src = kmap(kd->pages[i]);
+		memcpy(kd->info->screen_base + off, src, len);
+		kunmap(kd->pages[i]);
+	}
+}
+
+static int x11_thread(void *data)
+{
+	struct x11_kerndata *kd = data;
+	DECLARE_WAITQUEUE(wait,current);
+
+	add_wait_queue(&kd->wq, &wait);
+	for (;;) {
+		if (kthread_should_stop())
+			break;
+		if (kd->dirty) {
+			int x1 = kd->x1;
+			int x2 = kd->x2;
+			int y1 = kd->y1;
+			int y2 = kd->y2;
+			down(&kd->mm_lock);
+			if (kd->faults > 0)
+				x11_mmap_update(kd);
+			up(&kd->mm_lock);
+			kd->dirty = kd->x1 = kd->x2 = kd->y1 = kd->y2 = 0;
+			x11_blit_fb(kd->win, x1, y1, x2, y2);
+		}
+		if (kd->has_data) {
+			kd->has_data = 0;
+			x11_has_data(kd->win,kd);
+			reactivate_fd(x11_get_fd(kd->win), X11_IRQ);
+		}
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule();
+	}
+	remove_wait_queue(&kd->wq, &wait);
+	return 0;
+}
+
+/* ---------------------------------------------------------------------------- */
+/* input driver                                                                 */
+
+void x11_kbd_input(struct x11_kerndata *kd, int key, int down)
+{
+	if (key >= KEY_MAX) {
+		if (down)
+			printk("%s: unknown key pressed [%d]\n",
+			       __FUNCTION__, key-KEY_MAX);
+		return;
+	}
+	input_report_key(&kd->kbd,key,down);
+	input_sync(&kd->kbd);
+}
+
+void x11_mouse_input(struct x11_kerndata *kd, int key, int down,
+		     int x, int y)
+{
+	if (key != KEY_RESERVED)
+		input_report_key(&kd->mouse, key, down);
+	input_report_abs(&kd->mouse, ABS_X, x);
+	input_report_abs(&kd->mouse, ABS_Y, y);
+	input_sync(&kd->mouse);
+}
+
+void x11_cad(struct x11_kerndata *kd)
+{
+	printk("%s\n",__FUNCTION__);
+}
+
+/* ---------------------------------------------------------------------------- */
+/* framebuffer driver                                                           */
+
+static int x11_setcolreg(unsigned regno, unsigned red, unsigned green,
+			 unsigned blue, unsigned transp,
+			 struct fb_info *info)
+{
+	if (regno >= info->cmap.len)
+		return 1;
+
+	switch (info->var.bits_per_pixel) {
+	case 16:
+		if (info->var.red.offset == 10) {
+			/* 1:5:5:5 */
+			((u32*) (info->pseudo_palette))[regno] =
+				((red   & 0xf800) >>  1) |
+				((green & 0xf800) >>  6) |
+				((blue  & 0xf800) >> 11);
+		} else {
+			/* 0:5:6:5 */
+			((u32*) (info->pseudo_palette))[regno] =
+				((red   & 0xf800)      ) |
+				((green & 0xfc00) >>  5) |
+				((blue  & 0xf800) >> 11);
+		}
+		break;
+	case 24:
+		red   >>= 8;
+		green >>= 8;
+		blue  >>= 8;
+		((u32 *)(info->pseudo_palette))[regno] =
+			(red   << info->var.red.offset)   |
+			(green << info->var.green.offset) |
+			(blue  << info->var.blue.offset);
+		break;
+	case 32:
+		red   >>= 8;
+		green >>= 8;
+		blue  >>= 8;
+		((u32 *)(info->pseudo_palette))[regno] =
+			(red   << info->var.red.offset)   |
+			(green << info->var.green.offset) |
+			(blue  << info->var.blue.offset);
+		break;
+	}
+	return 0;
+}
+
+static void x11_fb_timer(unsigned long data)
+{
+	struct x11_kerndata *kd = (struct x11_kerndata*)data;
+	kd->dirty++;
+	wake_up(&kd->wq);
+}
+
+static void x11_fb_refresh(struct x11_kerndata *kd,
+			   int x1, int y1, int w, int h)
+{
+	int x2, y2;
+
+	x2 = x1 + w;
+	y2 = y1 + h;
+	if (0 == kd->x2 || 0 == kd->y2) {
+		kd->x1 = x1;
+		kd->x2 = x2;
+		kd->y1 = y1;
+		kd->y2 = y2;
+	}
+	if (kd->x1 > x1)
+		kd->x1 = x1;
+	if (kd->x2 < x2)
+		kd->x2 = x2;
+	if (kd->y1 > y1)
+		kd->y1 = y1;
+	if (kd->y2 < y2)
+		kd->y2 = y2;
+
+	if (timer_pending(&kd->refresh))
+		return;
+	mod_timer(&kd->refresh, jiffies + HZ/x11_fps);
+}
+
+void x11_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
+{
+	struct x11_kerndata *kd = p->par;
+
+	cfb_fillrect(p, rect);
+	x11_fb_refresh(kd, rect->dx, rect->dy, rect->width, rect->height);
+}
+
+void x11_imageblit(struct fb_info *p, const struct fb_image *image)
+{
+	struct x11_kerndata *kd = p->par;
+
+	cfb_imageblit(p, image);
+	x11_fb_refresh(kd, image->dx, image->dy, image->width, image->height);
+}
+
+void x11_copyarea(struct fb_info *p, const struct fb_copyarea *area)
+{
+	struct x11_kerndata *kd = p->par;
+
+	cfb_copyarea(p, area);
+	x11_fb_refresh(kd, area->dx, area->dy, area->width, area->height);
+}
+
+/* ---------------------------------------------------------------------------- */
+
+static void
+x11_fb_vm_open(struct vm_area_struct *vma)
+{
+	struct x11_kerndata *kd = vma->vm_private_data;
+
+	atomic_inc(&kd->map_refs);
+}
+
+static void
+x11_fb_vm_close(struct vm_area_struct *vma)
+{
+	struct x11_kerndata *kd = vma->vm_private_data;
+	int i;
+
+	if (!atomic_dec_and_test(&kd->map_refs))
+		return;
+	down(&kd->mm_lock);
+	for (i = 0; i < kd->nr_pages; i++) {
+		if (NULL == kd->pages[i])
+			continue;
+		put_page(kd->pages[i]);
+	}
+	kfree(kd->pages);
+	kfree(kd->mapped);
+	kd->pages    = NULL;
+	kd->mapped   = NULL;
+	kd->vma      = NULL;
+	kd->nr_pages = 0;
+	kd->faults   = 0;
+	up(&kd->mm_lock);
+}
+
+static struct page*
+x11_fb_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr,
+		 int *type)
+{
+	struct x11_kerndata *kd = vma->vm_private_data;
+	int pgnr = (vaddr - vma->vm_start) >> PAGE_SHIFT;
+	int y1,y2;
+
+	if (pgnr >= kd->nr_pages)
+		return NOPAGE_SIGBUS;
+
+	down(&kd->mm_lock);
+	if (NULL == kd->pages[pgnr]) {
+		struct page *page;
+		page = alloc_page_vma(GFP_HIGHUSER, vma, vaddr);
+		if (!page)
+			return NOPAGE_OOM;
+		clear_user_highpage(page, vaddr);
+		kd->pages[pgnr] = page;
+	}
+	get_page(kd->pages[pgnr]);
+	kd->mapped[pgnr] = 1;
+	kd->faults++;
+	up(&kd->mm_lock);
+
+	y1 = pgnr * PAGE_SIZE / kd->fix->line_length;
+	y2 = (pgnr * PAGE_SIZE + PAGE_SIZE-1) / kd->fix->line_length;
+	if (y2 > kd->var->yres)
+		y2 = kd->var->yres;
+	x11_fb_refresh(kd, 0, y1, kd->var->xres, y2 - y1);
+
+	if (type)
+		*type = VM_FAULT_MINOR;
+	return kd->pages[pgnr];
+}
+
+static struct vm_operations_struct x11_fb_vm_ops =
+{
+	.open     = x11_fb_vm_open,
+	.close    = x11_fb_vm_close,
+	.nopage   = x11_fb_vm_nopage,
+};
+
+int x11_mmap(struct fb_info *p, struct file *file,
+	     struct vm_area_struct * vma)
+{
+	struct x11_kerndata *kd = p->par;
+	int retval;
+	int fb_pages;
+	int map_pages;
+
+	down(&kd->mm_lock);
+
+	retval = -EBUSY;
+	if (kd->vma) {
+		printk("%s: busy, mapping exists\n",__FUNCTION__);
+		goto out;
+	}
+
+	retval = -EINVAL;
+	if (!(vma->vm_flags & VM_WRITE)) {
+		printk("%s: need writable mapping\n",__FUNCTION__);
+		goto out;
+	}
+	if (!(vma->vm_flags & VM_SHARED)) {
+		printk("%s: need shared mapping\n",__FUNCTION__);
+		goto out;
+	}
+	if (vma->vm_pgoff != 0) {
+		printk("%s: need offset 0 (vm_pgoff=%ld)\n",__FUNCTION__,
+		       vma->vm_pgoff);
+		goto out;
+	}
+
+	fb_pages  = (p->fix.smem_len             + PAGE_SIZE-1) >> PAGE_SHIFT;
+	map_pages = (vma->vm_end - vma->vm_start + PAGE_SIZE-1) >> PAGE_SHIFT;
+	if (map_pages > fb_pages) {
+		printk("%s: mapping to big (%ld > %d)\n",__FUNCTION__,
+		       vma->vm_end - vma->vm_start, p->fix.smem_len);
+		goto out;
+	}
+
+	retval = -ENOMEM;
+	kd->pages = kmalloc(sizeof(struct page*)*map_pages, GFP_KERNEL);
+	if (NULL == kd->pages)
+		goto out;
+	kd->mapped = kmalloc(sizeof(int)*map_pages, GFP_KERNEL);
+	if (NULL == kd->mapped) {
+		kfree(kd->pages);
+		goto out;
+	}
+	memset(kd->pages,  0, sizeof(struct page*) * map_pages);
+	memset(kd->mapped, 0, sizeof(int)          * map_pages);
+	kd->vma = vma;
+	kd->nr_pages = map_pages;
+	atomic_set(&kd->map_refs,1);
+	kd->faults = 0;
+
+	vma->vm_ops   = &x11_fb_vm_ops;
+	vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
+	vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
+	vma->vm_private_data = kd;
+	retval = 0;
+
+out:
+	up(&kd->mm_lock);
+	return retval;
+}
+
+/* ---------------------------------------------------------------------------- */
+
+static struct fb_ops x11_fb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_setcolreg	= x11_setcolreg,
+	.fb_fillrect	= x11_fillrect,
+	.fb_copyarea	= x11_copyarea,
+	.fb_imageblit	= x11_imageblit,
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE
+	.fb_cursor	= soft_cursor,
+#endif	
+	.fb_mmap        = x11_mmap,
+};
+
+/* ---------------------------------------------------------------------------- */
+
+static irqreturn_t x11_irq(int irq, void *data, struct pt_regs *unused)
+{
+	struct x11_kerndata *kd = data;
+
+	kd->has_data++;
+	wake_up(&kd->wq);
+	return IRQ_HANDLED;
+}
+
+static int x11_probe(void)
+{
+	struct x11_kerndata *kd;
+	int i;
+
+	if (!x11_enable)
+		return -ENODEV;
+
+	kd = kmalloc(sizeof(*kd),GFP_KERNEL);
+	if (NULL == kd)
+		return -ENOMEM;
+	memset(kd,0,sizeof(*kd));
+
+	kd->win = x11_open(x11_width, x11_height);
+	if (NULL == kd->win) {
+		printk("fb: can't open X11 window\n");
+		goto fail_free;
+	}
+	kd->fix = x11_get_fix(kd->win);
+	kd->var = x11_get_var(kd->win);
+
+	/* framebuffer setup */
+	kd->info = framebuffer_alloc(sizeof(u32) * 256, NULL);
+	kd->info->pseudo_palette = kd->info->par;
+	kd->info->par = kd;
+	kd->info->screen_base = x11_get_fbmem(kd->win);
+
+	kd->info->fbops = &x11_fb_ops;
+	kd->info->var = *kd->var;
+	kd->info->fix = *kd->fix;
+	kd->info->flags = FBINFO_FLAG_DEFAULT;
+
+	fb_alloc_cmap(&kd->info->cmap, 256, 0);
+	register_framebuffer(kd->info);
+	printk(KERN_INFO "fb%d: %s frame buffer device, %dx%d, %d fps, %d bpp (%d:%d:%d)\n",
+	       kd->info->node, kd->info->fix.id,
+	       kd->var->xres, kd->var->yres, x11_fps, kd->var->bits_per_pixel,
+	       kd->var->red.length, kd->var->green.length, kd->var->blue.length);
+
+	/* keyboard setup */
+	init_input_dev(&kd->kbd);
+	set_bit(EV_KEY, kd->kbd.evbit);
+	for (i = 0; i < KEY_MAX; i++)
+		set_bit(i, kd->kbd.keybit);
+	kd->kbd.id.bustype = BUS_HOST;
+	kd->kbd.name = "virtual keyboard";
+	kd->kbd.phys = "x11/input0";
+	input_register_device(&kd->kbd);
+
+	/* mouse setup */
+	init_input_dev(&kd->mouse);
+	set_bit(EV_ABS,     kd->mouse.evbit);
+	set_bit(EV_KEY,     kd->mouse.evbit);
+	set_bit(BTN_TOUCH,  kd->mouse.keybit);
+	set_bit(BTN_LEFT,   kd->mouse.keybit);
+	set_bit(BTN_MIDDLE, kd->mouse.keybit);
+	set_bit(BTN_RIGHT,  kd->mouse.keybit);
+	set_bit(ABS_X,      kd->mouse.absbit);
+	set_bit(ABS_Y,      kd->mouse.absbit);
+	kd->mouse.absmin[ABS_X] = 0;
+	kd->mouse.absmax[ABS_X] = kd->var->xres;
+	kd->mouse.absmin[ABS_Y] = 0;
+	kd->mouse.absmax[ABS_Y] = kd->var->yres;
+	kd->mouse.id.bustype = BUS_HOST;
+	kd->mouse.name = "virtual mouse";
+	kd->mouse.phys = "x11/input1";
+	input_register_device(&kd->mouse);
+
+	/* misc common kernel stuff */
+	init_MUTEX(&kd->mm_lock);
+	init_waitqueue_head(&kd->wq);
+	init_timer(&kd->refresh);
+	kd->refresh.function = x11_fb_timer;
+	kd->refresh.data     = (unsigned long)kd;
+
+	kd->kthread = kthread_run(x11_thread, kd, "x11 thread");
+	um_request_irq(X11_IRQ, x11_get_fd(kd->win), IRQ_READ, x11_irq,
+		       SA_INTERRUPT | SA_SHIRQ, "x11", kd);
+
+	return 0;
+
+fail_free:
+	kfree(kd);
+	return -ENODEV;
+}
+
+static int __init x11_init(void)
+{
+	return x11_probe();
+}
+
+static void __exit x11_fini(void)
+{
+	/* FIXME */
+}
+
+module_init(x11_init);
+module_exit(x11_fini);
+
+static int x11_setup(char *str)
+{
+	if (3 == sscanf(str,"%dx%d@%d",&x11_width,&x11_height,&x11_fps) ||
+	    2 == sscanf(str,"%dx%d",&x11_width,&x11_height)) {
+		x11_enable = 1;
+		return 0;
+	}
+	return -1;
+}
+__setup("x11=", x11_setup);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -urN linux-2.6.16/arch/um/drivers/x11_user.c linux-2.6.16-x11-uml/arch/um/drivers/x11_user.c
--- linux-2.6.16/arch/um/drivers/x11_user.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.16-x11-uml/arch/um/drivers/x11_user.c	2006-03-31 17:48:27.000000000 +0200
@@ -0,0 +1,445 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include <linux/fb.h>
+#include <linux/input.h>
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <X11/extensions/XShm.h>
+
+#include "x11_kern.h"
+#include "x11_user.h"
+
+/* --------------------------------------------------------------------------- */
+
+struct x11_window {
+	/* misc x11 stuff */
+	Display                   *dpy;
+	Window                    root, win;
+	GC                        gc;
+	XVisualInfo               vi;
+	Atom                      delete_window;
+
+	/* framebuffer -- x11 */
+	XImage                    *ximage;
+	unsigned char             *xidata;
+	XShmSegmentInfo           shminfo;
+
+	/* framebuffer -- kernel */
+	struct fb_fix_screeninfo  fix;
+	struct fb_var_screeninfo  var;
+};
+
+/* --------------------------------------------------------------------------- */
+
+/*
+ * map X11 keycodes to linux keycodes
+ *
+ * WARNING: X11 keycodes are not portable, this likely breaks as soon
+ * as one uses a X-Server not running on a linux machine as display.
+ *
+ * Using portable keysyms instead creates some strange and hard to
+ * handle keymapping effects through.  That happens because both host
+ * and uml machine are mapping keys then ...
+ */
+static int x11_keymap[] = {
+	[   9 ] = KEY_ESC,
+	[  10 ] = KEY_1,
+	[  11 ] = KEY_2,
+	[  12 ] = KEY_3,
+	[  13 ] = KEY_4,
+	[  14 ] = KEY_5,
+	[  15 ] = KEY_6,
+	[  16 ] = KEY_7,
+	[  17 ] = KEY_8,
+	[  18 ] = KEY_9,
+	[  19 ] = KEY_0,
+	[  20 ] = KEY_MINUS,
+	[  21 ] = KEY_EQUAL,
+	[  22 ] = KEY_BACKSPACE,
+
+	[  23 ] = KEY_TAB,
+	[  24 ] = KEY_Q,
+	[  25 ] = KEY_W,
+	[  26 ] = KEY_E,
+	[  27 ] = KEY_R,
+	[  28 ] = KEY_T,
+	[  29 ] = KEY_Y,
+	[  30 ] = KEY_U,
+	[  31 ] = KEY_I,
+	[  32 ] = KEY_O,
+	[  33 ] = KEY_P,
+	[  34 ] = KEY_LEFTBRACE,
+	[  35 ] = KEY_RIGHTBRACE,
+	[  36 ] = KEY_ENTER,
+
+	[  37 ] = KEY_LEFTCTRL,
+	[  38 ] = KEY_A,
+	[  39 ] = KEY_S,
+	[  40 ] = KEY_D,
+	[  41 ] = KEY_F,
+	[  42 ] = KEY_G,
+	[  43 ] = KEY_H,
+	[  44 ] = KEY_J,
+	[  45 ] = KEY_K,
+	[  46 ] = KEY_L,
+	[  47 ] = KEY_SEMICOLON,
+	[  48 ] = KEY_APOSTROPHE,
+	[  49 ] = KEY_GRAVE,
+
+	[  50 ] = KEY_LEFTSHIFT,
+	[  51 ] = KEY_BACKSLASH,
+	[  52 ] = KEY_Z,
+	[  53 ] = KEY_X,
+	[  54 ] = KEY_C,
+	[  55 ] = KEY_V,
+	[  56 ] = KEY_B,
+	[  57 ] = KEY_N,
+	[  58 ] = KEY_M,
+	[  59 ] = KEY_COMMA,
+	[  60 ] = KEY_DOT,
+	[  61 ] = KEY_SLASH,
+	[  62 ] = KEY_RIGHTSHIFT,
+
+	[  63 ] = KEY_KPASTERISK,
+	[  64 ] = KEY_LEFTALT,
+	[  65 ] = KEY_SPACE,
+	[  66 ] = KEY_CAPSLOCK,
+
+	[  67 ] = KEY_F1,
+	[  68 ] = KEY_F2,
+	[  69 ] = KEY_F3,
+	[  70 ] = KEY_F4,
+	[  71 ] = KEY_F5,
+	[  72 ] = KEY_F6,
+	[  73 ] = KEY_F7,
+	[  74 ] = KEY_F8,
+	[  75 ] = KEY_F9,
+	[  76 ] = KEY_F10,
+	[  77 ] = KEY_NUMLOCK,
+	[  78 ] = KEY_SCROLLLOCK,
+
+	[  79 ] = KEY_KP7,
+	[  80 ] = KEY_KP8,
+	[  81 ] = KEY_KP9,
+	[  82 ] = KEY_KPMINUS,
+	[  83 ] = KEY_KP4,
+	[  84 ] = KEY_KP5,
+	[  85 ] = KEY_KP6,
+	[  86 ] = KEY_KPPLUS,
+	[  87 ] = KEY_KP1,
+	[  88 ] = KEY_KP2,
+	[  89 ] = KEY_KP3,
+	[  90 ] = KEY_KP0,
+	[  91 ] = KEY_KPDOT,
+
+	// [  92 ] = KEY_Print,
+	// [  93 ] = KEY_Mode_switch,
+	[  94 ] = KEY_102ND,
+
+	[  95 ] = KEY_F11,
+	[  96 ] = KEY_F12,
+	[  97 ] = KEY_HOME,
+	[  98 ] = KEY_UP,
+	[  99 ] = KEY_PAGEUP,
+	[ 100 ] = KEY_LEFT,
+	[ 102 ] = KEY_RIGHT,
+	[ 103 ] = KEY_END,
+	[ 104 ] = KEY_DOWN,
+	[ 105 ] = KEY_PAGEDOWN,
+	[ 106 ] = KEY_INSERT,
+	[ 107 ] = KEY_DELETE,
+
+	// [ 108 ] = KEY_KP_Enter,
+	[ 109 ] = KEY_RIGHTCTRL,
+	// [ 110 ] = KEY_Pause,
+	// [ 111 ] = KEY_Print,
+	// [ 112 ] = KEY_KP_Divide,
+	[ 113 ] = KEY_RIGHTALT,
+	// [ 114 ] = KEY_Pause,
+	// [ 115 ] = KEY_Super_L,
+	// [ 116 ] = KEY_Super_R,
+	[ 117 ] = KEY_MENU,
+	// [ 124 ] = KEY_ISO_Level3_Shift,
+	// [ 126 ] = KEY_KP_Equal,
+};
+
+static void x11_kbd(struct x11_window *win, struct x11_kerndata *kd, XEvent *e)
+{
+	int key = KEY_RESERVED;
+
+	if (e->xkey.keycode < sizeof(x11_keymap)/sizeof(x11_keymap[0]))
+		key = x11_keymap[e->xkey.keycode];
+
+	if (KEY_RESERVED != key) {
+		x11_kbd_input(kd, key, e->type == KeyPress);
+	} else {
+		x11_kbd_input(kd, KEY_MAX + e->xkey.keycode, e->type == KeyPress);
+	}
+}
+
+static int x11_mousemap[] = {
+	[ Button1 ] = BTN_LEFT,    /* BTN_TOUCH ??? */
+	[ Button2 ] = BTN_MIDDLE,
+	[ Button3 ] = BTN_RIGHT,
+	[ Button4 ] = BTN_FORWARD, /* is this the wheel ??? */
+	[ Button5 ] = BTN_BACK,    /* is this the wheel ??? */
+};
+
+static void x11_mouse(struct x11_window *win, struct x11_kerndata *kd,
+		      XEvent *e)
+{
+	int key = KEY_RESERVED;
+
+	if (e->xbutton.button < sizeof(x11_mousemap)/sizeof(x11_mousemap[0]))
+		key = x11_mousemap[e->xbutton.button];
+	x11_mouse_input(kd, key, e->type == ButtonPress,
+			e->xbutton.x, e->xbutton.y);
+}
+
+/* --------------------------------------------------------------------------- */
+
+static int mitshm_err;
+
+static int
+catch_no_mitshm(Display * dpy, XErrorEvent * event)
+{
+	mitshm_err++;
+	return 0;
+}
+
+static void init_color(int32_t mask, struct fb_bitfield *bf)
+{
+	int i;
+
+	memset(bf, 0, sizeof(*bf));
+	for (i = 0; i < 32; i++) {
+		if (mask & ((int32_t)1 << i))
+			bf->length++;
+		else if (!bf->length)
+			bf->offset++;
+	}
+}
+
+struct x11_window *x11_open(int width, int height)
+{
+	char *title = "user mode linux framebuffer";
+	struct x11_window *win;
+	XSizeHints hints;
+	XTextProperty prop;
+	XVisualInfo *info, template;
+	void *old_handler;
+	int n,bytes_pp;
+
+	win = malloc(sizeof(*win));
+	if (NULL == win)
+		goto fail;
+
+	win->dpy = XOpenDisplay(NULL);
+	if (NULL == win->dpy)
+		goto fail_free;
+
+	/* get visual info */
+	template.screen = XDefaultScreen(win->dpy);
+	template.depth  = DefaultDepth(win->dpy, DefaultScreen(win->dpy));
+	info = XGetVisualInfo(win->dpy, VisualScreenMask | VisualDepthMask,
+			      &template, &n);
+	if (0 == n)
+		goto fail_free;
+	win->vi = info[0];
+	XFree(info);
+	if (win->vi.class != TrueColor && win->vi.class != DirectColor)
+		goto fail_free;
+
+	/* create pixmap */
+	mitshm_err  = 0;
+	old_handler = XSetErrorHandler(catch_no_mitshm);
+	win->ximage = XShmCreateImage(win->dpy,win->vi.visual,win->vi.depth,
+				      ZPixmap, NULL, &win->shminfo,
+				      width, height);
+	if (NULL == win->ximage)
+		goto shm_error;
+	bytes_pp = win->ximage->bits_per_pixel/8;
+	win->shminfo.shmid = shmget(IPC_PRIVATE,
+				    win->ximage->bytes_per_line * win->ximage->height,
+				    IPC_CREAT | 0777);
+	if (-1 == win->shminfo.shmid)
+		goto shm_error;
+	win->shminfo.shmaddr = (char *) shmat(win->shminfo.shmid, 0, 0);
+	if ((void *)-1 == win->shminfo.shmaddr)
+		goto shm_error;
+
+	win->ximage->data = win->shminfo.shmaddr;
+	win->shminfo.readOnly = False;
+	XShmAttach(win->dpy, &win->shminfo);
+	XSync(win->dpy, False);
+	if (mitshm_err)
+		goto shm_error;
+	shmctl(win->shminfo.shmid, IPC_RMID, 0);
+	XSetErrorHandler(old_handler);
+	goto have_ximage;
+
+shm_error:
+	/* can't use shared memory -- cleanup and try without */
+	if (win->ximage) {
+		XDestroyImage(win->ximage);
+		win->ximage = NULL;
+	}
+	if ((void *)-1 != win->shminfo.shmaddr  &&  NULL != win->shminfo.shmaddr)
+		shmdt(win->shminfo.shmaddr);
+	XSetErrorHandler(old_handler);
+
+	memset(&win->shminfo,0,sizeof(win->shminfo));
+	if (NULL == (win->xidata = malloc(width * height *
+					  (win->vi.depth > 16) ? 4 : 2)))
+		goto fail_free;
+
+	win->ximage = XCreateImage(win->dpy, win->vi.visual, win->vi.depth,
+				   ZPixmap, 0,  win->xidata,
+				   width, height, 8, 0);
+	bytes_pp = win->ximage->bits_per_pixel/8;
+
+have_ximage:
+	/* fill structs */
+	win->var.xres           = width;
+	win->var.xres_virtual   = width;
+	win->var.yres           = height;
+	win->var.yres_virtual   = height;
+	win->var.bits_per_pixel = bytes_pp * 8;
+	win->var.pixclock       = 10000000 / win->var.xres * 1000 / win->var.yres;
+	win->var.left_margin    = (win->var.xres / 8) & 0xf8;
+	win->var.hsync_len      = (win->var.xres / 8) & 0xf8;
+
+	init_color(win->vi.red_mask,   &win->var.red);
+	init_color(win->vi.green_mask, &win->var.green);
+	init_color(win->vi.blue_mask,  &win->var.blue);
+
+	win->var.activate       = FB_ACTIVATE_NOW;
+	win->var.height		= -1;
+	win->var.width		= -1;
+	win->var.right_margin	= 32;
+	win->var.upper_margin	= 16;
+	win->var.lower_margin	= 4;
+	win->var.vsync_len	= 4;
+	win->var.vmode		= FB_VMODE_NONINTERLACED;
+
+	win->fix.visual         = FB_VISUAL_TRUECOLOR;
+	win->fix.line_length    = win->ximage->bytes_per_line;
+	win->fix.smem_start     = 0;
+	win->fix.smem_len       = win->fix.line_length * win->var.yres;
+
+	strcpy(win->fix.id,"x11");
+	win->fix.type		= FB_TYPE_PACKED_PIXELS;
+	win->fix.accel		= FB_ACCEL_NONE;
+
+	/* create + init window */
+	hints.flags      = PMinSize | PMaxSize;
+	hints.min_width  = width;
+	hints.min_height = height;
+	hints.max_width  = width;
+	hints.max_height = height;
+	XStringListToTextProperty(&title,1,&prop);
+
+	win->root  = RootWindow(win->dpy, DefaultScreen(win->dpy));
+	win->win = XCreateSimpleWindow(win->dpy, win->root,
+				       0, 0, width, height,
+				       CopyFromParent, CopyFromParent,
+				       BlackPixel(win->dpy, DefaultScreen(win->dpy)));
+	win->gc = XCreateGC(win->dpy, win->win, 0, NULL);
+	XSelectInput(win->dpy, win->win,
+		     KeyPressMask    | KeyReleaseMask    | /* virtual keyboard */
+		     ButtonPressMask | ButtonReleaseMask | /* mouse (touchscreen?) */
+		     PointerMotionMask | ExposureMask | StructureNotifyMask |
+		     PropertyChangeMask);
+	XMapWindow(win->dpy,win->win);
+	XSetWMNormalHints(win->dpy,win->win,&hints);
+	XSetWMName(win->dpy,win->win,&prop);
+	win->delete_window = XInternAtom(win->dpy, "WM_DELETE_WINDOW", False);
+	XSetWMProtocols(win->dpy, win->win, &win->delete_window, 1);
+
+	XFlush(win->dpy);
+	return win;
+
+fail_free:
+	free(win);
+fail:
+	return NULL;
+}
+
+int x11_get_fd(struct x11_window *win)
+{
+	return ConnectionNumber(win->dpy);
+}
+
+struct fb_fix_screeninfo* x11_get_fix(struct x11_window *win)
+{
+	return &win->fix;
+}
+
+struct fb_var_screeninfo* x11_get_var(struct x11_window *win)
+{
+	return &win->var;
+}
+
+void* x11_get_fbmem(struct x11_window *win)
+{
+	return win->ximage->data;
+}
+
+int x11_blit_fb(struct x11_window *win, int x1, int y1, int x2, int y2)
+{
+	if (win->shminfo.shmid)
+		XShmPutImage(win->dpy, win->win, win->gc, win->ximage,
+			     x1,y1,x1,y1, x2-x1,y2-y1, True);
+	else
+		XPutImage(win->dpy, win->win, win->gc, win->ximage,
+			  x1,y1,x1,y1, x2-x1,y2-y1);
+	XFlush(win->dpy);
+	return 0;
+}
+
+int x11_has_data(struct x11_window *win, struct x11_kerndata *kd)
+{
+	XEvent e;
+	int count = 0;
+
+	while (True == XCheckMaskEvent(win->dpy, ~0, &e)) {
+		count++;
+		switch (e.type) {
+		case KeyPress:
+		case KeyRelease:
+			x11_kbd(win, kd, &e);
+			break;
+		case ButtonPress:
+		case ButtonRelease:
+			x11_mouse(win, kd, &e);
+			break;
+		case MotionNotify:
+			x11_mouse_input(kd, KEY_RESERVED, 0,
+			                e.xmotion.x, e.xmotion.y);
+			break;
+		case Expose:
+			if (0 == e.xexpose.count)
+				x11_blit_fb(win, 0,0, win->var.xres, win->var.yres);
+			break;
+		case ClientMessage:
+			/* hmm, don't get client messages ... */
+			if (e.xclient.data.l[0] == win->delete_window)
+				x11_cad(kd);
+			break;
+		}
+	}
+	return count;
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -urN linux-2.6.16/arch/um/include/x11_kern.h linux-2.6.16-x11-uml/arch/um/include/x11_kern.h
--- linux-2.6.16/arch/um/include/x11_kern.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.16-x11-uml/arch/um/include/x11_kern.h	2006-03-31 17:48:27.000000000 +0200
@@ -0,0 +1,9 @@
+/* x11_kern */
+
+struct x11_window;
+struct x11_kerndata;
+
+void x11_kbd_input(struct x11_kerndata *kd, int key, int down);
+void x11_mouse_input(struct x11_kerndata *kd, int key, int down,
+		     int x, int y);
+void x11_cad(struct x11_kerndata *kd);
diff -urN linux-2.6.16/arch/um/include/x11_user.h linux-2.6.16-x11-uml/arch/um/include/x11_user.h
--- linux-2.6.16/arch/um/include/x11_user.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.16-x11-uml/arch/um/include/x11_user.h	2006-03-31 17:48:27.000000000 +0200
@@ -0,0 +1,14 @@
+/* x11_user */
+
+struct x11_window;
+struct x11_kerndata;
+
+struct x11_window *x11_open(int width, int height);
+int x11_has_data(struct x11_window *win, struct x11_kerndata *kd);
+int x11_blit_fb(struct x11_window *win, int x1, int x2, int y1, int y2);
+
+int x11_get_fd(struct x11_window *win);
+struct fb_fix_screeninfo* x11_get_fix(struct x11_window *win);
+struct fb_var_screeninfo* x11_get_var(struct x11_window *win);
+void* x11_get_fbmem(struct x11_window *win);
+
diff -urN linux-2.6.16/arch/um/Kconfig linux-2.6.16-x11-uml/arch/um/Kconfig
--- linux-2.6.16/arch/um/Kconfig	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-x11-uml/arch/um/Kconfig	2006-03-31 18:25:29.000000000 +0200
@@ -117,6 +117,13 @@
 	recommended to read the NET-HOWTO, available from
 	<http://www.tldp.org/docs.html#howto>.
 
+source "drivers/input/Kconfig"
+source "drivers/char/Kconfig"
+source "drivers/video/Kconfig"
+
+config X11_FB
+	bool "X11 Framebuffer driver"
+	depends on FB && !MODE_TT && !STATIC_LINK
 
 source "fs/Kconfig.binfmt"
 
diff -urN linux-2.6.16/arch/um/kernel/um_arch.c linux-2.6.16-x11-uml/arch/um/kernel/um_arch.c
--- linux-2.6.16/arch/um/kernel/um_arch.c	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-x11-uml/arch/um/kernel/um_arch.c	2006-03-31 17:48:27.000000000 +0200
@@ -14,6 +14,7 @@
 #include "linux/bootmem.h"
 #include "linux/spinlock.h"
 #include "linux/utsname.h"
+#include "linux/console.h"
 #include "linux/sysrq.h"
 #include "linux/seq_file.h"
 #include "linux/delay.h"
@@ -58,7 +59,7 @@
 	strcat(command_line, arg);
 }
 
-struct cpuinfo_um boot_cpu_data = { 
+struct cpuinfo_um boot_cpu_data = {
 	.loops_per_jiffy	= 0,
 	.ipi_pipe		= { -1, -1 }
 };
@@ -148,20 +149,20 @@
 
 	umid = get_umid();
 	if(*umid != '\0'){
-		snprintf(argv1_begin, 
-			 (argv1_end - argv1_begin) * sizeof(*ptr), 
+		snprintf(argv1_begin,
+			 (argv1_end - argv1_begin) * sizeof(*ptr),
 			 "(%s) ", umid);
 		ptr = &argv1_begin[strlen(argv1_begin)];
 	}
 	else ptr = argv1_begin;
 
 	snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
-	memset(argv1_begin + strlen(argv1_begin), '\0', 
+	memset(argv1_begin + strlen(argv1_begin), '\0',
 	       argv1_end - argv1_begin - strlen(argv1_begin));
 #endif
 }
 
-static char *usage_string = 
+static char *usage_string =
 "User Mode Linux v%s\n"
 "	available at http://user-mode-linux.sourceforge.net/\n\n";
 
@@ -224,7 +225,7 @@
 
 __uml_setup("ncpus=", uml_ncpus_setup,
 "ncpus=<# of desired CPUs>\n"
-"    This tells an SMP kernel how many virtual processors to start.\n\n" 
+"    This tells an SMP kernel how many virtual processors to start.\n\n"
 );
 #endif
 
@@ -406,7 +407,7 @@
 	argv1_begin = argv[1];
 	argv1_end = &argv[1][strlen(argv[1])];
 #endif
-  
+
 	highmem = 0;
 	iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
 	max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
@@ -482,6 +483,9 @@
         strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
  	*cmdline_p = command_line;
 	setup_hostinfo();
+#if defined(CONFIG_DUMMY_CONSOLE)
+	conswitchp = &dummy_con;
+#endif
 }
 
 void __init check_bugs(void)
diff -urN linux-2.6.16/arch/um/Makefile linux-2.6.16-x11-uml/arch/um/Makefile
--- linux-2.6.16/arch/um/Makefile	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-x11-uml/arch/um/Makefile	2006-03-31 17:48:27.000000000 +0200
@@ -131,12 +131,17 @@
 #The wrappers will select whether using "malloc" or the kernel allocator.
 LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
 
+UML_LIBS := -lutil
+ifeq ($(CONFIG_X11_FB),y)
+UML_LIBS += -L/usr/X11R6/lib -lX11 -lXext
+endif
+
 CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS)
 define cmd_vmlinux__
 	$(CC) $(CFLAGS_vmlinux) -o $@ \
 	-Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
 	-Wl,--start-group $(vmlinux-main) -Wl,--end-group \
-	-lutil \
+	$(UML_LIBS) \
 	$(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) \
 	FORCE ,$^) ; rm -f linux
 endef
diff -urN linux-2.6.16/drivers/char/Kconfig linux-2.6.16-x11-uml/drivers/char/Kconfig
--- linux-2.6.16/drivers/char/Kconfig	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-x11-uml/drivers/char/Kconfig	2006-03-31 17:48:27.000000000 +0200
@@ -59,7 +59,7 @@
 
 config HW_CONSOLE
 	bool
-	depends on VT && !S390 && !UML
+	depends on VT && !S390
 	default y
 
 config SERIAL_NONSTANDARD
diff -urN linux-2.6.16/drivers/video/fbmem.c linux-2.6.16-x11-uml/drivers/video/fbmem.c
--- linux-2.6.16/drivers/video/fbmem.c	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-x11-uml/drivers/video/fbmem.c	2006-03-31 17:48:27.000000000 +0200
@@ -1209,9 +1209,11 @@
 #else
 #warning What do we have to do here??
 #endif
+#ifndef CONFIG_UML
 	if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
 			     vma->vm_end - vma->vm_start, vma->vm_page_prot))
 		return -EAGAIN;
+#endif
 #endif /* !__sparc_v9__ */
 	return 0;
 #endif /* !sparc32 */
diff -urN linux-2.6.16/include/asm-um/irq.h linux-2.6.16-x11-uml/include/asm-um/irq.h
--- linux-2.6.16/include/asm-um/irq.h	2006-03-20 06:53:29.000000000 +0100
+++ linux-2.6.16-x11-uml/include/asm-um/irq.h	2006-03-31 17:48:27.000000000 +0200
@@ -15,6 +15,7 @@
 #define SIGIO_WRITE_IRQ 	11
 #define TELNETD_IRQ 		12
 #define XTERM_IRQ 		13
+#define X11_IRQ			14
 
 #define LAST_IRQ XTERM_IRQ
 #define NR_IRQS (LAST_IRQ + 1)

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: x11-fb driver
  2006-03-31 17:14 x11-fb driver Robert Schwebel
  2006-03-31 17:16 ` Robert Schwebel
@ 2006-04-03  7:00 ` Gerd Hoffmann
  1 sibling, 0 replies; 3+ messages in thread
From: Gerd Hoffmann @ 2006-04-03  7:00 UTC (permalink / raw)
  To: Robert Schwebel; +Cc: Jeff Dike, Gerd Knorr, linux-kernel

> Gerd, are you still actively working on this driver?

Well, I rarely use UML these days, maybe that changes once the TLS
support bits are merged which hopefully makes it much easier to run
recent distros on UML.  Last time I tried (around 2.6.15) the driver
worked just fine for me.  Jeff had some problems to get it work on his
machine, not sure why, maybe you see the same problem, maybe the driver
must be adapted to some recent uml kernel changes ...

cheers,

  Gerd

-- 
Gerd 'just married' Hoffmann <kraxel@suse.de>
I'm the hacker formerly known as Gerd Knorr.
http://www.suse.de/~kraxel/just-married.jpeg

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2006-04-03  7:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-31 17:14 x11-fb driver Robert Schwebel
2006-03-31 17:16 ` Robert Schwebel
2006-04-03  7:00 ` Gerd Hoffmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox