Index: uspace/srv/hid/kbd/port/i8042.h
===================================================================
--- uspace/srv/hid/kbd/port/i8042.h	(revision 04803bf8f1da7bdbf5ff9493b1ebf9a322103841)
+++ uspace/srv/hid/kbd/port/i8042.h	(revision 04803bf8f1da7bdbf5ff9493b1ebf9a322103841)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup kbd_port
+ * @ingroup  kbd
+ * @{
+ */
+
+/** @file
+ * @brief i8042 port driver.
+ */
+
+#ifndef KBD_PORT_i8042_H_
+#define KBD_PORT_i8042_H_
+
+#include <libarch/ddi.h>
+#include <libarch/types.h>
+
+struct i8042 {
+	ioport8_t data;
+	uint8_t pad[3];
+	ioport8_t status;
+} __attribute__ ((packed));
+typedef struct i8042 i8042_t;
+
+#endif
+
+/**
+ * @}
+ */ 
Index: uspace/srv/loader/elf_load.c
===================================================================
--- uspace/srv/loader/elf_load.c	(revision 306061aed98cdcf0119a9e630f19df95fd68ccc0)
+++ uspace/srv/loader/elf_load.c	(revision 04803bf8f1da7bdbf5ff9493b1ebf9a322103841)
@@ -103,5 +103,6 @@
  *
  */
-int elf_load_file(const char *file_name, size_t so_bias, elf_info_t *info)
+int elf_load_file(const char *file_name, size_t so_bias, eld_flags_t flags,
+    elf_info_t *info)
 {
 	elf_ld_t elf;
@@ -118,4 +119,5 @@
 	elf.fd = fd;
 	elf.info = info;
+	elf.flags = flags;
 
 	rc = elf_load(&elf, so_bias);
@@ -124,19 +126,4 @@
 
 	return rc;
-}
-
-/** Run an ELF executable.
- *
- * Transfers control to the entry point of an ELF executable loaded
- * earlier with elf_load_file(). This function does not return.
- *
- * @param info Info structure filled earlier by elf_load_file()
- *
- */
-void elf_run(elf_info_t *info, pcb_t *pcb)
-{
-	program_run(info->entry, pcb);
-
-	/* not reached */
 }
 
@@ -153,4 +140,5 @@
 	pcb->entry = info->entry;
 	pcb->dynamic = info->dynamic;
+	pcb->rtld_runtime = NULL;
 }
 
@@ -306,11 +294,20 @@
 		break;
 	case PT_INTERP:
-		/* Assume silently interp == "/rtld.so" */
-		elf->info->interp = "/rtld.so";
+		/* Assume silently interp == "/app/dload" */
+		elf->info->interp = "/app/dload";
 		break;
 	case PT_DYNAMIC:
+		/* Record pointer to dynamic section into info structure */
+		elf->info->dynamic =
+		    (void *)((uint8_t *)entry->p_vaddr + elf->bias);
+		DPRINTF("dynamic section found at 0x%x\n",
+			(uintptr_t)elf->info->dynamic);
+		break;
+	case 0x70000000:
+		/* FIXME: MIPS reginfo */
+		break;
 	case PT_SHLIB:
-	case PT_LOPROC:
-	case PT_HIPROC:
+//	case PT_LOPROC:
+//	case PT_HIPROC:
 	default:
 		DPRINTF("Segment p_type %d unknown.\n", entry->p_type);
@@ -383,5 +380,6 @@
 	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
 	if (a == (void *)(-1)) {
-		DPRINTF("Memory mapping failed.\n");
+		DPRINTF("memory mapping failed (0x%x, %d)\n",
+			base+bias, mem_sz);
 		return EE_MEMORY;
 	}
@@ -425,4 +423,11 @@
 	}
 
+	/*
+	 * The caller wants to modify the segments first. He will then
+	 * need to set the right access mode and ensure SMC coherence.
+	 */
+	if ((elf->flags & ELDF_RW) != 0) return EE_OK;
+
+//	printf("set area flags to %d\n", flags);
 	rc = as_area_change_flags(seg_ptr, flags);
 	if (rc != 0) {
Index: uspace/srv/loader/include/elf_load.h
===================================================================
--- uspace/srv/loader/include/elf_load.h	(revision 306061aed98cdcf0119a9e630f19df95fd68ccc0)
+++ uspace/srv/loader/include/elf_load.h	(revision 04803bf8f1da7bdbf5ff9493b1ebf9a322103841)
@@ -43,4 +43,9 @@
 #include "elf.h"
 
+typedef enum {
+	/** Leave all segments in RW access mode. */
+	ELDF_RW = 1
+} eld_flags_t;
+
 /**
  * Some data extracted from the headers are stored here
@@ -67,4 +72,7 @@
 	uintptr_t bias;
 
+	/** Flags passed to the ELF loader. */
+	eld_flags_t flags;
+
 	/** A copy of the ELF file header */
 	elf_header_t *header;
@@ -74,6 +82,6 @@
 } elf_ld_t;
 
-int elf_load_file(const char *file_name, size_t so_bias, elf_info_t *info);
-void elf_run(elf_info_t *info, pcb_t *pcb);
+int elf_load_file(const char *file_name, size_t so_bias, eld_flags_t flags,
+    elf_info_t *info);
 void elf_create_pcb(elf_info_t *info, pcb_t *pcb);
 
Index: uspace/srv/loader/main.c
===================================================================
--- uspace/srv/loader/main.c	(revision 306061aed98cdcf0119a9e630f19df95fd68ccc0)
+++ uspace/srv/loader/main.c	(revision 04803bf8f1da7bdbf5ff9493b1ebf9a322103841)
@@ -65,4 +65,6 @@
 #define DPRINTF(...)
 
+void program_run(void *entry, pcb_t *pcb);
+
 /** Pathname of the file that will be loaded */
 static char *pathname = NULL;
@@ -283,5 +285,5 @@
 	int rc;
 	
-	rc = elf_load_file(pathname, 0, &prog_info);
+	rc = elf_load_file(pathname, 0, 0, &prog_info);
 	if (rc != EE_OK) {
 		DPRINTF("Failed to load executable '%s'.\n", pathname);
@@ -307,5 +309,6 @@
 	}
 	
-	rc = elf_load_file(prog_info.interp, 0, &interp_info);
+	printf("Load ELF interpreter '%s'\n", prog_info.interp);
+	rc = elf_load_file(prog_info.interp, 0, 0, &interp_info);
 	if (rc != EE_OK) {
 		DPRINTF("Failed to load interpreter '%s.'\n",
@@ -315,4 +318,9 @@
 	}
 	
+	printf("Run interpreter.\n");
+	printf("entry point: 0x%lx\n", (unsigned long) interp_info.entry);
+	printf("pcb address: 0x%lx\n", (unsigned long) &pcb);
+	printf("prog dynamic: 0x%lx\n", (unsigned long) prog_info.dynamic);
+
 	is_dyn_linked = true;
 	async_answer_0(rid, EOK);
@@ -343,9 +351,9 @@
 		
 		async_answer_0(rid, EOK);
-		elf_run(&interp_info, &pcb);
+		program_run(interp_info.entry, &pcb);
 	} else {
 		/* Statically linked program */
 		async_answer_0(rid, EOK);
-		elf_run(&prog_info, &pcb);
+		program_run(prog_info.entry, &pcb);
 	}
 	
