2005-12-13 15:06:55

by Gerd Hoffmann

[permalink] [raw]
Subject: [patch 1/2] uml/xen: make the vt subsystem a runtime option

Subject: [patch] xen vt runtime
From: Ian Pratt <[email protected]>

This patch enables the VT console to be disabled at runtime even if it is
built into the kernel. Arch xen needs this to avoid trying to initialise a VT
in virtual machine that doesn't have access to the console hardware.

Signed-off-by: Ian Pratt <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Gerd Knorr <[email protected]>
Index: linux-2.6.14/drivers/char/tty_io.c
===================================================================
--- linux-2.6.14.orig/drivers/char/tty_io.c 2005-12-02 11:58:50.000000000 +0100
+++ linux-2.6.14/drivers/char/tty_io.c 2005-12-02 12:03:13.000000000 +0100
@@ -132,6 +132,8 @@ LIST_HEAD(tty_drivers); /* linked list
vt.c for deeply disgusting hack reasons */
DECLARE_MUTEX(tty_sem);

+int console_use_vt = 1;
+
#ifdef CONFIG_UNIX98_PTYS
extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */
extern int pty_limit; /* Config limit on Unix98 ptys */
@@ -1825,7 +1827,7 @@ retry_open:
goto got_driver;
}
#ifdef CONFIG_VT
- if (device == MKDEV(TTY_MAJOR,0)) {
+ if (console_use_vt && device == MKDEV(TTY_MAJOR,0)) {
extern struct tty_driver *console_driver;
driver = console_driver;
index = fg_console;
@@ -3014,6 +3016,8 @@ static int __init tty_init(void)
#endif

#ifdef CONFIG_VT
+ if (!console_use_vt)
+ goto out_vt;
cdev_init(&vc0_cdev, &console_fops);
if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
@@ -3022,6 +3026,7 @@ static int __init tty_init(void)
class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");

vty_init();
+ out_vt:
#endif
return 0;
}


Attachments:
xen-vt-runtime (1.71 kB)

2005-12-13 15:16:06

by Gerd Hoffmann

[permalink] [raw]
Subject: [patch 2/2] uml: Framebuffer driver for UML

Subject: [patch] uml: x11 fb
From: [email protected]

Framebuffer driver for UML

Signed-off-by: Gerd Knorr <[email protected]>
Index: linux-2.6.14/arch/um/Kconfig
===================================================================
--- linux-2.6.14.orig/arch/um/Kconfig 2005-12-12 10:37:32.000000000 +0100
+++ linux-2.6.14/arch/um/Kconfig 2005-12-12 10:38:39.000000000 +0100
@@ -121,6 +121,16 @@ config NET
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
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT

source "fs/Kconfig.binfmt"

Index: linux-2.6.14/arch/um/drivers/Makefile
===================================================================
--- linux-2.6.14.orig/arch/um/drivers/Makefile 2005-12-07 13:24:03.000000000 +0100
+++ linux-2.6.14/arch/um/drivers/Makefile 2005-12-12 10:38:39.000000000 +0100
@@ -16,6 +16,7 @@ hostaudio-objs := hostaudio_kern.o
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

LDFLAGS_pcap.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libpcap.a)

@@ -48,6 +49,7 @@ 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_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
Index: linux-2.6.14/arch/um/drivers/x11_kern.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.14/arch/um/drivers/x11_kern.c 2005-12-12 17:10:48.000000000 +0100
@@ -0,0 +1,549 @@
+#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 <linux/vmalloc.h>
+#include <linux/platform_device.h>
+
+#include "irq_kern.h"
+#include "irq_user.h"
+#include "x11_kern.h"
+#include "x11_user.h"
+
+#define DRIVER_NAME "uml-x11-fb"
+
+/* ------------------------------------------------------------------ */
+
+static int x11_enable = 0;
+static int x11_fps = 5;
+static int x11_width;
+static int x11_height;
+
+struct x11_mapping {
+ struct list_head next;
+ struct vm_area_struct *vma;
+ atomic_t map_refs;
+ int faults;
+ struct x11_kerndata *kd;
+};
+
+struct x11_kerndata {
+ /* common stuff */
+ struct x11_window *win;
+ struct task_struct *kthread;
+ wait_queue_head_t wq;
+ int has_data;
+
+ /* framebuffer driver */
+ unsigned char *fb;
+ struct fb_fix_screeninfo *fix;
+ struct fb_var_screeninfo *var;
+ struct fb_info *info;
+ struct timer_list refresh;
+ int dirty, y1, y2;
+
+ /* fb mapping */
+ struct semaphore mm_lock;
+ int nr_pages;
+ struct page **pages;
+ struct list_head mappings;
+
+ /* input drivers */
+ struct input_dev *kbd;
+ struct input_dev *mouse;
+};
+
+void x11_update_screen(struct x11_kerndata *kd)
+{
+ int y1,y2,offset,length;
+ unsigned char *src, *dst;
+ struct list_head *item;
+ struct x11_mapping *map;
+
+ y1 = kd->y1;
+ y2 = kd->y2;
+ kd->dirty = kd->y1 = kd->y2 = 0;
+ down(&kd->mm_lock);
+ list_for_each(item, &kd->mappings) {
+ map = list_entry(item, struct x11_mapping, next);
+ if (!map->faults)
+ continue;
+ zap_page_range(map->vma, map->vma->vm_start,
+ map->vma->vm_end - map->vma->vm_start, NULL);
+ map->faults = 0;
+ }
+ up(&kd->mm_lock);
+
+ offset = y1 * kd->fix->line_length;
+ length = (y2 - y1) * kd->fix->line_length;
+ src = kd->fb + offset;
+ dst = x11_get_fbmem(kd->win) + offset;
+ memcpy(dst,src,length);
+ x11_blit_fb(kd->win, y1, y2);
+}
+
+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)
+ x11_update_screen(kd);
+ 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 y1, int h)
+{
+ int y2;
+
+ y2 = y1 + h;
+ if (0 == kd->y2) {
+ kd->y1 = y1;
+ kd->y2 = y2;
+ }
+ 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->dy, 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->dy, 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->dy, area->height);
+}
+
+/* ------------------------------------------------------------------ */
+
+static void
+x11_fb_vm_open(struct vm_area_struct *vma)
+{
+ struct x11_mapping *map = vma->vm_private_data;
+
+ atomic_inc(&map->map_refs);
+}
+
+static void
+x11_fb_vm_close(struct vm_area_struct *vma)
+{
+ struct x11_mapping *map = vma->vm_private_data;
+ struct x11_kerndata *kd = map->kd;
+
+ down(&kd->mm_lock);
+ if (atomic_dec_and_test(&map->map_refs)) {
+ list_del(&map->next);
+ kfree(map);
+ }
+ up(&kd->mm_lock);
+}
+
+static struct page*
+x11_fb_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr,
+ int *type)
+{
+ struct x11_mapping *map = vma->vm_private_data;
+ struct x11_kerndata *kd = map->kd;
+ int pgnr = (vaddr - vma->vm_start) >> PAGE_SHIFT;
+ struct page *page;
+ int y1,y2;
+
+ if (pgnr >= kd->nr_pages)
+ return NOPAGE_SIGBUS;
+
+ down(&kd->mm_lock);
+ page = kd->pages[pgnr];
+ get_page(page);
+ map->faults++;
+
+ 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, y1, y2 - y1);
+ up(&kd->mm_lock);
+
+ if (type)
+ *type = VM_FAULT_MINOR;
+ return page;
+}
+
+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;
+ struct x11_mapping *map;
+ int retval;
+ int map_pages;
+
+ down(&kd->mm_lock);
+
+ retval = -ENOMEM;
+ if (NULL == (map = kmalloc(sizeof(*map), GFP_KERNEL))) {
+ printk("%s: oops, out of memory\n",__FUNCTION__);
+ goto out;
+ }
+ memset(map,0,sizeof(*map));
+
+ 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;
+ }
+
+ map_pages = (vma->vm_end - vma->vm_start + PAGE_SIZE-1) >> PAGE_SHIFT;
+ if (map_pages > kd->nr_pages) {
+ printk("%s: mapping to big (%ld > %d)\n",__FUNCTION__,
+ vma->vm_end - vma->vm_start, p->fix.smem_len);
+ goto out;
+ }
+
+ map->vma = vma;
+ map->faults = 0;
+ map->kd = kd;
+ atomic_set(&map->map_refs,1);
+ list_add(&map->next,&kd->mappings);
+ vma->vm_ops = &x11_fb_vm_ops;
+ vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
+ vma->vm_private_data = map;
+ 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,
+ .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 __init x11_probe(struct device *device)
+{
+ struct x11_kerndata *kd;
+ int i;
+
+ kd = kzalloc(sizeof(*kd),GFP_KERNEL);
+ if (NULL == kd)
+ return -ENOMEM;
+
+ kd->kbd = input_allocate_device();
+ kd->mouse = input_allocate_device();
+ if (NULL == kd->kbd || NULL == kd->mouse)
+ goto fail_free;
+
+ kd->win = x11_open(x11_width, x11_height);
+ if (NULL == kd->win) {
+ printk(DRIVER_NAME ": can't open X11 window\n");
+ goto fail_free;
+ }
+ kd->fix = x11_get_fix(kd->win);
+ kd->var = x11_get_var(kd->win);
+ INIT_LIST_HEAD(&kd->mappings);
+
+ /* alloc memory */
+ kd->fb = vmalloc(kd->fix->smem_len);
+ if (NULL == kd->fb) {
+ printk("%s: vmalloc(%d) failed\n",
+ __FUNCTION__,kd->fix->smem_len);
+ goto fail_close;
+ }
+ memset(kd->fb,0,kd->fix->smem_len);
+ kd->nr_pages = (kd->fix->smem_len + PAGE_SIZE-1) >> PAGE_SHIFT;
+ kd->pages = kmalloc(sizeof(struct page*)*kd->nr_pages, GFP_KERNEL);
+ if (NULL == kd->pages)
+ goto fail_vfree;
+ for (i = 0; i < kd->nr_pages; i++)
+ kd->pages[i] = vmalloc_to_page(kd->fb + i*PAGE_SIZE);
+
+ /* framebuffer setup */
+ kd->info = framebuffer_alloc(sizeof(u32) * 256, device);
+ kd->info->pseudo_palette = kd->info->par;
+ kd->info->par = kd;
+ kd->info->screen_base = kd->fb;
+
+ 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 */
+ 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 = DRIVER_NAME " virtual keyboard";
+ kd->kbd->phys = DRIVER_NAME "/input0";
+ kd->kbd->cdev.dev = device;
+ 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 = DRIVER_NAME " virtual mouse";
+ kd->mouse->phys = DRIVER_NAME "/input1";
+ kd->mouse->cdev.dev = device;
+ 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,
+ DRIVER_NAME " thread");
+ um_request_irq(X11_IRQ, x11_get_fd(kd->win), IRQ_READ, x11_irq,
+ SA_INTERRUPT | SA_SHIRQ, DRIVER_NAME, kd);
+
+ return 0;
+
+fail_vfree:
+ vfree(kd->fb);
+fail_close:
+ x11_close(kd->win);
+fail_free:
+ if (kd->kbd)
+ input_free_device(kd->kbd);
+ if (kd->mouse)
+ input_free_device(kd->mouse);
+ kfree(kd);
+ return -ENODEV;
+}
+
+static struct device_driver x11_driver = {
+ .name = DRIVER_NAME,
+ .bus = &platform_bus_type,
+ .probe = x11_probe,
+};
+static struct platform_device x11_device = {
+ .name = DRIVER_NAME,
+};
+
+static int __init x11_init(void)
+{
+ int ret;
+
+ ret = driver_register(&x11_driver);
+ if (ret)
+ return ret;
+ if (!x11_enable)
+ return 0;
+ ret = platform_device_register(&x11_device);
+ if (ret)
+ driver_unregister(&x11_driver);
+ return ret;
+}
+
+static void __exit x11_fini(void)
+{
+ if (x11_enable)
+ platform_device_unregister(&x11_device);
+ driver_unregister(&x11_driver);
+}
+
+module_init(x11_init);
+module_exit(x11_fini);
+
+extern int console_use_vt; /* FIXME */
+
+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)) {
+#if defined(CONFIG_DUMMY_CONSOLE)
+ printk("%s: enable linux vt subsystem\n",__FUNCTION__);
+ x11_enable = 1;
+ console_use_vt = 1;
+ conswitchp = &dummy_con;
+#endif
+ return 0;
+ }
+ return -1;
+}
+__setup("x11=", x11_setup);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
Index: linux-2.6.14/arch/um/drivers/x11_user.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.14/arch/um/drivers/x11_user.c 2005-12-12 17:12:27.000000000 +0100
@@ -0,0 +1,514 @@
+#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;
+ char *xidata;
+ XShmSegmentInfo shminfo;
+
+ /* framebuffer -- kernel */
+ struct fb_fix_screeninfo fix;
+ struct fb_var_screeninfo var;
+
+ /* kbd state */
+ unsigned char keydown[32];
+};
+
+/* --------------------------------------------------------------------------- */
+
+/*
+ * 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 ...
+ *
+ * FIXME: Our pseudo mouse driver delivers absolute coordinates in a
+ * touchscreen-like manner. Everybody (gpm, x.org) seems to interpret
+ * those as relative coordinates though.
+ */
+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_send(struct x11_window *win, struct x11_kerndata *kd,
+ int keycode, int updown)
+{
+ int key = KEY_RESERVED;
+
+ if (keycode < sizeof(x11_keymap)/sizeof(x11_keymap[0]))
+ key = x11_keymap[keycode];
+ if (KEY_RESERVED == key)
+ return;
+ x11_kbd_input(kd, key, updown);
+ if (keycode < 256) {
+ int by = keycode / 8;
+ int bi = keycode % 8;
+ if (updown)
+ win->keydown[by] |= (1 << bi);
+ else
+ win->keydown[by] &= ~(1 << bi);
+ }
+}
+
+static void x11_kbd(struct x11_window *win, struct x11_kerndata *kd, XEvent *e)
+{
+ int updown = 0;
+ unsigned long by,bi;
+
+ switch (e->type) {
+ case KeyPress:
+ updown = 1;
+ /* fall though */
+ case KeyRelease:
+ x11_kbd_send(win, kd, e->xkey.keycode, updown);
+ break;
+ case KeymapNotify:
+ for (by = 0; by < 32; by++) {
+ if (win->keydown[by] == e->xkeymap.key_vector[by])
+ continue;
+ for (bi = 0; bi < 8; bi++) {
+ if ((win->keydown[by] & (1 << bi)) ==
+ (e->xkeymap.key_vector[by] & (1 << bi)))
+ continue;
+ updown = e->xkeymap.key_vector[by] & (1 << bi)
+ ? 1 : 0;
+ x11_kbd_send(win, kd, by * 8 + bi, updown);
+ }
+ }
+ break;
+ }
+}
+
+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 1
+ /*
+ Hmm, seems not to work without MIT shm, maybe due
+ to the amount of data being sent over the socket
+ then? What does libX11 when writing to the socket
+ returns -EAGAIN?
+ */
+ goto fail_free;
+#endif
+ }
+ 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 | KeymapStateMask);
+ 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;
+}
+
+void x11_close(struct x11_window *win)
+{
+ if (win->shminfo.shmid) {
+ XShmDetach(win->dpy, &win->shminfo);
+ XDestroyImage(win->ximage);
+ shmdt(win->shminfo.shmaddr);
+ } else {
+ XDestroyImage(win->ximage);
+ }
+ XDestroyWindow(win->dpy,win->win);
+ XCloseDisplay(win->dpy);
+}
+
+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 y1, int y2)
+{
+ int x1 = 0;
+ int x2 = win->var.xres;
+
+ 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:
+ case KeymapNotify:
+ 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, 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:
+ */
Index: linux-2.6.14/arch/um/include/x11_kern.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.14/arch/um/include/x11_kern.h 2005-12-12 10:38:39.000000000 +0100
@@ -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);
Index: linux-2.6.14/arch/um/include/x11_user.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.14/arch/um/include/x11_user.h 2005-12-12 10:38:39.000000000 +0100
@@ -0,0 +1,15 @@
+/* x11_user */
+
+struct x11_window;
+struct x11_kerndata;
+
+struct x11_window *x11_open(int width, int height);
+void x11_close(struct x11_window *win);
+int x11_has_data(struct x11_window *win, struct x11_kerndata *kd);
+int x11_blit_fb(struct x11_window *win, 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);
+
Index: linux-2.6.14/arch/um/kernel/um_arch.c
===================================================================
--- linux-2.6.14.orig/arch/um/kernel/um_arch.c 2005-12-12 10:37:32.000000000 +0100
+++ linux-2.6.14/arch/um/kernel/um_arch.c 2005-12-12 17:11:22.000000000 +0100
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2000, 2002 Jeff Dike ([email protected])
* Licensed under the GPL
*/
@@ -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 @@ static void add_arg(char *arg)
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 @@ void set_cmdline(char *cmd)

umid = get_umid(1);
if(umid != NULL){
- 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";

@@ -206,7 +207,7 @@ static int __init uml_ncpus_setup(char *

__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

@@ -387,7 +388,7 @@ int linux_main(int argc, char **argv)
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;
@@ -456,6 +457,8 @@ static struct notifier_block panic_exit_
.priority = 0
};

+extern int console_use_vt; /* FIXME */
+
void __init setup_arch(char **cmdline_p)
{
notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
@@ -463,6 +466,9 @@ void __init setup_arch(char **cmdline_p)
strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
*cmdline_p = command_line;
setup_hostinfo();
+#if defined(CONFIG_DUMMY_CONSOLE)
+ console_use_vt = 0;
+#endif
}

void __init check_bugs(void)
Index: linux-2.6.14/drivers/video/fbmem.c
===================================================================
--- linux-2.6.14.orig/drivers/video/fbmem.c 2005-12-12 10:37:58.000000000 +0100
+++ linux-2.6.14/drivers/video/fbmem.c 2005-12-12 10:38:39.000000000 +0100
@@ -1182,12 +1182,16 @@ fb_mmap(struct file *file, struct vm_are
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
else
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+#elif defined(CONFIG_UML)
+ /* nothing */
#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 */
Index: linux-2.6.14/include/asm-um/irq.h
===================================================================
--- linux-2.6.14.orig/include/asm-um/irq.h 2005-12-07 13:24:03.000000000 +0100
+++ linux-2.6.14/include/asm-um/irq.h 2005-12-12 10:38:39.000000000 +0100
@@ -15,8 +15,9 @@
#define SIGIO_WRITE_IRQ 11
#define TELNETD_IRQ 12
#define XTERM_IRQ 13
+#define X11_IRQ 14

-#define LAST_IRQ XTERM_IRQ
+#define LAST_IRQ X11_IRQ
#define NR_IRQS (LAST_IRQ + 1)

#endif
Index: linux-2.6.14/drivers/char/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/char/Kconfig 2005-12-12 10:37:33.000000000 +0100
+++ linux-2.6.14/drivers/char/Kconfig 2005-12-12 10:38:39.000000000 +0100
@@ -59,7 +59,7 @@ config VT_CONSOLE

config HW_CONSOLE
bool
- depends on VT && !S390 && !UML
+ depends on VT && !S390
default y

config SERIAL_NONSTANDARD
Index: linux-2.6.14/arch/um/Makefile
===================================================================
--- linux-2.6.14.orig/arch/um/Makefile 2005-12-12 10:37:32.000000000 +0100
+++ linux-2.6.14/arch/um/Makefile 2005-12-12 10:38:39.000000000 +0100
@@ -126,12 +126,22 @@ CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \
#The wrappers will select whether using "malloc" or the kernel allocator.
LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc

+ifeq ($(SUBARCH),x86_64)
+ libdir = lib64
+else
+ libdir = lib
+endif
+UML_LIBS := -L/usr/$(libdir) -lutil
+ifeq ($(CONFIG_X11_FB),y)
+UML_LIBS += -L/usr/X11R6/$(libdir) -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


Attachments:
uml-x11-fb (34.63 kB)

2005-12-13 15:21:24

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [patch 1/2] uml/xen: make the vt subsystem a runtime option

On Tue, Dec 13, 2005 at 04:06:52PM +0100, Gerd Knorr wrote:
> #ifdef CONFIG_VT
> - if (device == MKDEV(TTY_MAJOR,0)) {
> + if (console_use_vt && device == MKDEV(TTY_MAJOR,0)) {

You don't register a cdev for this one below, so this can't be reached.

2005-12-13 15:32:31

by Gerd Hoffmann

[permalink] [raw]
Subject: Re: [patch 1/2] uml/xen: make the vt subsystem a runtime option

Christoph Hellwig wrote:
> On Tue, Dec 13, 2005 at 04:06:52PM +0100, Gerd Knorr wrote:
>> #ifdef CONFIG_VT
>> - if (device == MKDEV(TTY_MAJOR,0)) {
>> + if (console_use_vt && device == MKDEV(TTY_MAJOR,0)) {
>
> You don't register a cdev for this one below, so this can't be reached.

It can be reached in uml kernels. Unless the vt subsystem is enabled
the uml kernel registeres a uml-specific tty driver with major #5 (see
arch/um/drivers/stdio_console.c).

cheers,

Gerd

2005-12-13 21:23:49

by Jeff Dike

[permalink] [raw]
Subject: Re: [patch 2/2] uml: Framebuffer driver for UML

On Tue, Dec 13, 2005 at 04:16:00PM +0100, Gerd Knorr wrote:
> $subject says pretty much all: This adds a framebuffer driver for UML.

> please apply,
>
> Gerd

Please don't. This patch fails to link for me in -rc5 - the errors start like

drivers/built-in.o(.text+0x18b): In function `vgacon_deinit':
/home/jdike/linux/2.6/linux-2.6.15/drivers/video/console/vgacon.c:151: undefined reference to `outw'
drivers/built-in.o(.text+0x1a7):/home/jdike/linux/2.6/linux-2.6.15/drivers/video/console/vgacon.c:152: undefined reference to `outw'
drivers/built-in.o(.text+0x366): In function `vgacon_set_cursor_size':
/home/jdike/linux/2.6/linux-2.6.15/drivers/video/console/vgacon.c:430: undefined reference to `outb_p'
drivers/built-in.o(.text+0x375):/home/jdike/linux/2.6/linux-2.6.15/drivers/video/console/vgacon.c:431: undefined reference to `inb_p'
drivers/built-in.o(.text+0x396):/home/jdike/linux/2.6/linux-2.6.15/drivers/video/console/vgacon.c:432: undefined reference to `outb_p'
drivers/built-in.o(.text+0x3a5):/home/jdike/linux/2.6/linux-2.6.15/drivers/video/console/vgacon.c:433: undefined reference to `inb_p'

and go on for another couple hundred lines.

IIRC, I found fixes for these when I merged this into my tree. It's a nice
addition, but there are aspects of this that I don't like, which is why I
haven't sent it in myself. Again, IIRC, enabling this disables the normal
consoles, which is fairly unfriendly.

Jeff

2005-12-15 09:06:30

by Gerd Hoffmann

[permalink] [raw]
Subject: Re: [patch 2/2] uml: Framebuffer driver for UML

Jeff Dike wrote:
> On Tue, Dec 13, 2005 at 04:16:00PM +0100, Gerd Knorr wrote:
>> $subject says pretty much all: This adds a framebuffer driver for UML.
>
>> please apply,
>>
>> Gerd
>
> Please don't. This patch fails to link for me in -rc5 - the errors start like
>
> drivers/built-in.o(.text+0x18b): In function `vgacon_deinit':
> /home/jdike/linux/2.6/linux-2.6.15/drivers/video/console/vgacon.c:151: undefined reference to `outw'

Uh, I havn't even tried to build vgacon, it doesn't make sense for UML
anyway. It's not needed, my .config looks like this:

CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y

Should be trivially fixable with some Kconfig tweaks, I'll have a look.

> IIRC, I found fixes for these when I merged this into my tree. It's a nice
> addition, but there are aspects of this that I don't like, which is why I
> haven't sent it in myself.

What exactly?

> Again, IIRC, enabling this disables the normal
> consoles, which is fairly unfriendly.

Yep, there is no way around that because the uml consoles hijacked the
vt subsystem's major #5. Unlike in older versions of that patch this
isn't a compile time but a runtime option, so it's much less annonying.
The uml consoles are present unless you activate the vt subsystem and
the framebuffer console by boot the kernel with x11=something.

cheers,

Gerd

2005-12-15 11:14:37

by Gerd Hoffmann

[permalink] [raw]
Subject: Re: [patch 2/2] uml: Framebuffer driver for UML

Index: linux-2.6.14/drivers/input/keyboard/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/input/keyboard/Kconfig 2005-12-12 18:24:51.000000000 +0100
+++ linux-2.6.14/drivers/input/keyboard/Kconfig 2005-12-15 12:07:26.000000000 +0100
@@ -10,7 +10,7 @@ menuconfig INPUT_KEYBOARD

If unsure, say Y.

-if INPUT_KEYBOARD
+if INPUT_KEYBOARD && !UML

config KEYBOARD_ATKBD
tristate "AT keyboard" if !X86_PC
Index: linux-2.6.14/drivers/input/mouse/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/input/mouse/Kconfig 2005-12-12 18:24:51.000000000 +0100
+++ linux-2.6.14/drivers/input/mouse/Kconfig 2005-12-15 12:06:59.000000000 +0100
@@ -10,7 +10,7 @@ menuconfig INPUT_MOUSE

If unsure, say Y.

-if INPUT_MOUSE
+if INPUT_MOUSE && !UML

config MOUSE_PS2
tristate "PS/2 mouse"
Index: linux-2.6.14/drivers/input/serio/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/input/serio/Kconfig 2005-10-28 02:02:08.000000000 +0200
+++ linux-2.6.14/drivers/input/serio/Kconfig 2005-12-15 12:06:11.000000000 +0100
@@ -21,7 +21,7 @@ if SERIO
config SERIO_I8042
tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86
default y
- depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && !M68K
+ depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && !M68K && !UML
---help---
i8042 is the chip over which the standard AT keyboard and PS/2
mouse are connected to the computer. If you use these devices,
Index: linux-2.6.14/drivers/video/console/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/video/console/Kconfig 2005-12-12 18:25:03.000000000 +0100
+++ linux-2.6.14/drivers/video/console/Kconfig 2005-12-15 12:01:31.000000000 +0100
@@ -6,7 +6,7 @@ menu "Console display driver support"

config VGA_CONSOLE
bool "VGA text console" if EMBEDDED || !X86
- depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC32 && !SPARC64 && !M68K && !PARISC && !ARCH_VERSATILE
+ depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC32 && !SPARC64 && !M68K && !PARISC && !ARCH_VERSATILE && !UML
default y
help
Saying Y here will allow you to use Linux in text mode through a


Attachments:
uml-kconfig (2.30 kB)

2005-12-15 13:23:58

by Gerd Hoffmann

[permalink] [raw]
Subject: Re: [patch 2/2] uml: Framebuffer driver for UML

Index: linux-2.6.14/drivers/input/keyboard/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/input/keyboard/Kconfig 2005-12-12 18:24:51.000000000 +0100
+++ linux-2.6.14/drivers/input/keyboard/Kconfig 2005-12-15 12:07:26.000000000 +0100
@@ -10,7 +10,7 @@ menuconfig INPUT_KEYBOARD

If unsure, say Y.

-if INPUT_KEYBOARD
+if INPUT_KEYBOARD && !UML

config KEYBOARD_ATKBD
tristate "AT keyboard" if !X86_PC
Index: linux-2.6.14/drivers/input/mouse/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/input/mouse/Kconfig 2005-12-12 18:24:51.000000000 +0100
+++ linux-2.6.14/drivers/input/mouse/Kconfig 2005-12-15 12:06:59.000000000 +0100
@@ -10,7 +10,7 @@ menuconfig INPUT_MOUSE

If unsure, say Y.

-if INPUT_MOUSE
+if INPUT_MOUSE && !UML

config MOUSE_PS2
tristate "PS/2 mouse"
Index: linux-2.6.14/drivers/input/serio/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/input/serio/Kconfig 2005-10-28 02:02:08.000000000 +0200
+++ linux-2.6.14/drivers/input/serio/Kconfig 2005-12-15 12:06:11.000000000 +0100
@@ -21,7 +21,7 @@ if SERIO
config SERIO_I8042
tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86
default y
- depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && !M68K
+ depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && !M68K && !UML
---help---
i8042 is the chip over which the standard AT keyboard and PS/2
mouse are connected to the computer. If you use these devices,
Index: linux-2.6.14/drivers/video/console/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/video/console/Kconfig 2005-12-12 18:25:03.000000000 +0100
+++ linux-2.6.14/drivers/video/console/Kconfig 2005-12-15 12:01:31.000000000 +0100
@@ -6,7 +6,7 @@ menu "Console display driver support"

config VGA_CONSOLE
bool "VGA text console" if EMBEDDED || !X86
- depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC32 && !SPARC64 && !M68K && !PARISC && !ARCH_VERSATILE
+ depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC32 && !SPARC64 && !M68K && !PARISC && !ARCH_VERSATILE && !UML
default y
help
Saying Y here will allow you to use Linux in text mode through a
Index: linux-2.6.14/drivers/char/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/char/Kconfig 2005-12-12 18:25:17.000000000 +0100
+++ linux-2.6.14/drivers/char/Kconfig 2005-12-15 12:52:55.000000000 +0100
@@ -64,6 +64,7 @@ config HW_CONSOLE

config SERIAL_NONSTANDARD
bool "Non-standard serial port support"
+ depends on !UML
---help---
Say Y here if you have any non-standard serial boards -- boards
which aren't supported using the standard "dumb" serial driver.
@@ -687,7 +688,7 @@ config NVRAM

config RTC
tristate "Enhanced Real Time Clock Support"
- depends on !PPC32 && !PARISC && !IA64 && !M68K
+ depends on !PPC32 && !PARISC && !IA64 && !M68K && !UML
---help---
If you say Y here and create a character special file /dev/rtc with
major number 10 and minor number 135 using mknod ("man mknod"), you
@@ -735,7 +736,7 @@ config SGI_IP27_RTC

config GEN_RTC
tristate "Generic /dev/rtc emulation"
- depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC32 && !SPARC64
+ depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC32 && !SPARC64 && !UML
---help---
If you say Y here and create a character special file /dev/rtc with
major number 10 and minor number 135 using mknod ("man mknod"), you
@@ -792,6 +793,7 @@ config COBALT_LCD

config DTLK
tristate "Double Talk PC internal speech card support"
+ depends on ISA
help
This driver is for the DoubleTalk PC, a speech synthesizer
manufactured by RC Systems (<http://www.rcsys.com/>). It is also
Index: linux-2.6.14/drivers/char/ipmi/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/char/ipmi/Kconfig 2005-10-28 02:02:08.000000000 +0200
+++ linux-2.6.14/drivers/char/ipmi/Kconfig 2005-12-15 12:54:05.000000000 +0100
@@ -5,6 +5,7 @@
menu "IPMI"
config IPMI_HANDLER
tristate 'IPMI top-level message handler'
+ depends on !UML
help
This enables the central IPMI message handler, required for IPMI
to work.
Index: linux-2.6.14/drivers/char/tpm/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/char/tpm/Kconfig 2005-12-12 18:24:50.000000000 +0100
+++ linux-2.6.14/drivers/char/tpm/Kconfig 2005-12-15 12:54:46.000000000 +0100
@@ -6,7 +6,7 @@ menu "TPM devices"

config TCG_TPM
tristate "TPM Hardware Support"
- depends on EXPERIMENTAL
+ depends on EXPERIMENTAL && !UML
---help---
If you have a TPM security chip in your system, which
implements the Trusted Computing Group's specification,
Index: linux-2.6.14/drivers/input/touchscreen/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/input/touchscreen/Kconfig 2005-10-28 02:02:08.000000000 +0200
+++ linux-2.6.14/drivers/input/touchscreen/Kconfig 2005-12-15 13:21:13.000000000 +0100
@@ -9,7 +9,7 @@ menuconfig INPUT_TOUCHSCREEN

If unsure, say Y.

-if INPUT_TOUCHSCREEN
+if INPUT_TOUCHSCREEN && !UML

config TOUCHSCREEN_BITSY
tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
Index: linux-2.6.14/drivers/serial/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/serial/Kconfig 2005-12-15 11:59:47.000000000 +0100
+++ linux-2.6.14/drivers/serial/Kconfig 2005-12-15 14:03:09.000000000 +0100
@@ -11,6 +11,7 @@ menu "Serial drivers"
config SERIAL_8250
tristate "8250/16550 and compatible serial support"
depends on (BROKEN || !(SPARC64 || SPARC32))
+ depends on !UML
select SERIAL_CORE
---help---
This selects whether you want to include the driver for the standard
Index: linux-2.6.14/drivers/video/Kconfig
===================================================================
--- linux-2.6.14.orig/drivers/video/Kconfig 2005-12-12 18:25:16.000000000 +0100
+++ linux-2.6.14/drivers/video/Kconfig 2005-12-15 14:06:13.000000000 +0100
@@ -602,7 +602,7 @@ config FB_EPSON1355

config FB_S1D13XXX
tristate "Epson S1D13XXX framebuffer support"
- depends on FB
+ depends on FB && !UML
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT


Attachments:
uml-kconfig (6.37 kB)