diff -urNpB kernel-2.6.23-v2/Kbuild contrib/Kbuild
--- kernel-2.6.23-v2/Kbuild
+++ contrib/Kbuild
@@ -57,4 +57,5 @@ quiet_cmd_syscalls = CALL    $<
 
 PHONY += missing-syscalls
 missing-syscalls: scripts/checksyscalls.sh FORCE
-	$(call cmd,syscalls)
+	@echo   Ignoring $@
+#	$(call cmd,syscalls)
diff -urNpB kernel-2.6.23-v2/arch/l4/Kconfig contrib/arch/l4/Kconfig
--- kernel-2.6.23-v2/arch/l4/Kconfig
+++ contrib/arch/l4/Kconfig
@@ -1,3 +1,5 @@
+mainmenu "OKLinux Kernel Configuration"
+
 config L4
 	bool
 	default y
@@ -23,7 +25,7 @@ config RWSEM_GENERIC_SPINLOCK
    bool
    default y
 
-mainmenu "L4/Linux Kernel Configuration"
+#mainmenu "L4/Linux Kernel Configuration"
 
 menu "L4/Linux-specific options"
 
@@ -33,19 +35,19 @@ config L4KDB_CONSOLE
 
 config IG_SERIAL
 	bool "Compile Iguana virtual serial driver"
-	default y
+	default n
 
 config IG_INPUT
 	bool "Compile Iguana virtual input driver"
-	default y
+	default n
 
 config IG_MMC
 	bool "Compile Iguana virtual mmc/sd driver"
-	default y
+	default n
 
 config IG_NET
 	bool "Compile Iguana virtual net driver"
-	default y
+	default n
 
 config MTD_IGMTD
 	tristate "Iguana virtual MTD device"
@@ -69,13 +71,35 @@ config IG_AUDIO
 config IG_TOUCH
 	bool "Compile Iguana virtual touch screen driver"
 	depends on INPUT && INPUT_TOUCHSCREEN
-	default y
+	default n
 
 config FB_IGVIRTUAL
 	tristate "Iguana Virtual Frame buffer support (ONLY FOR TESTING!)"
 	depends on FB
 	default n
 
+config SCREEN_GENODE
+	bool
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	default y
+
+config SND_GENODE
+	bool
+	select SND_PCM
+	default y
+
+config BLOCK_GENODE
+	bool
+	select BLOCK
+	default y
+
+config NET_GENODE
+	bool
+	select NET
+	default y
+
 endmenu
 
 config GENERIC_HWEIGHT
@@ -212,12 +236,12 @@ bool "Support for PLEB2 platform"
 endchoice
 
 config NODES_SHIFT
-	int
-	default 4
+	int "NODES_SHIFT"
+	default 5
 #	default "7" if MPENTIUM4 || X86_GENERIC
 
 config L4_ZONE_SIZE
-	int
+	int "L4_ZONE_SIZE"
 	default 22
 #	default "7" if MPENTIUM4 || X86_GENERIC
 
@@ -273,7 +297,7 @@ config CPU_HAS_LLDSCD
 
 config GENERIC_CALIBRATE_DELAY
 	bool
-	default y
+	default n
 
 config ISA
 	bool
@@ -311,7 +335,7 @@ source "net/Kconfig"
 source "fs/Kconfig"
 config OKL4FS
     bool
-    default m
+    default n
  
 source "drivers/mmc/Kconfig"
 
@@ -360,17 +384,17 @@ source "drivers/mca/Kconfig"
 
 endmenu
 
-source "drivers/scsi/Kconfig"
+source "drivers/parport/Kconfig"
 
-source "drivers/ata/Kconfig"
+source "drivers/pnp/Kconfig"
 
-#source "security/Kconfig"
+source "drivers/misc/Kconfig"
 
-#source "crypto/Kconfig"
+source "drivers/scsi/Kconfig"
 
-source "lib/Kconfig"
+source "drivers/ata/Kconfig"
 
-#source "drivers/md/Kconfig"
+source "drivers/md/Kconfig"
 
 source "drivers/mtd/Kconfig"
 
@@ -384,12 +408,24 @@ source "drivers/net/Kconfig"
 
 source "drivers/hid/Kconfig"
 
+source "drivers/hwmon/Kconfig"
+
+source "drivers/media/Kconfig"
+
 source "drivers/usb/Kconfig"
 
+source "drivers/leds/Kconfig"
+
 source "sound/Kconfig"
 
 source "drivers/i2c/Kconfig"
 
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
+
 menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
@@ -397,7 +433,7 @@ source "lib/Kconfig.debug"
 config EARLY_PRINTK
 	bool "Early printk" if EMBEDDED
 	depends on L4KDB_CONSOLE
-	default n
+	default y
 	help
 	  Write kernel log output directly to L4 KDB.
 
diff -urNpB kernel-2.6.23-v2/arch/l4/Makefile contrib/arch/l4/Makefile
--- kernel-2.6.23-v2/arch/l4/Makefile
+++ contrib/arch/l4/Makefile
@@ -105,12 +105,21 @@ CFLAGS += -DCONFIG_HYBRID_MUTEXES
 core-y			+= $(ARCH_DIR)/kernel/		 \
 			   $(ARCH_DIR)/mm/  \
 			   $(ARCH_DIR)/lib/  \
-			   $(ARCH_DIR)/sys-$(SYSTEM)/ \
-			   $(ARCH_DIR)/kernel/fs/okl4fs/
+			   $(ARCH_DIR)/sys-$(SYSTEM)/
+
+#			   $(ARCH_DIR)/kernel/fs/okl4fs
 
 drivers-y                  += $(ARCH_DIR)/drivers/
 
-libs-y +=  -lvtimer -lvserial -ll4e -lll -liguana -ll4 -lgcc -lmutex -lcircular_buffer -lc -latomic_ops -lfs
+#libs-y +=  -lvtimer -lvserial -ll4e -lll -liguana -ll4 -lgcc -lmutex -lcircular_buffer -lc -latomic_ops -lfs
+
+GENODE_LIBS = slab allocator_avl cxx ipc heap console log_console lock env \
+              thread oklx startup avl_tree signal
+
+libs-y += $(addprefix $(GENODE_LIBS_DIR)/,$(foreach l,$(GENODE_LIBS),$l/$l.lib.a))
+
+# link libgcc
+libs-y += $(shell $(CC) $(WOMBAT_CFLAGS) -print-libgcc-file-name)
 
 #libs-$(CONFIG_ARCH_PXA) += -lpxa
 
@@ -128,7 +137,7 @@ AFLAGS += -D__arch_l4__ -D__SYSTEM__=$(S
 
 CFLAGS += -Iarch/l4/include -Iinclude/asm-l4
 CFLAGS += -I../include
-CFLAGS += -I../../../tools/magpie/include
+#CFLAGS += -I../../../tools/magpie/include
 CFLAGS += $(WOMBAT_CFLAGS)
 
 AFLAGS += -Iarch/l4/include
diff -urNpB kernel-2.6.23-v2/arch/l4/drivers/Makefile contrib/arch/l4/drivers/Makefile
--- kernel-2.6.23-v2/arch/l4/drivers/Makefile
+++ contrib/arch/l4/drivers/Makefile
@@ -1,4 +1,7 @@
-obj-y := ig_ramdisk.o
+obj-$(CONFIG_SCREEN_GENODE) += genode_fb.o
+obj-$(CONFIG_BLOCK_GENODE)  += genode_block.o
+obj-$(CONFIG_SND_GENODE)    += genode_audio.o
+obj-$(CONFIG_NET_GENODE)    += genode_net.o
 obj-$(CONFIG_FB_IGVIRTUAL)  += ig_fb.o cfbcopyarea.o cfbfillrect.o cfbimgblt.o
 obj-$(CONFIG_L4KDB_CONSOLE) += l4kdb_console.o
 obj-$(CONFIG_IG_SERIAL) += ig_serial.o
diff -urNpB kernel-2.6.23-v2/arch/l4/drivers/genode_audio.c contrib/arch/l4/drivers/genode_audio.c
--- kernel-2.6.23-v2/arch/l4/drivers/genode_audio.c
+++ contrib/arch/l4/drivers/genode_audio.c
@@ -0,0 +1,325 @@
+/*
+ *  Alsa soundcard driver for OKLinux/Genode
+ *
+ *  Stefan Kalkowski <kalkowski@genode-labs.com>
+ */
+
+/*
+ * Copyright (C) 2006-2009
+ * Genode Labs, Feske & Helmuth Systementwicklung GbR
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+#include <sound/driver.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/wait.h>
+#include <linux/moduleparam.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/tlv.h>
+#include <sound/pcm.h>
+#include <sound/rawmidi.h>
+#include <sound/initval.h>
+
+#include <genode/audio.h>
+#include <genode/printf.h>
+
+#define DEBUG 0
+
+#define PDBG(args...) do {                         \
+		if(DEBUG) {                                \
+			genode_printf("%s(): ", __FUNCTION__); \
+			genode_printf("\033[33m");             \
+			genode_printf(args);                   \
+			genode_printf("\033[0m\n");            \
+		}                                          \
+	} while(0)
+
+
+static struct platform_device *platform_dev_ptr = 0;
+static void                   *packet_cache     = 0;
+static short                   stopped          = 1;
+
+static struct snd_pcm_hardware snd_genode_playback_props =
+{
+	.info             = SNDRV_PCM_INFO_INTERLEAVED,
+	.formats          = SNDRV_PCM_FMTBIT_S16_LE,
+	.rates            = SNDRV_PCM_RATE_44100,
+	.rate_min         = 44100,
+	.rate_max         = 44100,
+	.channels_min     = 2,
+	.channels_max     = 2,
+};
+
+
+static void snd_genode_period_elapsed_callback(unsigned long data)
+{
+	PDBG("Enter");
+	snd_pcm_period_elapsed((struct snd_pcm_substream *)data);
+}
+
+
+/**********************
+ * Callback functions *
+ **********************/
+
+static int snd_genode_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	spinlock_t *lock = runtime->private_data;
+	int err = 0;
+
+	spin_lock(lock);
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+		PDBG("Start");
+		genode_audio_trigger_start(snd_genode_period_elapsed_callback,
+		                           (unsigned long)substream);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+		PDBG("Stop");
+		genode_audio_trigger_stop();
+		stopped = 1;
+		break;
+	default:
+		PDBG("Unknown %d", cmd);
+		err = -EINVAL;
+		break;
+	}
+	spin_unlock(lock);
+	return 0;
+}
+
+
+static int snd_genode_prepare(struct snd_pcm_substream *substream)
+{
+	PDBG("buffer_size=%lx count=%d", snd_pcm_lib_buffer_bytes(substream),
+	     snd_pcm_lib_period_bytes(substream));
+	genode_audio_prepare();
+	return 0;
+}
+
+
+static snd_pcm_uframes_t snd_genode_pointer(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	unsigned long v = genode_audio_position();
+	unsigned long pos = bytes_to_frames(runtime, v) % runtime->buffer_size;
+	PDBG("position=%lx", pos);
+	return pos;
+}
+
+
+static void snd_genode_runtime_free(struct snd_pcm_runtime *runtime)
+{
+	spinlock_t *lock = (spinlock_t*) runtime->private_data;
+	PDBG("Enter");
+	kfree(lock);
+	kfree(packet_cache);
+}
+
+
+static int snd_genode_hw_params(struct snd_pcm_substream *substream,
+                                struct snd_pcm_hw_params *hw_params)
+{
+	PDBG("params_buffer_bytes=%lx", params_buffer_bytes(hw_params));
+	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+}
+
+
+static int snd_genode_hw_free(struct snd_pcm_substream *substream)
+{
+	PDBG("Enter");
+	return snd_pcm_lib_free_pages(substream);
+}
+
+
+static int snd_genode_playback_open(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	spinlock_t *lock;
+
+	PDBG("Enter");
+
+	if (!(lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL)))
+		return -ENOMEM;
+	spin_lock_init(lock);
+	runtime->private_data = lock;
+	runtime->private_free = snd_genode_runtime_free;
+
+	runtime->hw                  = snd_genode_playback_props;
+	runtime->hw.buffer_bytes_max = genode_audio_packet_count()
+	                               * genode_audio_packet_size();
+	runtime->hw.period_bytes_min = genode_audio_packet_size();
+	runtime->hw.period_bytes_max = genode_audio_packet_size();
+	runtime->hw.periods_min      = 1;
+	runtime->hw.periods_max      = genode_audio_packet_count();
+
+	if (!(packet_cache = kmalloc(runtime->hw.buffer_bytes_max, GFP_KERNEL))) {
+		kfree(lock);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+
+static int snd_genode_playback_close(struct snd_pcm_substream *substream)
+{
+	PDBG("Enter");
+	return 0;
+}
+
+
+static int snd_genode_copy(struct snd_pcm_substream *substream,
+                           int channel, snd_pcm_uframes_t pos,
+                           void __user *buf, snd_pcm_uframes_t count)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	unsigned long size = frames_to_bytes(runtime, count);
+	static snd_pcm_uframes_t position = 0;
+
+	if (stopped)
+		stopped = 0;
+	else
+		if (position == pos)
+			return 0;
+	position = pos;
+
+	PDBG("copy=%lx %lx\n", pos, count);
+	copy_from_user(packet_cache, buf, size);
+	genode_audio_write(packet_cache, size);
+	return 0;
+}
+
+
+static int snd_genode_silence(struct snd_pcm_substream *substream,
+                              int channel, snd_pcm_uframes_t pos,
+                              snd_pcm_uframes_t count)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	unsigned long size = frames_to_bytes(runtime, count);
+
+	PDBG("silence=%lx", size);
+	genode_audio_fill_silence(size);
+	return 0;
+}
+
+
+/****************************
+ * Initialization functions *
+ ****************************/
+
+#define SND_GENODE_DRIVER "snd_genode"
+
+
+static struct snd_pcm_ops snd_genode_playback_ops = {
+	.ioctl     = snd_pcm_lib_ioctl,
+	.open      = snd_genode_playback_open,
+	.close     = snd_genode_playback_close,
+	.hw_params = snd_genode_hw_params,
+	.hw_free   = snd_genode_hw_free,
+	.prepare   = snd_genode_prepare,
+	.trigger   = snd_genode_trigger,
+	.pointer   = snd_genode_pointer,
+	.copy      = snd_genode_copy,
+	.silence   = snd_genode_silence,
+};
+
+
+static int __devinit snd_genode_probe(struct platform_device *devptr)
+{
+	int err = 0;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+
+	if(!(card = snd_card_new(0, SND_GENODE_DRIVER, THIS_MODULE, 0)))
+		return -ENOMEM;
+
+	if ((err = snd_pcm_new(card, "Genode PCM", 0, 1, 0, &pcm)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_genode_playback_ops);
+	pcm->info_flags = 0;
+	strcpy(pcm->name, "Genode PCM");
+	if((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
+	                                                snd_dma_continuous_data(GFP_KERNEL),
+	                                                0, genode_audio_packet_count()
+	                                                * genode_audio_packet_size())) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	strcpy(card->driver, "Genode");
+	strcpy(card->shortname, "Genode");
+	sprintf(card->longname, "Genode %i", devptr->id + 1);
+	snd_card_set_dev(card, &devptr->dev);
+
+	if (!(err = snd_card_register(card)))
+		platform_set_drvdata(devptr, card);
+	else {
+		snd_card_free(card);
+		return err;
+	}
+	return 0;
+}
+
+
+static int __devexit snd_genode_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, 0);
+	return 0;
+}
+
+
+static struct platform_driver snd_genode_driver = {
+	.probe      = snd_genode_probe,
+	.remove     = __devexit_p(snd_genode_remove),
+	.driver     = {
+		.name   = SND_GENODE_DRIVER
+	},
+};
+
+
+static int __init alsa_card_genode_init(void)
+{
+	int err = 0;
+
+	if (!genode_audio_ready())
+		return err;
+
+	if (!(err = platform_driver_register(&snd_genode_driver))) {
+		platform_dev_ptr = platform_device_register_simple(SND_GENODE_DRIVER, 0, 0, 0);
+		if (!platform_get_drvdata(platform_dev_ptr)) {
+			platform_device_unregister(platform_dev_ptr);
+			err = -ENODEV;
+		}
+	}
+	return err;
+}
+
+
+static void __exit alsa_card_genode_exit(void)
+{
+	platform_device_unregister(platform_dev_ptr);
+	platform_driver_unregister(&snd_genode_driver);
+}
+
+module_init(alsa_card_genode_init);
+module_exit(alsa_card_genode_exit);
+
+MODULE_AUTHOR("Stefan Kalkowski <stefan.kalkowski@genode-labs.com>");
+MODULE_DESCRIPTION("Genode sound stub");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{ALSA,Genode sound stub}}");
diff -urNpB kernel-2.6.23-v2/arch/l4/drivers/genode_block.c contrib/arch/l4/drivers/genode_block.c
--- kernel-2.6.23-v2/arch/l4/drivers/genode_block.c
+++ contrib/arch/l4/drivers/genode_block.c
@@ -0,0 +1,273 @@
+/*
+ * \brief  Block driver to access Genode's block service
+ * \author Stefan Kalkowski <stefan.kalkowski@genode-labs.com>
+ * \date   2010-07-08
+ *
+ * This file is based on the sbull block driver from
+ * Linux Device Drivers, 3rd edition chapter 16 "Block Drivers".
+ */
+
+/*
+ * Copyright (C) 2006-2012 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+/* Linux includes */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/genhd.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <asm/semaphore.h>
+
+/* Genode support library includes */
+#include <genode/config.h>
+#include <genode/block.h>
+
+enum Geometry {
+		KERNEL_SECTOR_SIZE = 512,      /* sector size used by kernel */
+		GENODE_BLK_MINORS  = 16        /* number of minor numbers */
+};
+
+
+/*
+ * The internal representation of our device.
+ */
+static struct genode_blk_device {
+		unsigned              blk_cnt;    /* Total block count */
+		unsigned long         blk_sz;     /* Single block size */
+		spinlock_t            lock;       /* For mutual exclusion */
+		struct gendisk       *gd;         /* Generic disk structure */
+		struct request_queue *queue;      /* The device request queue */
+		struct semaphore      queue_wait; /* Used to block, when queue is full */
+		short                 stopped;    /* Indicates queue availability */
+} blk_dev;
+
+
+/*
+ * Handle an I/O request.
+ */
+static void genode_blk_request(struct request_queue *q)
+{
+	struct request *req;
+	unsigned long queue_offset;
+
+	while ((req = elv_next_request(q)) != NULL) {
+		void *buf            = 0;
+		unsigned long offset = req->sector * KERNEL_SECTOR_SIZE;
+		unsigned long nbytes = req->nr_sectors * KERNEL_SECTOR_SIZE;
+		short write          = rq_data_dir(req);
+
+		if (!blk_fs_request(req)) {
+			printk (KERN_NOTICE "Skip non-fs request\n");
+			end_request(req, 0);
+			continue;
+		}
+
+		blkdev_dequeue_request(req);
+
+		while (!buf) {
+			if ((buf = genode_block_request(nbytes, req, &queue_offset)))
+				break;
+
+			/* stop_queue needs disabled interrupts */
+			isr_irq_disable();
+			blk_stop_queue(q);
+			isr_irq_enable();
+
+			/* block until new responses are available */
+			blk_dev.stopped = 1;
+			down(&blk_dev.queue_wait);
+
+			/* start_queue needs disabled interrupts */
+			isr_irq_disable();
+			blk_start_queue(q);
+			isr_irq_enable();
+		}
+
+		if (write) {
+			struct bio *bio;
+			struct bio_vec *bvec;
+			int idx;
+			char *ptr = (char*) buf;
+
+			rq_for_each_bio(bio, req) {
+				bio_for_each_segment(bvec, bio, idx) {
+					void *buffer     = __bio_kmap_atomic(bio, idx, KM_USER0);
+					unsigned long sz = bio_cur_sectors(bio) * KERNEL_SECTOR_SIZE;
+					memcpy((void*)ptr, buffer, sz);
+					__bio_kunmap_atomic(buffer, KM_USER0);
+				}
+			}
+		}
+
+		genode_block_submit(queue_offset, nbytes, offset, write);
+	}
+}
+
+
+static void genode_end_request(void *request, short write,
+                               void *buf, unsigned long sz) {
+	struct request *req = (struct request*) request;
+	char *ptr = (char*) buf;
+
+	if (!write) {
+		struct bio *bio;
+		struct bio_vec *bvec;
+		int idx;
+		rq_for_each_bio(bio, req) {
+			bio_for_each_segment(bvec, bio, idx) {
+				void *buffer = __bio_kmap_atomic(bio, idx, KM_USER0);
+				unsigned long nbytes = bio_cur_sectors(bio) * KERNEL_SECTOR_SIZE;
+				memcpy(buffer, (void*)ptr, nbytes);
+				ptr += nbytes;
+				__bio_kunmap_atomic(buffer, KM_USER0);
+			}
+		}
+	}
+
+	if (!end_that_request_first(req, 1, req->nr_sectors))
+		end_that_request_last(req, 1);
+
+	if (blk_dev.stopped) {
+		blk_dev.stopped = 0;
+		up(&blk_dev.queue_wait);
+	}
+}
+
+
+/*
+ * Ioctl method.
+ */
+int genode_blk_ioctl (struct inode *inode, struct file *filp,
+                      unsigned int cmd, unsigned long arg)
+{
+		struct hd_geometry geo;
+		struct genode_blk_device *dev = inode->i_bdev->bd_disk->private_data;
+
+		switch(cmd) {
+		case HDIO_GETGEO:
+			{
+				/*
+				 * Get geometry: since we cannot access the real geometry of the
+				 * device, we have to make up something plausible. So we claim
+				 * 16 sectors, four heads, and calculate the corresponding number
+				 * of cylinders. We set the start of data at sector four.
+				 */
+				unsigned long size = dev->blk_cnt * dev->blk_sz *
+					(dev->blk_sz / KERNEL_SECTOR_SIZE);
+				geo.cylinders = (size & ~0x3f) >> 6;
+				geo.heads     = 4;
+				geo.sectors   = 16;
+				geo.start     = 4;
+				if (copy_to_user((void *) arg, &geo, sizeof(geo)))
+						return -EFAULT;
+				return 0;
+			}
+		}
+		return -ENOTTY; /* unknown command */
+}
+
+
+/*
+ * The device operations structure.
+ */
+static struct block_device_operations genode_blk_ops = {
+		.owner = THIS_MODULE,
+		.ioctl = genode_blk_ioctl
+};
+
+static int __init genode_blk_init(void)
+{
+		int           major_num;
+		int           writeable    = 0;
+		unsigned long req_queue_sz = 0;
+
+		if (!genode_config_block())
+			return 0;
+
+		/* Initialize device structure */
+		memset (&blk_dev, 0, sizeof (struct genode_blk_device));
+		spin_lock_init(&blk_dev.lock);
+
+		genode_block_geometry((unsigned long*)&blk_dev.blk_cnt,
+		                      &blk_dev.blk_sz, &writeable, &req_queue_sz);
+
+		genode_block_register_callback(genode_end_request);
+
+		/*
+		 * Get a request queue.
+		 */
+		if(!(blk_dev.queue = blk_init_queue(genode_blk_request, &blk_dev.lock)))
+				return -ENOMEM;
+
+		/*
+		 * Align queue requests to hardware sector size.
+		 */
+		blk_queue_hardsect_size(blk_dev.queue, blk_dev.blk_sz);
+
+		/*
+		 * Important, limit number of sectors per request,
+		 * as Genode's block-session has a limited request-transmit-queue.
+		 */
+		blk_queue_max_sectors(blk_dev.queue, req_queue_sz / KERNEL_SECTOR_SIZE);
+		blk_dev.queue->queuedata = &blk_dev;
+
+		sema_init(&blk_dev.queue_wait, 0);
+		blk_dev.stopped = 0;
+
+		/*
+		 * Register block device and gain major number.
+		 */
+		if((major_num = register_blkdev(0, "genode_blk")) < 0) {
+				printk(KERN_WARNING "genode_blk: unable to get major number\n");
+				return -EBUSY;
+		}
+
+		/*
+		 * Allocate and setup generic disk structure.
+		 */
+		if(!(blk_dev.gd = alloc_disk(GENODE_BLK_MINORS))) {
+				unregister_blkdev(major_num, "genode_blk");
+				return -ENOMEM;
+		}
+		blk_dev.gd->major        = major_num;
+		blk_dev.gd->first_minor  = 0;
+		blk_dev.gd->fops         = &genode_blk_ops;
+		blk_dev.gd->private_data = &blk_dev;
+		blk_dev.gd->queue        = blk_dev.queue;
+		strncpy(blk_dev.gd->disk_name, "sda", sizeof(blk_dev.gd->disk_name));
+		set_capacity(blk_dev.gd, blk_dev.blk_cnt *
+		                         (blk_dev.blk_sz / KERNEL_SECTOR_SIZE));
+
+		/* Set it read-only or writeable */
+		if(!writeable)
+			set_disk_ro(blk_dev.gd, 1);
+
+		/* Make the block device available to the system */
+		add_disk(blk_dev.gd);
+		printk("Genode blk-file driver initialized\n");
+		return 0;
+}
+
+
+static void __exit
+genode_blk_exit(void)
+{
+		del_gendisk(blk_dev.gd);
+		put_disk(blk_dev.gd);
+		unregister_blkdev(blk_dev.gd->major, "genode_blk");
+		blk_cleanup_queue(blk_dev.queue);
+}
+
+module_init(genode_blk_init);
+module_exit(genode_blk_exit);
+
+MODULE_LICENSE("GPL");
diff -urNpB kernel-2.6.23-v2/arch/l4/drivers/genode_fb.c contrib/arch/l4/drivers/genode_fb.c
--- kernel-2.6.23-v2/arch/l4/drivers/genode_fb.c
+++ contrib/arch/l4/drivers/genode_fb.c
@@ -0,0 +1,511 @@
+/*
+ * \brief  Genode screen driver
+ * \author Stefan Kalkowski <kalkowski@genode-labs.com>
+ * \date   2010-04-20
+ *
+ * This driver enables usage of any of Genode's framebuffer, input
+ * and nitpicker sessions, as defined in Linux corresponding XML config stub.
+ * The implementation is based on virtual (vfb.c) and
+ * L4 (l4fb.c) framebuffer driver of L4Linux from TU-Dresden.
+ */
+
+/*
+ * Copyright (C) 2010-2012 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+/* Linux includes */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/proc_fs.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/screen_info.h>
+
+/* Platform includes */
+#include <asm/uaccess.h>
+
+/* Genode support lib includes */
+#include <genode/framebuffer.h>
+#include <genode/input.h>
+#include <oklx/ioctl.h>
+
+
+/**********************************
+ **  Datastructure declarations  **
+ **********************************/
+
+/**
+ * List of available framebuffers (used by device->driver_data)
+ */
+struct genodefb_infolist {
+	struct fb_info           *info;
+	struct genodefb_infolist *next;
+};
+
+
+/**********************
+ ** Global variables **
+ **********************/
+
+static const char GENODEFB_DRV_NAME[] = "genodefb";
+
+static struct fb_var_screeninfo genodefb_var __initdata = {
+	.activate       = FB_ACTIVATE_NOW,
+	.height         = -1,
+	.width          = -1,
+	.right_margin   = 32,
+	.upper_margin   = 16,
+	.lower_margin   = 4,
+	.vsync_len      = 4,
+	.vmode          = FB_VMODE_NONINTERLACED,
+	.bits_per_pixel = 16, // Genode only supports RGB565 by now */
+	.red.length     = 5,
+	.red.offset     = 11,
+	.green.length   = 6,
+	.green.offset   = 5,
+	.blue.length    = 5,
+	.blue.offset    = 0,
+	.transp.length  = 0,
+	.transp.offset  = 0,
+};
+
+static struct fb_fix_screeninfo genodefb_fix __initdata = {
+	.id        = "genode_fb",
+	.type      = FB_TYPE_PACKED_PIXELS,
+	.accel     = FB_ACCEL_NONE,
+	.visual    = FB_VISUAL_TRUECOLOR,
+	.ypanstep  = 0,
+	.ywrapstep = 0,
+};
+
+static u32 pseudo_palette[17];
+
+
+/*************************
+ **  Device operations  **
+ *************************/
+
+/*
+ *  Set a single color register. The values supplied are
+ *  already rounded down to the hardware's capabilities
+ *  (according to the entries in the `var' structure). Return
+ *  != 0 for invalid regno and pixel formats.
+ */
+static int genodefb_setcolreg(unsigned regno, unsigned red, unsigned green,
+                              unsigned blue, unsigned transp,
+                              struct fb_info *info)
+{
+	if (regno >= info->cmap.len || info->var.bits_per_pixel != 16)
+		return 1;
+
+	if (regno < 16)
+		((u32*) (info->pseudo_palette))[regno] =
+			((red   >> (16 -   info->var.red.length)) <<   info->var.red.offset) |
+			((green >> (16 - info->var.green.length)) << info->var.green.offset) |
+			((blue  >> (16 -  info->var.blue.length)) <<  info->var.blue.offset);
+	return 0;
+}
+
+
+/**
+ *  Pan or Wrap the Display
+ *
+ *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+ */
+static int genodefb_pan_display(struct fb_var_screeninfo *var,
+                                struct fb_info *info)
+{
+	if (var->vmode & FB_VMODE_YWRAP) {
+		if (var->yoffset < 0
+		    || var->yoffset >= info->var.yres_virtual
+		    || var->xoffset)
+			return -EINVAL;
+	} else {
+		if (var->xoffset + var->xres > info->var.xres_virtual ||
+		    var->yoffset + var->yres > info->var.yres_virtual)
+			return -EINVAL;
+	}
+	info->var.xoffset = var->xoffset;
+	info->var.yoffset = var->yoffset;
+	if (var->vmode & FB_VMODE_YWRAP)
+		info->var.vmode |= FB_VMODE_YWRAP;
+	else
+		info->var.vmode &= ~FB_VMODE_YWRAP;
+	return 0;
+}
+
+
+static void genodefb_copyarea(struct fb_info *info,
+                              const struct fb_copyarea *region)
+{
+	cfb_copyarea(info, region);
+	genode_fb_refresh(info->node, region->dx, region->dy,
+	                  region->width, region->height);
+}
+
+
+static void genodefb_fillrect(struct fb_info *info,
+                              const struct fb_fillrect *rect)
+{
+	cfb_fillrect(info, rect);
+	genode_fb_refresh(info->node, rect->dx, rect->dy,
+	                  rect->width, rect->height);
+}
+
+
+static void genodefb_imageblit(struct fb_info *info,
+                               const struct fb_image *image)
+{
+	cfb_imageblit(info, image);
+	genode_fb_refresh(info->node, image->dx, image->dy,
+	                  image->width, image->height);
+}
+
+
+static int genodefb_open(struct fb_info *info, int user)
+{
+	return 0;
+}
+
+
+static int genodefb_release(struct fb_info *info, int user)
+{
+	genode_nit_close_all_views(info->node);
+	return 0;
+}
+
+
+static int genodefb_ioctl(struct fb_info *info, unsigned int cmd,
+                          unsigned long arg)
+{
+	void __user *argp = (void __user *)arg;
+	switch (cmd) {
+	case NITPICKER_IOCTL_CREATE_VIEW:
+		{
+			genode_nit_view_create(info->node, (int)arg);
+			break;
+		}
+	case NITPICKER_IOCTL_DESTROY_VIEW:
+		{
+			genode_nit_view_destroy(info->node, (int)arg);
+			break;
+		}
+	case NITPICKER_IOCTL_BACK_VIEW:
+		{
+			genode_nit_view_back(info->node, (int)arg);
+			break;
+		}
+	case NITPICKER_IOCTL_PLACE_VIEW:
+		{
+			struct genode_view_place val;
+			if (copy_from_user(&val, argp, sizeof(val)))
+				return -EFAULT;
+			genode_nit_view_place(info->node, val.view, val.reg.x,
+			                      val.reg.y, val.reg.w, val.reg.h);
+			break;
+		}
+	case NITPICKER_IOCTL_STACK_VIEW:
+		{
+			struct genode_view_stack val;
+			if (copy_from_user(&val, argp, sizeof(val)))
+				return -EFAULT;
+			genode_nit_view_stack(info->node, val.view,
+			                      val.neighbor, val.behind);
+			break;
+		}
+	case FRAMEBUFFER_IOCTL_REFRESH:
+		{
+			struct genode_screen_region val;
+			if (copy_from_user(&val, argp, sizeof(val)))
+				return -EFAULT;
+			genode_fb_refresh(info->node, val.x, val.y, val.w, val.h);
+			break;
+		}
+	default:
+		printk(KERN_INFO "Unknown ioctl command: %d\n", cmd);
+	}
+	return 0;
+}
+
+
+static struct fb_ops genodefb_ops = {
+	.owner          = THIS_MODULE,
+	.fb_open        = genodefb_open,
+	.fb_release     = genodefb_release,
+	.fb_setcolreg   = genodefb_setcolreg,
+	.fb_pan_display = genodefb_pan_display,
+	.fb_fillrect    = genodefb_fillrect,
+	.fb_ioctl       = genodefb_ioctl,
+	.fb_copyarea    = genodefb_copyarea,
+	.fb_imageblit   = genodefb_imageblit,
+};
+
+
+/***********************
+ **  Input callbacks  **
+ ***********************/
+
+void input_event_callback (void *dev, unsigned int type,
+                           unsigned int code, int value)
+{
+	struct input_dev *input_dev = (struct input_dev*) dev;
+	input_event(input_dev, type, code, value);
+	input_sync(input_dev);
+}
+
+
+/***************************************
+ **  Device initialization / removal  **
+ ***************************************/
+
+static int __init genodefb_register_input_devices(unsigned int idx,
+                                                  unsigned int xres,
+                                                  unsigned int yres)
+{
+	int i;
+	struct input_dev *mouse_dev = input_allocate_device();
+	struct input_dev *keyb_dev  = input_allocate_device();
+	if (!keyb_dev || !mouse_dev)
+		return -ENOMEM;
+
+
+	/****************
+	 **  Keyboard  **
+	 ****************/
+
+	keyb_dev->name       = "Genode input key";
+	keyb_dev->phys       = "Genode fb key";
+	keyb_dev->id.bustype = BUS_USB;
+	keyb_dev->id.vendor  = 0;
+	keyb_dev->id.product = 0;
+	keyb_dev->id.version = 0;
+
+	/* We generate key events */
+	set_bit(EV_KEY, keyb_dev->evbit);
+	set_bit(EV_REP, keyb_dev->evbit);
+
+	/* We can generate every key */
+	for (i = 0; i < 0x100; i++)
+		set_bit(i, keyb_dev->keybit);
+
+	/* Register keyboard device */
+	input_register_device(keyb_dev);
+	genode_input_register_keyb(idx, (void*) keyb_dev);
+
+
+	/*************
+	 **  Mouse  **
+	 *************/
+
+	mouse_dev->name = "Genode input mouse";
+	mouse_dev->phys = "Genode mouse";
+	mouse_dev->id.bustype = BUS_USB;
+	mouse_dev->id.vendor  = 0;
+	mouse_dev->id.product = 0;
+	mouse_dev->id.version = 0;
+
+	/* We generate key and relative mouse events */
+	set_bit(EV_KEY, mouse_dev->evbit);
+	set_bit(EV_REP, mouse_dev->evbit);
+	set_bit(EV_REL, mouse_dev->evbit);
+	set_bit(EV_ABS, mouse_dev->evbit);
+
+	/* Buttons */
+	set_bit(BTN_0,      mouse_dev->keybit);
+	set_bit(BTN_1,      mouse_dev->keybit);
+	set_bit(BTN_2,      mouse_dev->keybit);
+	set_bit(BTN_3,      mouse_dev->keybit);
+	set_bit(BTN_4,      mouse_dev->keybit);
+	set_bit(BTN_LEFT,   mouse_dev->keybit);
+	set_bit(BTN_RIGHT,  mouse_dev->keybit);
+	set_bit(BTN_MIDDLE, mouse_dev->keybit);
+
+	/* Movements */
+	set_bit(REL_X, mouse_dev->relbit);
+	set_bit(REL_Y, mouse_dev->relbit);
+	set_bit(ABS_X, mouse_dev->absbit);
+	set_bit(ABS_Y, mouse_dev->absbit);
+
+	/* Coordinates are 1:1 pixel in frame buffer */
+	mouse_dev->absmax[ABS_X] = xres;
+	mouse_dev->absmax[ABS_Y] = yres;
+	mouse_dev->absmin[ABS_X] = 0;
+	mouse_dev->absmin[ABS_Y] = 0;
+
+	/* We are precise */
+	mouse_dev->absfuzz[ABS_X] = 0;
+	mouse_dev->absfuzz[ABS_Y] = 0;
+	mouse_dev->absflat[ABS_X] = 0;
+	mouse_dev->absflat[ABS_Y] = 0;
+
+	/* Register mouse device */
+	input_register_device(mouse_dev);
+	genode_input_register_mouse(idx, (void*) mouse_dev);
+	return 0;
+}
+
+
+static int __init genodefb_probe(struct platform_device *dev)
+{
+	struct genodefb_infolist *pred=0, *succ;
+	int i, ret, cnt = genode_screen_count();
+
+	/*
+	 * Iterate through all available framebuffers
+	 */
+	for (i=0; i < cnt; i++) {
+
+		/* Allocate new framebuffer list entry */
+		if(!(succ = kmalloc(sizeof(struct genodefb_infolist), GFP_KERNEL)))
+			return -ENOMEM;
+		succ->next = 0;
+
+		/* Set first entry as driver's private data, else concatenate it */
+		if (!i)
+			platform_set_drvdata(dev, succ);
+		else
+			pred->next = succ;
+		pred = succ;
+
+		/* Allocate new framebuffer info struct */
+		pred->info = framebuffer_alloc(0, &dev->dev);
+		if (!pred->info)
+			return -ENOMEM;
+
+		/* Copy default values */
+		pred->info->var = genodefb_var;
+		pred->info->fix = genodefb_fix;
+
+		/* Get framebuffer dimensions from Genode's support lib */
+		pred->info->screen_base    = genode_fb_attach(i);
+		pred->info->screen_size    = genode_fb_size(i);
+		pred->info->fix.smem_start = (unsigned long) pred->info->screen_base;
+		pred->info->fix.smem_len   = pred->info->screen_size;
+		if (!pred->info->screen_base || !pred->info->screen_size) {
+			printk(KERN_ERR "genode_fb: abort, could not be initialized.\n");
+			framebuffer_release(pred->info);
+			return -EIO;
+		}
+
+		/* Get framebuffer resolution from Genode's support lib */
+		genode_fb_info(i, &pred->info->var.xres, &pred->info->var.yres);
+
+		/* We only support 16-Bit Pixel, so line length is xres*2 */
+		pred->info->fix.line_length  = pred->info->var.xres * 2;
+
+		/* Set virtual resolution to visible resolution */
+		pred->info->var.xres_virtual = pred->info->var.xres;
+		pred->info->var.yres_virtual = pred->info->screen_size
+		                                / pred->info->fix.line_length;
+
+		/* Some dummy values for timing to make fbset happy */
+		pred->info->var.pixclock     = 10000000 / pred->info->var.xres
+		                               * 1000 / pred->info->var.yres;
+		pred->info->var.left_margin  = (pred->info->var.xres / 8) & 0xf8;
+		pred->info->var.hsync_len    = (pred->info->var.xres / 8) & 0xf8;
+
+		pred->info->fbops            = &genodefb_ops;
+		pred->info->pseudo_palette   = pseudo_palette;
+		pred->info->flags            = FBINFO_FLAG_DEFAULT;
+
+		printk(KERN_INFO "genode_fb:framebuffer at 0x%p, size %dk\n",
+		       pred->info->screen_base, (int)(pred->info->screen_size >> 10));
+		printk(KERN_INFO "genode_fb: mode is %dx%dx%d\n",
+		       pred->info->var.xres, pred->info->var.yres,
+		       pred->info->var.bits_per_pixel);
+
+		/* Allocate 16-Bit colormap */
+		ret = fb_alloc_cmap(&pred->info->cmap, 16, 0);
+		if (ret < 0) {
+			framebuffer_release(pred->info);
+			return ret;
+		}
+
+		/* Register framebuffer info structure */
+		if (register_framebuffer(pred->info) < 0) {
+			fb_dealloc_cmap(&pred->info->cmap);
+			framebuffer_release(pred->info);
+			return -EINVAL;
+		}
+
+		ret = genodefb_register_input_devices(i, pred->info->var.xres,
+		                                      pred->info->var.yres);
+		if (ret) {
+			fb_dealloc_cmap(&pred->info->cmap);
+			framebuffer_release(pred->info);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+
+static int genodefb_remove(struct platform_device *device)
+{
+	struct genodefb_infolist *succ = platform_get_drvdata(device);
+
+	while (succ && succ->info) {
+		struct genodefb_infolist *pred = succ;
+		succ = succ->next;
+		genode_fb_close(pred->info->node);
+		unregister_framebuffer(pred->info);
+		framebuffer_release(pred->info);
+		kfree(pred);
+	}
+	platform_set_drvdata(device, 0);
+	return 0;
+}
+
+
+/***************************************
+ **  Module initialization / removal  **
+ ***************************************/
+
+static struct platform_driver genodefb_driver = {
+	.probe       = genodefb_probe,
+	.remove      = genodefb_remove,
+	.driver.name = GENODEFB_DRV_NAME,
+};
+
+static struct platform_device genodefb_device = {
+	.name        = GENODEFB_DRV_NAME,
+};
+
+
+static int __init genodefb_init(void)
+{
+	int ret = platform_driver_register(&genodefb_driver);
+	if (!ret) {
+		ret = platform_device_register(&genodefb_device);
+		if (ret)
+			platform_driver_unregister(&genodefb_driver);
+	}
+	genode_input_register_callback(&input_event_callback);
+	return ret;
+}
+module_init(genodefb_init);
+
+
+static void __exit genodefb_exit(void)
+{
+	platform_device_unregister(&genodefb_device);
+	platform_driver_unregister(&genodefb_driver);
+	genode_input_unregister_callback();
+}
+module_exit(genodefb_exit);
+
+
+MODULE_AUTHOR("Stefan Kalkowski <stefan.kalkowski@genode-labs.com>");
+MODULE_DESCRIPTION("Frame buffer driver for OKLinux on Genode");
+MODULE_LICENSE("GPL v2");
diff -urNpB kernel-2.6.23-v2/arch/l4/drivers/genode_net.c contrib/arch/l4/drivers/genode_net.c
--- kernel-2.6.23-v2/arch/l4/drivers/genode_net.c
+++ contrib/arch/l4/drivers/genode_net.c
@@ -0,0 +1,165 @@
+/*
+ * \brief  NIC driver to access Genode's nic service
+ * \author Stefan Kalkowski <stefan.kalkowski@genode-labs.com>
+ * \date   2010-09-09
+ */
+
+/*
+ * Copyright (C) 2006-2012 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+/* Linux includes */
+#include <linux/etherdevice.h>
+#include <linux/errno.h>
+#include <linux/inet.h>
+#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <genode/net.h>
+
+static struct net_device *net_dev;
+
+
+static void genode_net_receive_packet(void* dev_addr, void *addr,
+                                      unsigned long size)
+{
+	struct net_device       *dev   = (struct net_device *) dev_addr;
+	struct net_device_stats *stats = (struct net_device_stats*) netdev_priv(dev);
+
+	/* allocate skb */
+	struct sk_buff *skb = dev_alloc_skb(size + 2);
+	if (!skb) {
+		if (printk_ratelimit())
+			printk(KERN_NOTICE "genode_net_rx: low on mem - packet dropped!\n");
+		stats->rx_dropped++;
+		return;
+	}
+
+	/* copy packet */
+	memcpy(skb_put(skb, size), addr, size);
+
+	skb->dev       = dev;
+	skb->protocol  = eth_type_trans(skb, dev);
+	skb->ip_summed = CHECKSUM_NONE;
+	netif_rx(skb);
+
+	stats->rx_packets++;
+	stats->rx_bytes += size;
+}
+
+
+/********************************
+ **  Network driver functions  **
+ ********************************/
+
+int genode_net_open(struct net_device *dev)
+{
+	genode_net_start(dev, genode_net_receive_packet);
+	netif_start_queue(dev);
+	return 0;
+}
+
+
+int genode_net_close(struct net_device *dev)
+{
+	netif_stop_queue(dev);
+	genode_net_stop();
+	return 0;
+}
+
+
+int genode_net_xmit_frame(struct sk_buff *skb, struct net_device *dev)
+{
+	struct net_device_stats *stats = (struct net_device_stats*) netdev_priv(dev);
+	int len                        = skb->len;
+	void* addr                     = skb->data;
+
+	/* collect acknowledgements of old packets */
+	while (genode_net_tx_ack_avail())
+		dev_kfree_skb((struct sk_buff *)genode_net_tx_ack());
+
+	/* transmit to nic-session */
+	if (genode_net_tx(addr, len, skb)) {
+		/* tx queue is full, could not enqueue packet */
+		netif_stop_queue(dev);
+		return 1;
+	}
+
+	/* save timestamp */
+	dev->trans_start = jiffies;
+
+	stats->tx_packets++;
+	stats->tx_bytes += len;
+	return 0;
+}
+
+
+struct net_device_stats* genode_net_get_stats(struct net_device *dev)
+{
+	return (struct net_device_stats*) netdev_priv(dev);
+}
+
+
+void genode_net_tx_timeout(struct net_device *dev)
+{
+}
+
+
+/**************************
+ **  De-/Initialization  **
+ **************************/
+
+/* Setup and register the device. */
+static int __init genode_net_init(void)
+{
+	int err = 0;
+
+	if (!genode_net_ready())
+		return 0;
+
+	/* allocate network device */
+	if (!(net_dev = alloc_etherdev(sizeof(struct net_device_stats))))
+		goto out;
+
+	net_dev->open            = genode_net_open;
+	net_dev->stop            = genode_net_close;
+	net_dev->hard_start_xmit = genode_net_xmit_frame;
+	net_dev->get_stats       = genode_net_get_stats;
+	net_dev->tx_timeout      = genode_net_tx_timeout;
+	net_dev->watchdog_timeo  = 20 * HZ;
+
+	/* set MAC address */
+	genode_net_mac(net_dev->dev_addr, ETH_ALEN);
+
+	/* register network device */
+	if ((err = register_netdev(net_dev))) {
+		panic("loopback: Failed to register netdevice: %d\n", err);
+		goto out_free;
+	}
+
+	return 0;
+
+out_free:
+	free_netdev(net_dev);
+out:
+	return err;
+};
+
+
+static void __exit genode_net_exit(void)
+{
+	unregister_netdev(net_dev);
+	free_netdev(net_dev);
+}
+
+
+module_init(genode_net_init);
+module_exit(genode_net_exit);
diff -urNpB kernel-2.6.23-v2/arch/l4/drivers/l4kdb_console.c contrib/arch/l4/drivers/l4kdb_console.c
--- kernel-2.6.23-v2/arch/l4/drivers/l4kdb_console.c
+++ contrib/arch/l4/drivers/l4kdb_console.c
@@ -4,28 +4,25 @@
 
 #include <l4/kdebug.h>
 
+#include <genode/printf.h>
+
 static void l4kdb_cons_write(struct console *co, const char *p, unsigned count)
 {
-	while (count-- > 0) {
-		L4_KDB_PrintChar(*p++);
-	}
+	char buf[count+1];
+	int i;
+	for(i=0; i<count; ++i)
+		buf[i]=p[i];
+	buf[i]=0;
+	genode_printf(buf);
 }
 
 static struct console l4kdb_cons = {
-	.name	    = "l4con",
+	.name	    = "ttyKDB",
 	.write	    = l4kdb_cons_write,
 	.flags	    = CON_PRINTBUFFER,
 	.index	    = -1,
 };
 
-static int __init l4kdb_console_init(void)
-{
-	register_console(&l4kdb_cons);
-	return 0;
-}
-
-console_initcall(l4kdb_console_init);
-
 #ifdef CONFIG_EARLY_PRINTK
 void
 enable_early_printk(void)
@@ -38,5 +35,16 @@ disable_early_printk(void)
 {
 	unregister_console(&l4kdb_cons);
 }
+
+#else
+
+static int __init l4kdb_console_init(void)
+{
+	register_console(&l4kdb_cons);
+	return 0;
+}
+
+console_initcall(l4kdb_console_init);
+
 #endif
 
diff -urNpB kernel-2.6.23-v2/arch/l4/include/wombat.h contrib/arch/l4/include/wombat.h
--- kernel-2.6.23-v2/arch/l4/include/wombat.h
+++ contrib/arch/l4/include/wombat.h
@@ -2,7 +2,7 @@
 #include <linux/mm.h>
 #include <asm/mmzone.h>
 
-#define STACK_SIZE 0x2000
+#define STACK_SIZE 0x4000
 
 extern cap_t *first_cap;
 extern bootmem_area_t bootmem_area[MAX_PHYSMEM_RANGES];
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/Makefile contrib/arch/l4/kernel/Makefile
--- kernel-2.6.23-v2/arch/l4/kernel/Makefile
+++ contrib/arch/l4/kernel/Makefile
@@ -3,7 +3,11 @@ core-y += arch/l4/kernel/fs/
 obj-y := reboot.o glue.o main.o init_task.o time.o memcpy_user.o \
 	syscalls.o proc.o process.o syscall_impl.o setup.o \
 	signal.o sys_iguana.o cache.o exit.o syscall_loop.o \
-	mmap.o irq.o intervm_loop.o
+	mmap.o irq.o intervm_loop.o calibrate.o
+
+# Genode specific
+obj-y := $(filter-out intervm_loop.o sys_iguana.o,$(obj-y))
+obj-y += sys_genode.o
 
 obj-$(CONFIG_MODULES)	+= syms.o
 obj-$(CONFIG_ARCH_ARM)  += memcpy_user_armshared.o
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/calibrate.c contrib/arch/l4/kernel/calibrate.c
--- kernel-2.6.23-v2/arch/l4/kernel/calibrate.c
+++ contrib/arch/l4/kernel/calibrate.c
@@ -0,0 +1,179 @@
+/* calibrate.c: default delay calibration
+ *
+ * Excised from init/main.c
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <asm/timex.h>
+
+#include <genode/lock.h>
+
+extern void* timer_main_kernel_lock;
+
+static unsigned long preset_lpj;
+static int __init lpj_setup(char *str)
+{
+	preset_lpj = simple_strtoul(str,NULL,0);
+	return 1;
+}
+
+__setup("lpj=", lpj_setup);
+
+#ifdef ARCH_HAS_READ_CURRENT_TIMER
+
+/* This routine uses the read_current_timer() routine and gets the
+ * loops per jiffy directly, instead of guessing it using delay().
+ * Also, this code tries to handle non-maskable asynchronous events
+ * (like SMIs)
+ */
+#define DELAY_CALIBRATION_TICKS			((HZ < 100) ? 1 : (HZ/100))
+#define MAX_DIRECT_CALIBRATION_RETRIES		5
+
+static unsigned long __devinit calibrate_delay_direct(void)
+{
+	unsigned long pre_start, start, post_start;
+	unsigned long pre_end, end, post_end;
+	unsigned long start_jiffies;
+	unsigned long tsc_rate_min, tsc_rate_max;
+	unsigned long good_tsc_sum = 0;
+	unsigned long good_tsc_count = 0;
+	int i;
+
+	if (read_current_timer(&pre_start) < 0 )
+		return 0;
+
+	/*
+	 * A simple loop like
+	 *	while ( jiffies < start_jiffies+1)
+	 *		start = read_current_timer();
+	 * will not do. As we don't really know whether jiffy switch
+	 * happened first or timer_value was read first. And some asynchronous
+	 * event can happen between these two events introducing errors in lpj.
+	 *
+	 * So, we do
+	 * 1. pre_start <- When we are sure that jiffy switch hasn't happened
+	 * 2. check jiffy switch
+	 * 3. start <- timer value before or after jiffy switch
+	 * 4. post_start <- When we are sure that jiffy switch has happened
+	 *
+	 * Note, we don't know anything about order of 2 and 3.
+	 * Now, by looking at post_start and pre_start difference, we can
+	 * check whether any asynchronous event happened or not
+	 */
+
+	for (i = 0; i < MAX_DIRECT_CALIBRATION_RETRIES; i++) {
+		pre_start = 0;
+		read_current_timer(&start);
+		start_jiffies = jiffies;
+		while (jiffies <= (start_jiffies + 1)) {
+			pre_start = start;
+			read_current_timer(&start);
+		}
+		read_current_timer(&post_start);
+
+		pre_end = 0;
+		end = post_start;
+		while (jiffies <=
+		       (start_jiffies + 1 + DELAY_CALIBRATION_TICKS)) {
+			pre_end = end;
+			read_current_timer(&end);
+		}
+		read_current_timer(&post_end);
+
+		tsc_rate_max = (post_end - pre_start) / DELAY_CALIBRATION_TICKS;
+		tsc_rate_min = (pre_end - post_start) / DELAY_CALIBRATION_TICKS;
+
+		/*
+	 	 * If the upper limit and lower limit of the tsc_rate is
+		 * >= 12.5% apart, redo calibration.
+		 */
+		if (pre_start != 0 && pre_end != 0 &&
+		    (tsc_rate_max - tsc_rate_min) < (tsc_rate_max >> 3)) {
+			good_tsc_count++;
+			good_tsc_sum += tsc_rate_max;
+		}
+	}
+
+	if (good_tsc_count)
+		return (good_tsc_sum/good_tsc_count);
+
+	printk(KERN_WARNING "calibrate_delay_direct() failed to get a good "
+	       "estimate for loops_per_jiffy.\nProbably due to long platform interrupts. Consider using \"lpj=\" boot option.\n");
+	return 0;
+}
+#else
+static unsigned long __devinit calibrate_delay_direct(void) {return 0;}
+#endif
+
+/*
+ * This is the number of bits of precision for the loops_per_jiffy.  Each
+ * bit takes on average 1.5/HZ seconds.  This (like the original) is a little
+ * better than 1%
+ */
+#define LPS_PREC 8
+
+void __devinit calibrate_delay(void)
+{
+	unsigned long ticks, loopbit;
+	int lps_precision = LPS_PREC;
+
+	genode_unlock(timer_main_kernel_lock);
+
+	if (preset_lpj) {
+		loops_per_jiffy = preset_lpj;
+		printk("Calibrating delay loop (skipped)... "
+			"%lu.%02lu BogoMIPS preset\n",
+			loops_per_jiffy/(500000/HZ),
+			(loops_per_jiffy/(5000/HZ)) % 100);
+	} else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) {
+		printk("Calibrating delay using timer specific routine.. ");
+		printk("%lu.%02lu BogoMIPS (lpj=%lu)\n",
+			loops_per_jiffy/(500000/HZ),
+			(loops_per_jiffy/(5000/HZ)) % 100,
+			loops_per_jiffy);
+	} else {
+		loops_per_jiffy = (1<<12);
+
+		printk(KERN_DEBUG "Calibrating delay loop... ");
+		while ((loops_per_jiffy <<= 1) != 0) {
+			/* wait for "start of" clock tick */
+			ticks = jiffies;
+			while (ticks == jiffies)
+				/* nothing */;
+			/* Go .. */
+			ticks = jiffies;
+			__delay(loops_per_jiffy);
+			ticks = jiffies - ticks;
+			if (ticks)
+				break;
+		}
+
+		/*
+		 * Do a binary approximation to get loops_per_jiffy set to
+		 * equal one clock (up to lps_precision bits)
+		 */
+		loops_per_jiffy >>= 1;
+		loopbit = loops_per_jiffy;
+		while (lps_precision-- && (loopbit >>= 1)) {
+			loops_per_jiffy |= loopbit;
+			ticks = jiffies;
+			while (ticks == jiffies)
+				/* nothing */;
+			ticks = jiffies;
+			__delay(loops_per_jiffy);
+			if (jiffies != ticks)	/* longer than 1 tick */
+				loops_per_jiffy &= ~loopbit;
+		}
+
+		/* Round the value and print it */
+		printk("%lu.%02lu BogoMIPS (lpj=%lu)\n",
+			loops_per_jiffy/(500000/HZ),
+			(loops_per_jiffy/(5000/HZ)) % 100,
+			loops_per_jiffy);
+	}
+	genode_lock(timer_main_kernel_lock);
+}
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/exit.c contrib/arch/l4/kernel/exit.c
--- kernel-2.6.23-v2/arch/l4/kernel/exit.c
+++ contrib/arch/l4/kernel/exit.c
@@ -9,7 +9,7 @@
 #include <linux/kernel.h>
 
 #include <assert.h>
-#include <iguana/pd.h>
+#include <genode/exit.h>
 
 /*
  * Called when Linux startup fails / exit server
@@ -18,10 +18,8 @@
 void
 _Exit(int status)
 {
-	pd_delete(pd_myself());
-
-	assert(!"We have exitted -- sholdn't reach here");
-	while(1);
+	genode_exit(status);
+	while(1) ;
 }
 
 void __div0(void)
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/fs/okl4fs/inode.c contrib/arch/l4/kernel/fs/okl4fs/inode.c
--- kernel-2.6.23-v2/arch/l4/kernel/fs/okl4fs/inode.c
+++ contrib/arch/l4/kernel/fs/okl4fs/inode.c
@@ -17,8 +17,8 @@
 #include <unistd.h>
 #include "internal.h"
 
-#include <iguana/env.h>
-#include <iguana/memsection.h>
+//#include <iguana/env.h>
+//#include <iguana/memsection.h>
 
 #include <l4/kdebug.h>
 
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/glue.c contrib/arch/l4/kernel/glue.c
--- kernel-2.6.23-v2/arch/l4/kernel/glue.c
+++ contrib/arch/l4/kernel/glue.c
@@ -4,9 +4,12 @@
 #include <linux/syscalls.h>
 #include <linux/string.h>
 
+#include <linux/pagemap.h>  /* needed by 'asm/tlb.h' */
+
 #define __KERNEL_SYSCALLS__
 
-#include <asm/unistd.h>	/* execve */
+#include <asm/unistd.h>  /* execve */
+#include <asm/tlb.h>     /* 'struct mmu_gather' */
 
 int
 kernel_execve(const char *filename, char *const argv[], char *const envp[])
@@ -40,7 +43,8 @@ const char *get_system_type(void)
 	return "L4 Default arch";
 }
 
-void per_cpu__mmu_gathers (void) { printk("per_cpu__mmu_gathers called\n"); } 
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+
 void ptrace_disable (void) { printk("ptrace_disable called\n"); } 
 //void search_extable (void) { printk("search_extable called\n"); } 
 void show_stack(struct task_struct *task, unsigned long *sp) { printk("show_stack called\n"); }
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/irq.c contrib/arch/l4/kernel/irq.c
--- kernel-2.6.23-v2/arch/l4/kernel/irq.c
+++ contrib/arch/l4/kernel/irq.c
@@ -78,12 +78,12 @@ show_interrupts(struct seq_file *p, void
 #endif
 		seq_printf(p, " %14s", irq_desc[i].chip->name);
 		seq_printf(p, "  %c%s",
-			(action->flags & SA_INTERRUPT)?'+':' ',
+			(action->flags & IRQF_DISABLED)?'+':' ',
 			action->name);
 
 		for (action=action->next; action; action = action->next) {
 			seq_printf(p, ", %c%s",
-				  (action->flags & SA_INTERRUPT)?'+':' ',
+				  (action->flags & IRQF_DISABLED)?'+':' ',
 				   action->name);
 		}
 
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/main.c contrib/arch/l4/kernel/main.c
--- kernel-2.6.23-v2/arch/l4/kernel/main.c
+++ contrib/arch/l4/kernel/main.c
@@ -24,12 +24,13 @@
 #include <asm/setup.h>
 
 #include <iguana/thread.h>
-#include <iguana/cap.h>
 #include <iguana/memsection.h>
 #include <iguana/tls.h>
-#include <iguana/env.h>
 
-void *__callback_buffer;
+#include <genode/memory.h>
+#include <genode/sleep.h>
+#include <genode/config.h>
+#include <genode/lock.h>
 
 uintptr_t temp_cap_slot;
 uintptr_t temp_cap_used;
@@ -39,17 +40,20 @@ uintptr_t temp_cap_addr;
 uintptr_t dma_heap_base, dma_heap_phys_base;
 
 static uintptr_t main_stack[STACK_SIZE];
-static uintptr_t intervm_stack[STACK_SIZE];
+static uintptr_t timer_stack[STACK_SIZE];
+
+void* timer_main_kernel_lock;
 
 extern void interrupt_loop(void);
 
 void *main_tls_area[KERNEL_THREADS][32];
 
 extern void start_kernel(void);
-extern void intervm_loop(void);
 
 void *console_out, *console_in;
 
+extern void enable_early_printk(void);
+
 /* Our per cpu irq enable/disable. Where should this go? */
 DEFINE_PER_CPU(irq_info_t, _l4_irq_state) = { 0 };
 EXPORT_PER_CPU_SYMBOL(_l4_irq_state);
@@ -59,7 +63,6 @@ L4_Word_t start_phys_mem, end_phys_mem;
 L4_ThreadId_t main_thread;
 L4_ThreadId_t timer_thread;
 L4_ThreadId_t timer_handle;
-L4_ThreadId_t intervm_thread;
 
 unsigned long get_instr(unsigned long addr)
 {
@@ -96,67 +99,13 @@ unsigned long set_instr(unsigned long ad
 	return 0;
 }
 
-/*
-Malloc
-*/
-void *
-malloc(size_t size)
-{
-	void *ret;
-	//printk("malloc: %d\n", (int)size);
-	ret = kmalloc(size, GFP_ATOMIC);
-	//printk("malloc returned: %p\n", ret);
-	return ret;
-}
-
-void *
-calloc(size_t nmemb, size_t size)
-{
-	printk("calloc called\n");
-	return NULL;
-}
-
-void
-free(void *ptr)
-{
-	return kfree(ptr);
-}
-
-int
-puts(const char *format)
-{
-	printk("puts called\n");
-	return 0;
-}
-
-int
-printf(const char *format, ...)
-{
-	printk("printf\n");
-	return 0;
-//	return printk(format);
-}
-
 
-
-void 
-__linux_cap_init(uintptr_t cap_slot, uintptr_t cap_used, uintptr_t cap_size, uintptr_t cap_addr)
-{
-//	temp_cap_slot = cap_slot;
-//	temp_cap_used = cap_used;
-//	temp_cap_size = cap_size;
-//	temp_cap_addr = cap_addr;
-//	first_cap = (cap_t*) cap_addr;
-}
-
-
-void
-__libc_setup(void *callback, void *stdin_p, void *stdout_p, void *stderr_p, 
-	     unsigned long heap_base, unsigned long heap_end)
+void __init
+__libc_setup(void *stdin_p, void *stdout_p, void *stderr_p,
+			 unsigned long heap_base, unsigned long heap_end)
 {
 	console_out = stdout_p;
 	console_in = stdin_p;
-	__callback_buffer = callback;
 
 	/* Setup the memory areas from iguana */
 	assert(heap_end > heap_base);
@@ -165,106 +114,96 @@ __libc_setup(void *callback, void *stdin
 	bootmem_area[0].pages = (heap_end >> PAGE_SHIFT) - bootmem_area[0].page_base;
 }
 
-void
-__lib_init(uintptr_t *buf)
+void __init __lib_init(void)
 {
-	void* callback;
-	void* stdin_p;
-	void* stdout_p;
-	void* stderr_p;
 	char* heap_base;
 	size_t heap_size;
 	uint32_t dma_size;
 
-	__lib_iguana_init(buf);
-
-    callback  = env_memsection_base(iguana_getenv("__OKL4_CALLBACK_BUFFER"));
-    stdin_p   = NULL; //env_memsection_base(iguana_getenv("OKL4_SERIAL_SERVER"));
-    stdout_p  = NULL; //env_memsection_base(iguana_getenv("OKL4_SERIAL_SERVER"));
-    stderr_p  = NULL; //env_memsection_base(iguana_getenv("OKL4_SERIAL_SERVER"));
-    heap_base = (char*) env_const(iguana_getenv("HEAP_BASE"));
-    heap_size = env_const(iguana_getenv("HEAP_SIZE"));
-
-
-	__libc_setup(callback, stdin_p, stdout_p, stderr_p,
-		     (unsigned long) heap_base,
-                     (unsigned long) (heap_base + heap_size - 1));
-         __cap_init();
-
-//	__linux_cap_init((uintptr_t) iguana_getenv(IGUANA_GETENV_CLIST_SLOT),
-//			 (uintptr_t) iguana_getenv(IGUANA_GETENV_CLIST_USED),
-//			 CLIST_MEMORY_SIZE / sizeof(cap_t),
-//			 (uintptr_t) iguana_getenv(IGUANA_GETENV_CLIST_BASE));
-//
+	heap_size = genode_quota() - genode_used_mem()
+	            - 8*1024*1024; // Leave some memory left for dynamic allocations
+	heap_base = genode_malloc(heap_size);
+	__libc_setup(0, 0, 0, (unsigned long) heap_base,
+				 (unsigned long) (heap_base + heap_size - 1));
 	dma_heap_base = (uint32_t)heap_base;
 	dma_heap_phys_base = memsection_virt_to_phys((uintptr_t)heap_base,
-	    &dma_size);
+												 &dma_size);
 }
 
-
-void __sys_entry(void *buf, int argc, char** argv);
 void _Exit(int status);
 
 int main(int argc, char** argv);
+void __sys_entry(void *buf, int argc, char** argv){}
 
-/* This is the entry point from the C libraries crt0 */
-void
-__sys_entry(void *buf, int argc, char** argv)
+void setup_tls(int thread_num)
 {
-	int result;
-	__lib_init(buf);
-	/* Start Linux */
-	result = main(argc, argv);
-	/* Exit Linux Server */
-	_Exit(result);
 }
 
-void
-setup_tls(int thread_num)
+void __init start_main_thread(void)
 {
-	__tls_init(main_tls_area[thread_num]);
+	/* Set me as the pager for every user process started by Linux */
+	genode_set_pager();
+	genode_lock(timer_main_kernel_lock);
+
+#ifdef CONFIG_EARLY_PRINTK
+	/* early console initialisation */
+	enable_early_printk();
+#endif
+
+	start_kernel();
 }
 
-int
-main(int argc, char **argv)
+void __init start_timer_thread(void)
 {
-	int r;
-	/* Start a new thread */
-	assert(argc > 0 && argv[0] != NULL);
-	
-	strlcpy(boot_command_line, argv[1], COMMAND_LINE_SIZE);
-	L4_KDB_SetThreadName(L4_myselfconst, "L_timer");
-	
+	/* Create main kernel thread, doing paging, syscalls etc. */
 	thread_create(&main_thread);
-	r  = L4_Set_Priority(main_thread, 99);
-	assert (r != 0);
-
-	timer_thread = thread_l4tid(env_thread(iguana_getenv("MAIN")));
 	L4_KDB_SetThreadName(main_thread, "L_syscall");
 
 	/* Setup our TLS as well */
-	setup_tls(TIMER_THREAD);
-
-    thread_create(&intervm_thread);
-    r = L4_Set_Priority(intervm_thread, 98);
-    assert(r != 0);
-    L4_KDB_SetThreadName(intervm_thread, "L_intervm");
+	__tls_init(main_tls_area[TIMER_THREAD]);
 
 	/* Thread info setup. */
 	/* FIXME:  remember for SMP startup */
-	current_tinfo(smp_processor_id()) = (unsigned long)&init_thread_union.thread_info;
+	current_tinfo(smp_processor_id()) =
+		(unsigned long)&init_thread_union.thread_info;
 	current_thread_info()->user_tid = L4_nilthread;
 	current_thread_info()->user_handle = L4_nilthread;
 
+	/* Start linux main thread */
 	L4_Start_SpIp(main_thread,
-		      (L4_Word_t) &main_stack[STACK_SIZE-1],
-		      (L4_Word_t) start_kernel);
-    
-    L4_Start_SpIp(intervm_thread,
-              (L4_Word_t) &intervm_stack[STACK_SIZE-1],
-              (L4_Word_t) intervm_loop);
+				  (L4_Word_t) &main_stack[STACK_SIZE-1],
+				  (L4_Word_t) start_main_thread);
 
-	/* Now we go and do the timer stuff */
+	/* Now we go and do the timer/IRQ stuff */
 	interrupt_loop();
+}
+
+int __init
+main(int argc, char **argv)
+{
+	char* cmdline = genode_config_cmdline();
+
+	/* Do init stuff, especially get memory */
+	__lib_init();
+
+	/* Copy kernel commandline from the XML config */
+	if (cmdline)
+		memcpy(boot_command_line, cmdline,
+			   min_t(size_t, COMMAND_LINE_SIZE,
+					 sizeof(char)*strlen(cmdline)));
+
+	/* Create timer thread, which provides so to say timer interrupts */
+	thread_create(&timer_thread);
+	L4_KDB_SetThreadName(timer_thread, "L_timer");
+
+	timer_main_kernel_lock = genode_alloc_lock();
+
+	/* Start timer thread */
+	L4_Start_SpIp(timer_thread,
+				  (L4_Word_t) &timer_stack[STACK_SIZE-1],
+				  (L4_Word_t) start_timer_thread);
+
+	/* Now, work is done, lets go sleeping */
+	genode_sleep_forever();
 	return 0;
 }
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/process.c contrib/arch/l4/kernel/process.c
--- kernel-2.6.23-v2/arch/l4/kernel/process.c
+++ contrib/arch/l4/kernel/process.c
@@ -23,6 +23,10 @@
 #include <iguana/eas.h>
 #include <iguana/thread.h>
 
+#include <genode/lock.h>
+
+extern void* timer_main_kernel_lock;
+
 extern void NORET_TYPE syscall_loop (void);
 static void new_thread_handler(struct thread_info *prev);
 static void new_process_handler(struct thread_info *prev);
@@ -144,7 +148,7 @@ __execve(char *file, char **argv, char *
 void
 cpu_idle (void)
 {
-	int r;
+	//int r;
 
 	/* Idle thread has special user_tid so we can identify it */
 	current_thread_info()->user_tid = L4_anythread;
@@ -152,25 +156,17 @@ cpu_idle (void)
 
 	//printk("Starting idle loop (%lx)\n", L4_Myself().raw); XXX: L4_Myself() is no longer valid - nt
 
-	r  = L4_Set_Priority(L4_myselfconst, 99);
-	if (r == 0) {
-		printk("Failed: %lx\n", L4_ErrorCode());
-	}
-	assert(r != 0);
-
 	atomic_inc(&init_mm.mm_count);
 	current->mm = &init_mm;
 	current->active_mm = &init_mm;
 
 	while (1) {
-		while (!need_resched())
-		{
-			/* Wait on timer_thread */
-			if (!need_resched()){
-				L4_Receive(timer_thread);
-			}
+		while (!need_resched()){
+			genode_unlock(timer_main_kernel_lock);
+			L4_Receive(timer_thread);
+			genode_lock(timer_main_kernel_lock);
+
 		}
-		//printk("!");
 		schedule();
 	}
 }
@@ -187,7 +183,7 @@ copy_thread(int nr, unsigned long clone_
 	    unsigned long unused,  struct task_struct * p, 
 	    struct pt_regs * regs)
 {
-	int r = 0;
+	//int r = 0;
 	//printk("%s %d %lx usp=%lx, task=%p, regs=%p\n", __func__, nr, clone_flags, usp, p, regs);
 
 	if ((task_thread_info(p)->request.op != OP_KTHREAD) &&
@@ -222,9 +218,6 @@ copy_thread(int nr, unsigned long clone_
 			    name);
 		}
 
-		r  = L4_Set_Priority(task_thread_info(p)->user_tid, 98);
-		assert(r != 0);
-
 		L4_Copy_regs (current_thread_info()->user_tid,
 				   task_thread_info(p)->user_tid);
 
@@ -308,7 +301,7 @@ start_thread(struct pt_regs * regs, unsi
 	//printk("%s current = %p  pc = %lx, sp = %lx\n", __func__, current, pc, sp);
 
 	if (current_thread_info()->user_tid.raw == L4_nilthread.raw) {
-		int r;
+		//int r;
 		void * utcb;
 
 		if (utcb_area.raw == L4_Nilpage.raw)
@@ -328,8 +321,7 @@ start_thread(struct pt_regs * regs, unsi
 				utcb, &handle);
 
 		assert(thrd.raw != 0);
-		r  = L4_Set_Priority(thrd, 98);
-		assert(r != 0);
+
 		/*
 		 * This will be disabled in libl4 with NDEBUG set, so it's OK.
 		 */
@@ -352,7 +344,8 @@ start_thread(struct pt_regs * regs, unsi
 //	syscall_exit(1);
 
 	set_need_restart(current_thread_info(), pc, sp, 0);
-	L4_AbortIpc_and_stop_Thread(thrd);
+	//L4_AbortIpc_and_stop_Thread(thrd);
+	L4_Stop(thrd);
 	set_user_ipc_cancelled(current_thread_info());
 
 	/* Setup which messages we will recieve */
@@ -385,6 +378,29 @@ __switch_to(struct task_struct *prev, st
 		/* XXX - is the race from here to the switch important? */
 		current_tinfo(smp_processor_id()) = (unsigned long)next_info;
 
+		/* Suspend running thread */
+		if(prev_info->user_tid.raw != 0)
+		{
+			L4_Word_t dummy;
+			L4_ThreadId_t dummy_id;
+			L4_ExchangeRegisters(prev_info->user_tid,
+								 L4_ExReg_Halt + L4_ExReg_AbortSendIPC,
+								 0, 0, 0,
+								 0, L4_nilthread, &dummy, &dummy, &dummy,
+								 &dummy, &dummy, &dummy_id);
+		}
+
+		/* Resume scheduled thread */
+		if(next_info->user_tid.raw != 0)
+		{
+			L4_Word_t dummy;
+			L4_ThreadId_t dummy_id;
+			L4_ExchangeRegisters(next_info->user_tid,
+								 L4_ExReg_Resume, 0, 0, 0,
+								 0, L4_nilthread, &dummy, &dummy, &dummy,
+								 &dummy, &dummy, &dummy_id);
+		}
+
 		prev_info = arch_switch(prev_info, next_info);
 		mb();
 	} else {
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/setup.c contrib/arch/l4/kernel/setup.c
--- kernel-2.6.23-v2/arch/l4/kernel/setup.c
+++ contrib/arch/l4/kernel/setup.c
@@ -14,8 +14,6 @@
 #include <asm/tlbflush.h>
 #include <asm/setup.h>
 
-#include <iguana/memsection.h>
-#include <iguana/cap.h>
 #include <iguana/thread.h>
 
 #ifdef CONFIG_VT
@@ -25,7 +23,9 @@
 #include <linux/screen_info.h>
 #include <asm/io.h>
 
-#include <iguana/env.h>
+#include <genode/config.h>
+#include <genode/open.h>
+
 unsigned long VGA_offset;
 
 struct screen_info screen_info = {
@@ -52,15 +52,16 @@ struct screen_info screen_info = {
 	.orig_video_points	= 16
 }; 
 #define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM)
-static struct resource video_ram_resource = { 
-	.name = "Video RAM area", 
-	.start = 0xa0000, 
-	.end 0xbffff, 
-	.flags = IORESOURCE_RAM
-};
+/* static struct resource video_ram_resource = {  */
+/* 	.name = "Video RAM area",  */
+/* 	.start = 0xa0000,  */
+/* 	.end = 0xbffff,  */
+/* 	.flags = IORESOURCE_RAM */
+/* }; */
 
 void __init __setup_vga(void)
 {
+	/*
 	char* vga_obj;
         envitem_t *ig_ref;
 
@@ -72,7 +73,7 @@ void __init __setup_vga(void)
 
 	VGA_offset = (unsigned long)vga_obj - video_ram_resource.start;
 	request_resource(&iomem_resource, &video_ram_resource);
-
+	*/
 }
 
 
@@ -91,8 +92,6 @@ L4_Fpage_t utcb_area;
 extern unsigned long start_phys_mem, end_phys_mem;
 extern void * __rd_start, * __rd_end;
 
-extern void enable_early_printk(void);
-
 void __init
 setup_machine_name(void)
 {
@@ -112,7 +111,7 @@ void __init
 setup_arch (char **command_line) 
 { 
 	unsigned long base, area;
-
+	char* initrd_name;
 	setup_tls(1);
 
 	/* Return the command line to the rest of the kernel */
@@ -156,19 +155,19 @@ setup_arch (char **command_line)
 	task_thread_info(current)->user_tid = L4_nilthread;
 	task_thread_info(current)->user_handle = L4_nilthread;
 
-#ifdef CONFIG_EARLY_PRINTK
-	/* early console initialisation */
-	enable_early_printk();
-#endif
-
 	/* Ramdisk setup */
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* Board specific code should have set up initrd_start and initrd_end */
 	ROOT_DEV = Root_RAM0;
         /* FIXME! */
-	initrd_start = 0; //naming_lookup("ramdisk");
-	initrd_end = 0; //naming_lookup("ramdisk_end");
-	printk("end: %lx\n", initrd_end);
+	initrd_name = genode_config_initrd();
+	if(initrd_name) {
+		initrd_start = (unsigned long) genode_open(initrd_name, &initrd_end);
+		initrd_end   = initrd_start + initrd_end;
+	} else {
+		initrd_start = 0;
+		initrd_end   = 0;
+	}
 	initrd_below_start_ok = 1;
 
 	if (initrd_start) {
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/sys_genode.c contrib/arch/l4/kernel/sys_genode.c
--- kernel-2.6.23-v2/arch/l4/kernel/sys_genode.c
+++ contrib/arch/l4/kernel/sys_genode.c
@@ -0,0 +1,433 @@
+#define timer_t	    	timer_t_linux
+
+#include <l4.h>
+#include <l4/interrupt.h>
+#include <l4/utcb.h>
+#include <wombat.h>
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#undef timer_t
+
+#include <iguana/memsection.h>
+#include <iguana/thread.h>
+#include <iguana/hardware.h>
+
+#include <genode/memory.h>
+#include <genode/sleep.h>
+#include <genode/lock.h>
+#ifdef CONFIG_SCREEN_GENODE
+#include <genode/input.h>
+#endif
+#ifdef CONFIG_SND_GENODE
+#include <genode/audio.h>
+#endif
+#ifdef CONFIG_NET_GENODE
+#include <genode/net.h>
+#endif
+#ifdef CONFIG_BLOCK_GENODE
+#include <genode/block.h>
+#endif
+
+#include "assert.h"
+#include "irq_impl.h"
+
+#include <linux/posix_types.h>
+
+
+extern L4_ThreadId_t main_thread;
+extern L4_ThreadId_t timer_thread;
+extern L4_ThreadId_t timer_handle;
+
+/*
+ * Mask is set (1) if enabled
+ */
+L4_Word_t irq_mask = 1;     // Keep bit 1 reserverd for timer as it is somewhat magic
+
+#define NUM_CPUS 1
+fd_set pending_irqs[NUM_CPUS];
+#define PENDING_MASK_SIZE (NR_IRQS / 32)
+
+/*
+ * Need SMP-safe access to interrupt CSRs
+ */
+DEFINE_SPINLOCK(iguana_irq_lock);
+
+static inline void
+iguana_enable_irq(unsigned int irq)
+{
+	printk("WARN: %s does not work by now!\n",__func__);
+	spin_lock(&iguana_irq_lock);
+	if (irq < 32) {
+		irq_mask |= (1UL << 31); /* always use bit 31 for hw irqs */
+		//L4_LoadMR(0, irq);
+		//L4_AcknowledgeInterruptOnBehalf(timer_thread, 0, 0);
+	} else {
+		irq_mask |= (1UL << irq);
+	}
+	spin_unlock(&iguana_irq_lock);
+}
+
+static inline void
+iguana_disable_irq(unsigned int irq)
+{
+	printk("WARN: %s does not work by now!\n",__func__);
+	spin_lock(&iguana_irq_lock);
+	if (irq < 32) {
+		//L4_LoadMR(0, irq);
+		//L4_UnregisterInterrupt(timer_thread, 0, 0);
+	} else {
+		irq_mask &= ~(1UL << irq);
+	}
+
+	spin_unlock(&iguana_irq_lock);
+}
+
+static unsigned int
+iguana_startup_irq(unsigned int irq)
+{
+	if (irq < 32)
+		hardware_register_interrupt(timer_thread, irq);
+
+	iguana_enable_irq(irq);
+
+	return 0;
+}
+
+static void
+iguana_ack_irq(unsigned int irq)
+{
+}
+
+static void
+iguana_end_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		iguana_enable_irq(irq);
+}
+
+static void
+iguana_cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
+{
+	// XXX fixme
+	printk("%s called\n", __func__);
+}
+
+static void
+iguana_set_irq_affinity(unsigned int irq, cpumask_t affinity)
+{
+	spin_lock(&iguana_irq_lock);
+	iguana_cpu_set_irq_affinity(irq, affinity);
+	spin_unlock(&iguana_irq_lock);
+}
+
+static void __init
+init_iguana_irqs(struct hw_interrupt_type * ops, int imin, int imax)
+{
+	long i;
+	for (i = imin; i <= imax; ++i) {
+		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
+		irq_desc[i].chip = ops;
+	}
+}
+
+static struct hw_interrupt_type iguana_irq_type = {
+	.typename       = "iguana",
+	.startup        = iguana_startup_irq,
+	.shutdown       = iguana_disable_irq,
+	.enable         = iguana_enable_irq,
+	.disable        = iguana_disable_irq,
+	.ack            = iguana_ack_irq,
+	.end            = iguana_end_irq,
+	.set_affinity   = iguana_set_irq_affinity,
+};
+
+static void __init
+iguana_init_irq(void)
+{
+	init_iguana_irqs(&iguana_irq_type, 0, NR_IRQS-1);
+}
+
+void __init
+init_IRQ(void)
+{
+	iguana_init_irq();
+}
+
+/*
+ * Iguana Family
+ */
+extern uintptr_t temp_cap_slot;
+extern uintptr_t temp_cap_used;
+extern uintptr_t temp_cap_size;
+extern uintptr_t temp_cap_addr;
+
+extern void
+__cap_init(uintptr_t cap_slot, uintptr_t cap_used, uintptr_t cap_size, uintptr_t cap_addr);
+
+memsection_ref_t vmalloc_memsect;
+uintptr_t vmalloc_start, vmalloc_end;
+
+/* FIXME: Should be extended for SMP? */ 
+struct ig_irq_rec{
+	unsigned short pending;
+	L4_ThreadId_t  tid;
+} irq_recs[NR_IRQS]; 
+
+static int __init
+iguana_arch_init(void)
+{
+#if 0
+	/*
+	 * Enable the system error interrupts. These interrupts are 
+	 * all reported to the kernel as machine checks, so the handler
+	 * is a nop so it can be called to count the individual events.
+	 */
+
+	/*
+	   FIXME: We need to setup capabilties library properly now!
+	   Ideally we would do this really early, but this is about as early
+	   as we get!
+	*/
+	__cap_init(temp_cap_slot, temp_cap_used, temp_cap_size, temp_cap_addr);
+#endif
+
+	/* Just take physical memory end + 1MB hole as starting point */
+	unsigned long offset = 10*1024*1024;
+	vmalloc_start  = (uintptr_t) genode_malloc(10);
+	vmalloc_start += (2*offset-1) & ~(offset-1);
+
+	/* Let the vmalloc area size be 100MB and hope it doesn't collude */
+	vmalloc_end   =  vmalloc_start + 100*1024*1024;
+	genode_printf("vmalloc area: %lx - %lx\n", vmalloc_start, vmalloc_end);
+
+	return 0;
+}
+
+arch_initcall(iguana_arch_init);
+
+extern void * __callback_buffer;
+
+#define BIT(x) (1<<(x))
+#define TIMER_IRQ 0
+
+/*
+ * XXX: namespace clash.  :-(
+ */
+#define device_create okl4_device_create
+
+//#include <driver/types.h>
+//#include <interfaces/vtimer_client.h>
+
+//server_t timer_server;
+//device_t timer_dev;
+
+/*
+ * XXX this needs 32/64bit cleanup + merge into irq.c
+ */
+/* int mask_to_irq(L4_Word_t *mask) */
+/* { */
+/* 	int i; */
+
+/* 	for (i = 0 ; i < NR_IGUANA_IRQS; i++) */
+/* 	{ */
+/* 		if (*mask & (1 << i)) */
+/* 		{ */
+/* 			*mask &= ~(1 << i); */
+
+/* 			/\* Bit 31 is ia32 BSP's way of saying hardware interrupt *\/ */
+/* 			if (i == 31) */
+/* 			{ */
+/* 				/\* read hw irq number from utcb->platform_reserved[0] *\/ */
+/* 				//printk("mask_to_irq: got hw irq %ld!\n", utcb_base_get()->platform_reserved[0]); */
+/* 				return utcb_base_get()->platform_reserved[0]; */
+/* 			} */
+/* 			else */
+/* 			{ */
+/* 				return IGUANA_IRQ(i); */
+/* 			} */
+/* 		} */
+/*     } */
+/*     return -1; */
+/* } */
+
+int iguana_alloc_irq(void)
+{
+	int i;
+	for (i = 0; i < NR_IGUANA_IRQS; i++){
+		if (!(irq_mask & (1UL<<i))){
+			irq_mask |= (1UL<<i);
+			return IGUANA_IRQ(i);
+		}
+	}
+	return -1;
+}
+//extern void ig_serial_interrupt(void);
+//extern void ig_input_interrupt(void);
+
+static int pending_tick;
+
+/* static int */
+/* tid_to_int(L4_ThreadId_t tid) */
+/* { */
+/* 	return (int)L4_ThreadNo(tid); */
+/* } */
+
+/* L4_Word_t */
+/* corba_l4_error(CORBA_Environment *env) */
+/* { */
+/* 	L4_Word_t	val = *(L4_Word_t *)(env); */
+	
+/* 	if ((val & 0xff) == CORBA_SYSTEM_EXCEPTION) */
+/* 		return val >> 8; */
+/* 	else */
+/* 		return 0; */
+/* } */
+
+extern void* timer_main_kernel_lock;
+
+void
+interrupt_loop(void)
+{
+	struct thread_info * curinfo;
+
+	/* timer interrupt */
+	int irq = IGUANA_IRQ(0);
+
+	/* Wait for wake up message from timer init */
+    L4_Call(main_thread);
+
+	printk("START CLOCK LOOP\n");
+
+	while(1) {
+		genode_sleep(10);
+		genode_lock(timer_main_kernel_lock);
+#ifdef CONFIG_SCREEN_GENODE
+		genode_input_handle_events();
+#endif
+#ifdef CONFIG_SND_GENODE
+		genode_audio_collect_acks();
+#endif
+#ifdef CONFIG_NET_GENODE
+		genode_net_rx_receive();
+#endif
+#ifdef CONFIG_BLOCK_GENODE
+		genode_block_collect_responses();
+#endif
+		curinfo = current_thread_info();
+		curinfo->regs.mode ++;
+
+		if (irqs_disabled())
+		{
+			FD_SET(irq, &pending_irqs[smp_processor_id()]);
+
+			/* Keep time going for missed ticks */
+			if (pending_tick)
+				jiffies_64++;
+			IRQ_pending(smp_processor_id()) ++;
+			pending_tick = 1;
+			curinfo->regs.mode --;
+			genode_unlock(timer_main_kernel_lock);
+		}
+		else
+		{
+			isr_irq_disable();
+			// Should loop over all bits potentially set
+			handle_irq(irq, NULL);
+			isr_irq_enable();
+			pending_tick = 0;
+			isr_irq_disable();
+			irq_enter();
+			do_timer(1);
+			update_process_times(user_mode(&curinfo->regs));
+			irq_exit();
+			isr_irq_enable();
+			curinfo->regs.mode --;
+
+			genode_unlock(timer_main_kernel_lock);
+			if (need_resched()) {
+				L4_MsgTag_t msgtag = L4_Niltag;
+				L4_Msg_t msg;
+				L4_Set_MsgMsgTag( &msg, msgtag );
+				L4_MsgLoad( &msg );
+				L4_Send_Nonblocking(main_thread);
+			}
+		}
+	}
+}
+
+static int irq_mask_to_num(void){
+	int i;
+	int cpu = smp_processor_id();
+	unsigned int least_sig;
+
+	for (i = 0; i <= PENDING_MASK_SIZE; ++i){
+		least_sig = fls(pending_irqs[cpu].fds_bits[i]);
+		if (least_sig == 0)
+			continue;
+		else{
+			int bit = (i * sizeof(long)*8) + least_sig;
+			FD_CLR(bit-1, &pending_irqs[smp_processor_id()]);
+			return (bit - 1);
+		}
+	}
+	return -1;
+}
+/*
+ * This is called to handle pending interrupts from the main linux thread.
+ * We thus need to send a deceiving IPC to the L4 interrupt thread to
+ * ACK the interrupt. This is called with interrupts disabled
+ */
+void
+l4_handle_pending(void)
+{
+	int irq_num;
+	struct thread_info * curinfo = current_thread_info();
+
+	curinfo->regs.mode ++;
+
+	if (pending_tick)
+	{
+		irq_enter();
+		do_timer(1);
+		update_process_times(user_mode(&curinfo->regs));
+
+		pending_tick = 0;
+		irq_exit();
+	}
+
+	/*
+	 * XXX
+	 * 
+	 * Concurrency problem: the FD_SET() and FD_CLR() are not 
+	 * atomic but can be accessed either in the timer thread
+	 * context or the syscall loop thread context
+	 *
+	 * -gl
+	 */
+	while((irq_num = irq_mask_to_num()) != -1)
+	{
+		handle_irq(irq_num, NULL);
+	}
+
+	IRQ_pending(smp_processor_id())--;
+
+	curinfo->regs.mode --;
+}
+
+void local_irq_enable(void)
+{
+	if (unlikely(!in_interrupt() && IRQ_pending(smp_processor_id())))
+	{
+		IRQ_state(smp_processor_id()) = 1;
+		l4_handle_pending();
+	}
+	IRQ_state(smp_processor_id()) = 0;
+}
+
+EXPORT_SYMBOL(local_irq_enable);
+
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/syscall_loop.c contrib/arch/l4/kernel/syscall_loop.c
--- kernel-2.6.23-v2/arch/l4/kernel/syscall_loop.c
+++ contrib/arch/l4/kernel/syscall_loop.c
@@ -23,10 +23,8 @@
 #include <asm/setup.h>
 
 #include <iguana/thread.h>
-#include <iguana/cap.h>
 #include <iguana/memsection.h>
-#include <iguana/tls.h>
-#include <iguana/object.h>
+#include <genode/lock.h>
 
 #include <linux/mman.h>
 
@@ -36,6 +34,7 @@
 extern L4_ThreadId_t timer_thread;
 extern L4_ThreadId_t timer_handle;
 extern L4_ThreadId_t main_thread;
+extern void* timer_main_kernel_lock;
 
 extern unsigned long get_instr(unsigned long addr);
 extern unsigned long set_instr(unsigned long addr, unsigned long value);
@@ -556,9 +555,12 @@ return_to_user:
 			if (likely(reply_user_ipc(curinfo))) {
 				curinfo->regs.mode = 0;
 				L4_MsgLoad(&curinfo->regs.msg);
+				genode_unlock(timer_main_kernel_lock);
 				/* Reply to caller and wait for next IPC */
 				tag = L4_ReplyWait(curinfo->user_tid,
 						&from);
+				genode_lock(timer_main_kernel_lock);
+
 			} else {
 retry:
 				if (user_need_restart(curinfo)) {
@@ -570,10 +572,12 @@ retry:
 				}
 				curinfo->regs.mode = 0;
 				/* Open Wait */
+				genode_unlock(timer_main_kernel_lock);
 				tag = L4_Wait (&from);
+				genode_lock(timer_main_kernel_lock);
 			}
 
-			if (likely(from.raw == curinfo->user_handle.raw))
+			if (likely(from.raw == curinfo->user_tid.raw))
 			{
 				curinfo->regs.mode = 1;
 				curinfo->tag = tag;
@@ -587,6 +591,7 @@ retry:
 			}
 			else
 			{
+#if 0
 				/* XXX
 				 * Here we have to lookup the linux thread from
 				 * the L4 thread_id, which may be expensive.
@@ -595,9 +600,12 @@ retry:
 				 * thread could use this to kill root processes.
 				 */
 				printk("illegal ipc from %lx, expected %lx\n", from.raw,
-						curinfo->user_handle.raw);
+						curinfo->user_tid.raw);
 				L4_KDB_Enter("ill");
 				goto retry;
+#endif
+				curinfo->regs.mode = 1;
+				curinfo->tag = tag;
 			}
 		}
 
diff -urNpB kernel-2.6.23-v2/arch/l4/kernel/vmlinux.lds.S contrib/arch/l4/kernel/vmlinux.lds.S
--- kernel-2.6.23-v2/arch/l4/kernel/vmlinux.lds.S
+++ contrib/arch/l4/kernel/vmlinux.lds.S
@@ -22,6 +22,10 @@ SECTIONS
 #endif
   /* read-only */
   .text : {
+    /* begin of program image (link address) */
+    _prog_img_beg = .;
+
+    _stext = .;
     _text = .;			/* Text and read-only data */
     *(.text)
     SCHED_TEXT
@@ -29,6 +33,18 @@ SECTIONS
     *(.fixup)
     *(.gnu.warning)
     *(.note*)
+
+    . = ALIGN(0x04);
+
+    _ctors_start = .;
+    KEEP (*(.ctors))
+    KEEP (*(SORT(.ctors.*)))
+    _ctors_end = .;
+    _dtors_start = .;
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+    _dtors_end = .;
+
     . = ALIGN(PAGE_SIZE);
     __user_exregs_page = .;
     *(.exregspage)
@@ -42,11 +58,25 @@ SECTIONS
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
 
+  .eh_frame_hdr : { *(.eh_frame_hdr) }
+
   RODATA
 
-  . = ALIGN(PAGE_SIZE); 
-	
+  . = ALIGN(PAGE_SIZE);
+
+  _prog_img_data = .;
+
   .data : {			/* Data */
+    /* Leave space for parent capability parameters at start of data
+     * section. The protection domain creator is reponsible for storing
+     * sane values here.
+     */
+    _parent_cap = .;
+    LONG(0xffffffff);
+    LONG(0xffffffff);
+    LONG(0xffffffff);
+    LONG(0xffffffff);
+
    /* Align the initial ramdisk image (INITRD) on page boundaries. */
 /*
    __rd_start = .;
@@ -59,7 +89,16 @@ SECTIONS
 
     CONSTRUCTORS
    . = ALIGN(PAGE_SIZE);
-  }
+  } : rw
+
+  /* exception frames for C++ */
+  .eh_frame : {
+    __eh_frame_start__ = .;
+    KEEP (*(.eh_frame))
+    LONG(0)
+  } : rw
+  .gcc_except_table : { KEEP(*(.gcc_except_table)) }
+  .dynamic :  { *(.dynamic) }
 
   . = ALIGN(32);
   .data.cacheline_aligned : { *(.data.cacheline_aligned) }
@@ -122,9 +161,15 @@ SECTIONS
 	*(COMMON)
 	_end = .;
   }
+
+  /* end of program image -- must be after last section */
+  _prog_img_end = .;
+
 }
 
 PHDRS
 {
   main_seg PT_LOAD;
+  ro       PT_LOAD;
+  rw       PT_LOAD;
 }
diff -urNpB kernel-2.6.23-v2/arch/l4/mm/mmu.c contrib/arch/l4/mm/mmu.c
--- kernel-2.6.23-v2/arch/l4/mm/mmu.c
+++ contrib/arch/l4/mm/mmu.c
@@ -39,7 +39,6 @@ void activate_mm(struct mm_struct *old,
 
 	if (old_thrd.raw != L4_nilthread.raw)
 	{
-		int r;
 		thread_delete(old_thrd);
 		current_thread_info()->user_tid =
 			eas_create_thread(new->context.eas,
@@ -48,8 +47,6 @@ void activate_mm(struct mm_struct *old,
 					&current_thread_info()->user_handle);
 
 		assert(current_thread_info()->user_tid.raw != 0);
-		r  = L4_Set_Priority(current_thread_info()->user_tid, 98);
-		assert(r != 0);
 
 		{
 			char name[16];
diff -urNpB kernel-2.6.23-v2/arch/l4/sys-i386/Makefile contrib/arch/l4/sys-i386/Makefile
--- kernel-2.6.23-v2/arch/l4/sys-i386/Makefile
+++ contrib/arch/l4/sys-i386/Makefile
@@ -4,7 +4,7 @@ CFLAGS += -O2
 ELF_ARCH = i386
 ELF_FORMAT = elf32-i386
 
-obj-y = crt0.o delay.o signal.o syscalls.o semaphore.o io.o sys_i386.o bitops.o user.o ptrace.o process.o ldt.o traps.o processor.o string.o dma.o memcpy.o strstr.o ioport.o
+obj-y = delay.o signal.o syscalls.o semaphore.o io.o sys_i386.o bitops.o user.o ptrace.o process.o ldt.o traps.o processor.o string.o dma.o memcpy.o strstr.o ioport.o
 
 ifdef CONFIG_IA32_VDSO_ENABLE
 obj-y += sysenter.o vsyscall.o
@@ -42,7 +42,7 @@ targets += vsyscall-note.o vsyscall.lds
 
 # The DSO images are built using a special linker script.
 quiet_cmd_syscall = SYSCALL $@
-	cmd_syscall = $(CC) -m elf_i386 -nostdlib $(SYSCFLAGS_$(@F)) \
+	cmd_syscall = $(CC) -m32 -nostdlib $(SYSCFLAGS_$(@F)) \
 			-Wl,-T,$(filter-out FORCE,$^) -o $@
 
 export CPPFLAGS_vsyscall.lds += -P -C -U$(ARCH)
diff -urNpB kernel-2.6.23-v2/arch/l4/sys-i386/crt0.S contrib/arch/l4/sys-i386/crt0.S
--- kernel-2.6.23-v2/arch/l4/sys-i386/crt0.S
+++ contrib/arch/l4/sys-i386/crt0.S
@@ -31,13 +31,13 @@
  ********************************************************************/
 
         .text
-        .global _start
+        .global _wombat_start
 _stext:
         .global _stext
 
-_start:
+_wombat_start:
 	push	$0xfee1dead	/* dummy frame thingy */
 	jmp	__sys_entry	/* off we go! */
 	/*NOTREACHED*/
 
-	.end	_start
+	.end	_wombat_start
diff -urNpB kernel-2.6.23-v2/arch/l4/sys-i386/dma.c contrib/arch/l4/sys-i386/dma.c
--- kernel-2.6.23-v2/arch/l4/sys-i386/dma.c
+++ contrib/arch/l4/sys-i386/dma.c
@@ -11,7 +11,7 @@
 #include <iguana/thread.h>
 #include <iguana/memsection.h>
 #include <iguana/hardware.h>
-#include <iguana/physmem.h>
+//#include <iguana/physmem.h>
 
 /* Allocate consistent (uncached, or the appearance of it) memory */
 /* We ignore the flags at the moment */
diff -urNpB kernel-2.6.23-v2/arch/l4/sys-i386/ioport.c contrib/arch/l4/sys-i386/ioport.c
--- kernel-2.6.23-v2/arch/l4/sys-i386/ioport.c
+++ contrib/arch/l4/sys-i386/ioport.c
@@ -13,8 +13,8 @@
  */
 asmlinkage long sys_iopl(unsigned long unused)
 {
-	unsigned long old = 0;	/* XXX */
-	unsigned long level;	/* in %ebx */
+	//unsigned long old = 0;	/* XXX */
+	//unsigned long level;	/* in %ebx */
 
 	printk("%s: not implemented.\n", __func__);
 #if 0
diff -urNpB kernel-2.6.23-v2/arch/l4/sys-i386/signal.c contrib/arch/l4/sys-i386/signal.c
--- kernel-2.6.23-v2/arch/l4/sys-i386/signal.c
+++ contrib/arch/l4/sys-i386/signal.c
@@ -189,8 +189,8 @@ restore_sigcontext(struct pt_regs *ptreg
 
 	return err;
 
-badframe:
-	return 1;
+//badframe:
+//	return 1;
 }
 
 asmlinkage int sys_sigreturn(struct pt_regs *regs)
diff -urNpB kernel-2.6.23-v2/block/cfq-iosched.c contrib/block/cfq-iosched.c
--- kernel-2.6.23-v2/block/cfq-iosched.c
+++ contrib/block/cfq-iosched.c
@@ -1427,6 +1427,7 @@ cfq_async_queue_prio(struct cfq_data *cf
 	default:
 		BUG();
 	}
+	return 0;
 }
 
 static struct cfq_queue *
diff -urNpB kernel-2.6.23-v2/include/asm-l4/bug.h contrib/include/asm-l4/bug.h
--- kernel-2.6.23-v2/include/asm-l4/bug.h
+++ contrib/include/asm-l4/bug.h
@@ -4,12 +4,13 @@
 #ifndef __ASSEMBLY__
 
 #include <iguana/pd.h>
+#include <genode/printf.h>
+#include <genode/exit.h>
 
 #define HAVE_ARCH_BUG
 #define BUG() do { \
-	/*panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__);*/ \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-	pd_delete(pd_myself());	\
+	genode_printf("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	genode_exit(1); \
 } while (0)
 
 #define HAVE_ARCH_BUG_ON
@@ -23,6 +24,18 @@
 	BUG(); \
 } while (0)
 
+
+#define HAVE_ARCH_WARN_ON
+#define WARN_ON(condition) ({						\
+	int __ret_warn_on = !!(condition);				\
+	if (unlikely(__ret_warn_on)) {					\
+		genode_printf("WARNING: at %s:%d %s()\n", __FILE__,		\
+			__LINE__, __FUNCTION__);			\
+	}								\
+	unlikely(__ret_warn_on);					\
+})
+
+
 extern int foo;
 
 #include <asm-generic/bug.h>
diff -urNpB kernel-2.6.23-v2/include/asm-l4/i386/dma-mapping.h contrib/include/asm-l4/i386/dma-mapping.h
--- kernel-2.6.23-v2/include/asm-l4/i386/dma-mapping.h
+++ contrib/include/asm-l4/i386/dma-mapping.h
@@ -26,7 +26,7 @@
 #include <iguana/thread.h>
 #include <iguana/memsection.h>
 #include <iguana/hardware.h>
-#include <iguana/physmem.h>
+//#include <iguana/physmem.h>
 
 
 static inline int
diff -urNpB kernel-2.6.23-v2/include/asm-l4/i386/ptrace.h contrib/include/asm-l4/i386/ptrace.h
--- kernel-2.6.23-v2/include/asm-l4/i386/ptrace.h
+++ contrib/include/asm-l4/i386/ptrace.h
@@ -61,7 +61,7 @@
 #define PTRACE_GET_THREAD_AREA		25
 #define PTRACE_SET_THREAD_AREA		26
 
-extern inline void
+static inline void
 l4_arch_setup_restart(struct pt_regs *regs)
 {
 	i386_put_eax(regs, i386_save(regs));
@@ -70,7 +70,7 @@ l4_arch_setup_restart(struct pt_regs *re
 
 #define __NR_restart_syscall	0
 
-extern inline void
+static inline void
 l4_arch_setup_sys_restart(struct pt_regs *regs)
 {
 	i386_put_eax(regs, __NR_restart_syscall);
diff -urNpB kernel-2.6.23-v2/include/asm-l4/i386/syscalls.h contrib/include/asm-l4/i386/syscalls.h
--- kernel-2.6.23-v2/include/asm-l4/i386/syscalls.h
+++ contrib/include/asm-l4/i386/syscalls.h
@@ -47,7 +47,7 @@ extern l4_i386_abi_syscalls_t l4_i386_ab
 
 #ifdef CONFIG_IA32_VDSO_ENABLE
 
-extern inline void
+static inline void
 l4_i386_get_fast_syscall_args(struct pt_regs *regs)
 {
     /* TODO: ensure sp is valid */
@@ -69,7 +69,7 @@ l4_i386_get_fast_syscall_args(struct pt_
 
 #endif /* ifdef CONFIG_IA32_VDSO_ENABLE */
 
-extern inline long
+static inline long
 l4_arch_lookup_syscall (struct pt_regs *regs, L4_Word_t *abi)
 {
     L4_Word_t call;
@@ -98,7 +98,7 @@ typedef L4_Word_t func_four_arg_t(L4_Wor
 typedef L4_Word_t func_five_arg_t(L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t);
 typedef L4_Word_t func_six_arg_t(L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t, L4_Word_t);
 
-extern inline L4_Word_t
+static inline L4_Word_t
 l4_arch_abi_call(struct pt_regs *regs, L4_Word_t sys_num, L4_Word_t abi)
 {
     L4_Word_t result = -1ul;
@@ -159,13 +159,13 @@ l4_arch_abi_call(struct pt_regs *regs, L
     return result;
 }
 
-extern inline long
+static inline long
 l4_arch_get_error(struct pt_regs *regs)
 {
     return -(long)i386_eax(regs);
 }
 
-extern inline int
+static inline int
 l4_arch_restart_syscall(struct pt_regs *regs)
 {
     L4_Word_t temp;
diff -urNpB kernel-2.6.23-v2/include/asm-l4/signal_l4.h contrib/include/asm-l4/signal_l4.h
--- kernel-2.6.23-v2/include/asm-l4/signal_l4.h
+++ contrib/include/asm-l4/signal_l4.h
@@ -22,7 +22,7 @@ static inline int need_to_resched(struct
 
 extern void do_syscall_trace(int, void *);
 
-extern inline void
+static inline void
 syscall_entry(struct thread_info * my_info)
 {
 	if (unlikely(need_syscall_trace(my_info)))
@@ -34,7 +34,7 @@ syscall_entry(struct thread_info * my_in
 	}
 }
 
-extern inline void
+static inline void
 syscall_exit(struct thread_info * my_info, int syscall)
 {
 	if (unlikely( syscall && need_syscall_trace(my_info) ))
@@ -46,7 +46,7 @@ syscall_exit(struct thread_info * my_inf
 	}
 }
 
-extern inline int
+static inline int
 l4_work_pending(struct thread_info * my_info, int syscall, struct pt_regs *regs)
 {
 	if (unlikely( need_to_resched(my_info) )) {
@@ -59,7 +59,7 @@ l4_work_pending(struct thread_info * my_
 	return 0;
 }
 
-extern inline int
+static inline int
 l4_work_pending_preempt(struct pt_regs *regs)
 {
 	int restart = 0;
diff -urNpB kernel-2.6.23-v2/include/asm-l4/uaccess.h contrib/include/asm-l4/uaccess.h
--- kernel-2.6.23-v2/include/asm-l4/uaccess.h
+++ contrib/include/asm-l4/uaccess.h
@@ -101,7 +101,7 @@ static inline int verify_area(int type,
 	return 0;
 }
 
-#define access_ok(type,addr,size) 1
+#define access_ok(type,addr,size) (((unsigned long)addr != size) || 1)
 
 #endif
 
diff -urNpB kernel-2.6.23-v2/kernel/mutex.c contrib/kernel/mutex.c
--- kernel-2.6.23-v2/kernel/mutex.c
+++ contrib/kernel/mutex.c
@@ -57,7 +57,7 @@ EXPORT_SYMBOL(__mutex_init);
  * We also put the fastpath first in the kernel image, to make sure the
  * branch is predicted by the CPU as default-untaken.
  */
-static void fastcall noinline __sched
+void fastcall noinline __sched
 __mutex_lock_slowpath(atomic_t *lock_count);
 
 /***
@@ -93,7 +93,7 @@ void inline fastcall __sched mutex_lock(
 
 EXPORT_SYMBOL(mutex_lock);
 
-static void fastcall noinline __sched
+void fastcall noinline __sched
 __mutex_unlock_slowpath(atomic_t *lock_count);
 
 /***
@@ -197,7 +197,7 @@ done:
 	return 0;
 }
 
-static void fastcall noinline __sched
+void fastcall noinline __sched
 __mutex_lock_slowpath(atomic_t *lock_count)
 {
 	struct mutex *lock = container_of(lock_count, struct mutex, count);
@@ -265,7 +265,7 @@ __mutex_unlock_common_slowpath(atomic_t
 /*
  * Release the lock, slowpath:
  */
-static fastcall noinline void
+fastcall noinline void
 __mutex_unlock_slowpath(atomic_t *lock_count)
 {
 	__mutex_unlock_common_slowpath(lock_count, 1);
diff -urNpB kernel-2.6.23-v2/mm/slab.c contrib/mm/slab.c
--- kernel-2.6.23-v2/mm/slab.c
+++ contrib/mm/slab.c
@@ -3758,6 +3758,7 @@ void kfree(const void *objp)
 {
 	struct kmem_cache *c;
 	unsigned long flags;
+	void *ptr = (void*)objp;
 
 	if (unlikely(ZERO_OR_NULL_PTR(objp)))
 		return;
@@ -3765,7 +3766,7 @@ void kfree(const void *objp)
 	kfree_debugcheck(objp);
 	c = virt_to_cache(objp);
 	debug_check_no_locks_freed(objp, obj_size(c));
-	__cache_free(c, (void *)objp);
+	__cache_free(c, /*(void *)objp*/ptr);
 	local_irq_restore(flags);
 }
 EXPORT_SYMBOL(kfree);
diff -urNpB kernel-2.6.23-v2/scripts/checksyscalls.sh contrib/scripts/checksyscalls.sh
--- kernel-2.6.23-v2/scripts/checksyscalls.sh
+++ contrib/scripts/checksyscalls.sh
@@ -119,5 +119,9 @@ sed -n -e '/^\#define/ { s/[^_]*__NR_\([
 \#endif/p }' $1
 }
 
+echo "SRCTREE"
+echo "${srctree}"
+echo "END"
+
 (ignore_list && syscall_list ${srctree}/include/asm-i386/unistd.h) | \
 $* -E -x c - > /dev/null
