Index: generic/include/elf.h
===================================================================
--- generic/include/elf.h	(revision a82500ce45577f8d8eb985c998aee0e0223090c1)
+++ generic/include/elf.h	(revision de6b301a63efb6d81e9db05625bc3438102b9842)
@@ -31,4 +31,304 @@
 
 #include <arch/elf.h>
-
+#include <arch/types.h>
+#include <mm/as.h>
+
+/**
+ * current ELF version
+ */
+#define	EV_CURRENT	1
+
+/** 
+ * ELF types 
+ */
+#define ET_NONE		0	/* No type */
+#define ET_REL		1	/* Relocatable file */
+#define ET_EXEC		2	/* Executable */
+#define ET_DYN		3	/* Shared object */
+#define ET_CORE		4	/* Core */
+#define ET_LOPROC	0xff00	/* Processor specific */
+#define ET_HIPROC	0xffff	/* Processor specific */
+
+/** 
+ * ELF machine types
+ */
+#define EM_NO		0	/* No machine */
+#define EM_SPARC	2	/* SPARC */
+#define EM_386		3	/* i386 */
+#define EM_MIPS		8	/* MIPS RS3000 */
+#define EM_MIPS_RS3_LE	10	/* MIPS RS3000 LE */
+#define EM_PPC		20	/* PPC32 */
+#define EM_PPC64	21	/* PPC64 */
+#define EM_SPARCV9	43	/* SPARC64 */
+#define EM_IA_64	50	/* IA-64 */
+#define EM_X86_64	62	/* AMD64/EMT64 */
+
+/**
+ * ELF identification indexes
+ */
+#define EI_MAG0		0
+#define EI_MAG1		1
+#define EI_MAG2		2
+#define EI_MAG3		3
+#define EI_CLASS	4		/* File class */
+#define EI_DATA		5		/* Data encoding */
+#define EI_VERSION	6		/* File version */
+#define EI_OSABI	7
+#define EI_ABIVERSION	8
+#define EI_PAD		9		/* Start of padding bytes */
+#define EI_NIDENT	16		/* ELF identification table size */
+
+/**
+ * ELF magic number
+ */
+#define ELFMAG0		0x7f
+#define ELFMAG1		'E'
+#define ELFMAG2		'L'
+#define ELFMAG3		'F'
+
+/**
+ * ELF file classes
+ */
+#define ELFCLASSNONE	0
+#define ELFCLASS32	1
+#define ELFCLASS64	2
+
+/**
+ * ELF data encoding types
+ */
+#define ELFDATANONE	0
+#define ELFDATA2LSB	1		/* Least significant byte first (little endian) */
+#define ELFDATA2MSB	2		/* Most signigicant byte first (big endian) */
+
+/**
+ * ELF error return codes
+ */
+#define EE_OK			0	/* No error */
+#define EE_INVALID		1	/* Invalid ELF image */
+#define	EE_MEMORY		2	/* Cannot allocate address space */
+#define EE_INCOMPATIBLE		3	/* ELF image is not compatible with current architecture */
+#define EE_UNSUPPORTED		4	/* Non-supported ELF (e.g. dynamic ELFs) */
+#define EE_IRRECOVERABLE	5
+
+/**
+ * ELF section types
+ */
+#define SHT_NULL		0
+#define SHT_PROGBITS		1
+#define SHT_SYMTAB		2
+#define SHT_STRTAB		3
+#define SHT_RELA		4
+#define SHT_HASH		5
+#define SHT_DYNAMIC		6
+#define SHT_NOTE		7
+#define SHT_NOBITS		8
+#define SHT_REL			9
+#define SHT_SHLIB		10
+#define SHT_DYNSYM		11
+#define SHT_LOOS		0x60000000
+#define SHT_HIOS		0x6fffffff
+#define SHT_LOPROC		0x70000000
+#define SHT_HIPROC		0x7fffffff
+#define SHT_LOUSER		0x80000000
+#define SHT_HIUSER		0xffffffff
+
+/**
+ * ELF section flags
+ */
+#define SHF_WRITE		0x1 
+#define SHF_ALLOC		0x2
+#define SHF_EXECINSTR		0x4
+#define SHF_MASKPROC		0xf0000000
+
+/**
+ * Symbol binding
+ */
+#define STB_LOCAL		0
+#define STB_GLOBAL		1
+#define STB_WEAK		2
+#define STB_LOPROC		13
+#define STB_HIPROC		15
+
+/**
+ * Symbol types
+ */
+#define STT_NOTYPE		0
+#define STT_OBJECT		1
+#define STT_FUNC		2
+#define STT_SECTION		3
+#define STT_FILE		4
+#define STT_LOPROC		13
+#define STT_HIPROC		15
+
+/**
+ * Program segment types
+ */
+#define PT_NULL			0
+#define PT_LOAD			1
+#define PT_DYNAMIC		2
+#define PT_INTERP		3
+#define PT_NOTE			4
+#define PT_SHLIB		5
+#define PT_PHDR			6
+#define PT_LOPROC		0x70000000
+#define PT_HIPROC		0x7fffffff
+
+/**
+ * Program segment attributes.
+ */
+#define PF_X	1
+#define PF_W	2
+#define PF_R	4
+
+/**
+ * ELF data types
+ *
+ * These types are found to be identical in both 32-bit and 64-bit
+ * ELF object file specifications. They are the only types used
+ * in ELF header.
+ */
+typedef __u64 elf_xword;
+typedef __s64 elf_sxword;
+typedef __u32 elf_word;
+typedef __s32 elf_sword;
+typedef __u16 elf_half;
+
+/**
+ * 32-bit ELF data types.
+ *
+ * These types are specific for 32-bit format.
+ */
+typedef __u32 elf32_addr;
+typedef __u32 elf32_off;
+
+/**
+ * 64-bit ELF data types.
+ *
+ * These types are specific for 64-bit format.
+ */
+typedef __u64 elf64_addr;
+typedef __u64 elf64_off;
+
+/** ELF header */
+struct elf32_header {
+	__u8 e_ident[EI_NIDENT];
+	elf_half e_type;
+	elf_half e_machine;
+	elf_word e_version;
+	elf32_addr e_entry;
+	elf32_off e_phoff;
+	elf32_off e_shoff;
+	elf_word e_flags;
+	elf_half e_ehsize;
+	elf_half e_phentsize;
+	elf_half e_phnum;
+	elf_half e_shentsize;
+	elf_half e_shnum;
+	elf_half e_shstrndx;
+};
+struct elf64_header {
+	__u8 e_ident[EI_NIDENT];
+	elf_half e_type;
+	elf_half e_machine;
+	elf_word e_version;
+	elf64_addr e_entry;
+	elf64_off e_phoff;
+	elf64_off e_shoff;
+	elf_word e_flags;
+	elf_half e_ehsize;
+	elf_half e_phentsize;
+	elf_half e_phnum;
+	elf_half e_shentsize;
+	elf_half e_shnum;
+	elf_half e_shstrndx;
+};
+
+/*
+ * ELF section header
+ */
+struct elf32_section_header {
+	elf_word sh_name;
+	elf_word sh_type;
+	elf_word sh_flags;
+	elf32_addr sh_addr;
+	elf32_off sh_offset;
+	elf_word sh_size;
+	elf_word sh_link;
+	elf_word sh_info;
+	elf_word sh_addralign;
+	elf_word sh_entsize;
+};
+struct elf64_section_header {
+	elf_word sh_name;
+	elf_word sh_type;
+	elf_xword sh_flags;
+	elf64_addr sh_addr;
+	elf64_off sh_offset;
+	elf_xword sh_size;
+	elf_word sh_link;
+	elf_word sh_info;
+	elf_xword sh_addralign;
+	elf_xword sh_entsize;
+};
+
+/*
+ * ELF symbol table entry
+ */
+struct elf32_symbol {
+	elf_word st_name;
+	elf32_addr st_value;
+	elf_word st_size;
+	__u8 st_info;
+	__u8 st_other;
+	elf_half st_shndx;
+};
+struct elf64_symbol {
+	elf_word st_name;
+	__u8 st_info;
+	__u8 st_other;
+	elf_half st_shndx;
+	elf64_addr st_value;
+	elf_xword st_size;
+};
+
+/*
+ * ELF program header entry
+ */
+struct elf32_ph_entry {
+	elf_word p_type;
+	elf32_off p_offset;
+	elf32_addr p_vaddr;
+	elf32_addr p_paddr;
+	elf_word p_filesz;
+	elf_word p_memsz;
+	elf_word p_flags;
+	elf_word p_align;
+};
+struct elf64_ph_entry {
+	elf_word p_type;
+	elf_word p_flags;
+	elf64_off p_offset;
+	elf64_addr p_vaddr;
+	elf64_addr p_paddr;
+	elf_xword p_filesz;
+	elf_xword p_memsz;
+	elf_xword p_align;
+};
+
+#ifdef __32_BITS__ 
+typedef struct elf32_header elf_header_t;
+typedef struct elf32_section_header elf_section_header_t;
+typedef struct elf32_symbol elf_symbol_t;
+typedef struct elf32_ph_entry elf_ph_entry_t;
 #endif
+#ifdef __64_BITS__
+typedef struct elf64_header elf_header_t;
+typedef struct elf64_section_header elf_section_header_t;
+typedef struct elf64_symbol elf_symbol_t;
+typedef struct elf64_ph_entry elf_ph_entry_t;
+#endif
+
+extern int elf_load(elf_header_t *header, as_t * as);
+extern char *elf_error(int rc);
+
+#endif
Index: generic/include/elf32.h
===================================================================
--- generic/include/elf32.h	(revision a82500ce45577f8d8eb985c998aee0e0223090c1)
+++ 	(revision )
@@ -1,256 +1,0 @@
-/*
- * Copyright (C) 2006 Sergey Bondari
- * 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.
- */
-
-#ifndef __ELF32_H__
-#define __ELF32_H__
-
-#include <arch/types.h>
-#include <mm/as.h>
-
-/**
- * current ELF version
- */
-#define	EV_CURRENT	1
-
-/** 
- * ELF types 
- */
-#define ET_NONE		0	// No type
-#define ET_REL		1	// Relocatable file
-#define ET_EXEC		2	// Executable
-#define ET_DYN		3	// Shared object
-#define ET_CORE		4	// Core
-#define ET_LOPROC	0xff00	// Processor specific
-#define ET_HIPROC	0xffff	// Processor specific
-
-/** 
- * ELF machine types
- */
-#define EM_NO		0	// No machine
-#define EM_SPARC	2	// SPARC
-#define EM_386		3	// i386
-#define EM_MIPS		8	// MIPS RS3000
-#define EM_MIPS_RS3_LE	10	// MIPS RS3000 LE
-#define EM_PPC		20	// PPC32
-#define EM_PPC64	21	// PPC64
-#define EM_SPARCV9	43	// SPARC64
-#define EM_IA_64	50	// IA-64
-#define EM_X86_64	62	// AMD64/EMT64
-
-/**
- * ELF identification indexes
- */
-#define EI_MAG0		0
-#define EI_MAG1		1
-#define EI_MAG2		2
-#define EI_MAG3		3
-#define EI_CLASS	4	// File class
-#define EI_DATA		5	// Data encoding
-#define EI_VERSION	6	// File version
-#define EI_PAD		7	// Start of padding bytes
-#define EI_NIDENT	16	// ELF identification table size
-
-/**
- * ELF magic number
- */
-#define ELFMAG0		0x7f
-#define ELFMAG1		'E'
-#define ELFMAG2		'L'
-#define ELFMAG3		'F'
-
-/**
- * ELF file classes
- */
-#define ELFCLASSNONE	0
-#define ELFCLASS32	1
-#define ELFCLASS64	2
-
-/**
- * ELF data encoding types
- */
-#define ELFDATANONE	0
-#define ELFDATA2LSB	1	// Least significant byte first (little endian)
-#define ELFDATA2MSB	2	// Most signigicant byte first (Big endian)
-
-/**
- * ELF error return codes
- */
-#define EE_OK			0	// No error
-#define EE_INVALID		1	// invalid ELF image
-#define	EE_MEMORY		2	// cannot allocate address space
-#define EE_INCOMPATIBLE		3	// ELF image is not compatible with current architecture
-#define EE_UNSUPPORTED		4	// Non-supported ELF (e.g. dynamic ELFs)
-
-
-/**
- * ELF section types
- */
-#define SHT_NULL		0
-#define SHT_PROGBITS		1
-#define SHT_SYMTAB		2
-#define SHT_STRTAB		3
-#define SHT_RELA		4
-#define SHT_HASH		5
-#define SHT_DYNAMIC		6
-#define SHT_NOTE		7
-#define SHT_NOBITS		8
-#define SHT_REL			9
-#define SHT_SHLIB		10
-#define SHT_DYNSYM		11
-#define SHT_LOPROC		0x70000000
-#define SHT_HIPROC		0x7fffffff
-#define SHT_LOUSER		0x80000000
-#define SHT_HIUSER		0xffffffff
-
-/**
- * ELF section flags
- */
-#define SHF_WRITE		0x1 
-#define SHF_ALLOC		0x2
-#define SHF_EXECINSTR		0x4
-#define SHF_MASKPROC		0xf0000000
-
-
-/**
- * Symbol binding
- */
-#define STB_LOCAL		0
-#define STB_GLOBAL		1
-#define STB_WEAK		2
-#define STB_LOPROC		13
-#define STB_HIPROC		15
-
-/**
- * Symbol types
- */
-#define STT_NOTYPE		0
-#define STT_OBJECT		1
-#define STT_FUNC		2
-#define STT_SECTION		3
-#define STT_FILE		4
-#define STT_LOPROC		13
-#define STT_HIPROC		15
-
-
-/**
- * Program segment types
- */
-#define PT_NULL			0
-#define PT_LOAD			1
-#define PT_DYNAMIC		2
-#define PT_INTERP		3
-#define PT_NOTE			4
-#define PT_SHLIB		5
-#define PT_PHDR			6
-#define PT_LOPROC		0x70000000
-#define PT_HIPROC		0x7fffffff
-
-/**
- * 32-bit ELF data types
- */
-typedef __u32 elf32_addr;
-typedef __u16 elf32_half;
-typedef __u32 elf32_off;
-typedef int elf32_sword;
-typedef __u32 elf32_word;
-
-/**
- * 32-bit ELF header
- */
-struct elf32_header {
-	__u8 e_ident[EI_NIDENT];
-	elf32_half e_type;
-	elf32_half e_machine;
-	elf32_word e_version;
-	elf32_addr e_entry;
-	elf32_off e_phoff;
-	elf32_off e_shoff;
-	elf32_word e_flags;
-	elf32_half e_ehsize;
-	elf32_half e_phentsize;
-	elf32_half e_phnum;
-	elf32_half e_shentsize;
-	elf32_half e_shnum;
-	elf32_half e_shstrndx;
-};
-
-
-/*
- * 32-bit ELF section header
- */
-struct elf32_section_header {
-	elf32_word sh_name;
-	elf32_word sh_type;
-	elf32_word sh_flags;
-	elf32_addr sh_addr;
-	elf32_off sh_offset;
-	elf32_word sh_size;
-	elf32_word sh_link;
-	elf32_word sh_info;
-	elf32_word sh_addralign;
-	elf32_word sh_entsize;
-};
-
-
-/*
- * 32-bit ELF symbol table entry
- */
-struct elf32_symbol {
-	elf32_word st_name;
-	elf32_addr st_value;
-	elf32_word st_size;
-	__u8 st_info;
-	__u8 st_other;
-	elf32_half st_shndx;
-};
-
-
-/*
- * 32-bit ELF program header
- */
-struct elf32_program_header {
-	elf32_word p_type;
-	elf32_off p_offset;
-	elf32_addr pv_addr;
-	elf32_addr pp_addr;
-	elf32_word p_filesz;
-	elf32_word p_memsz;
-	elf32_word p_flags;
-	elf32_word p_align;
-};
- 
-typedef struct elf32_header elf32_header_t;
-typedef struct elf32_section_header elf32_section_header_t;
-typedef struct elf32_symbol elf32_symbol_t;
-typedef struct elf32_program_header elf32_program_header_t;
-
-
-
-extern int elf32_load(__address header, as_t * as);
-
-#endif
Index: generic/include/elf64.h
===================================================================
--- generic/include/elf64.h	(revision a82500ce45577f8d8eb985c998aee0e0223090c1)
+++ 	(revision )
@@ -1,40 +1,0 @@
-/*
- * Copyright (C) 2006 Sergey Bondari
- * 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.
- */
-
-#ifndef __ELF64_H__
-#define __ELF64_H__
-
-#include <arch/types.h>
-#include <mm/as.h>
-
-/* remove later */
-#include <elf32.h>
-
-extern int elf64_load(__address header, as_t * as);
-
-#endif
Index: generic/include/userspace.h
===================================================================
--- generic/include/userspace.h	(revision a82500ce45577f8d8eb985c998aee0e0223090c1)
+++ generic/include/userspace.h	(revision de6b301a63efb6d81e9db05625bc3438102b9842)
@@ -30,5 +30,7 @@
 #define __USERSPACE_H__
 
-extern void userspace(void) __attribute__ ((noreturn)); /**< Switch to user-space (CPU user priviledge level) */
+#include <arch/types.h>
+
+extern void userspace(__address entry) __attribute__ ((noreturn)); /**< Switch to user-space (CPU user priviledge level) */
 
 #endif
Index: generic/src/lib/elf.c
===================================================================
--- generic/src/lib/elf.c	(revision de6b301a63efb6d81e9db05625bc3438102b9842)
+++ generic/src/lib/elf.c	(revision de6b301a63efb6d81e9db05625bc3438102b9842)
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2006 Sergey Bondari
+ * 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.
+ */
+
+#include <elf.h>
+#include <debug.h>
+#include <arch/types.h>
+#include <typedefs.h>
+#include <mm/as.h>
+#include <mm/frame.h>
+#include <print.h>
+#include <align.h>
+
+static char *error_codes[] = {
+	"no error",
+	"invalid image",
+	"address space error",
+	"incompatible image",
+	"unsupported image type",
+	"irrecoverable error"
+};
+
+static int program_header_entry(elf_header_t *header, elf_ph_entry_t *entry, as_t *as);
+static int load_segment(elf_header_t *header, elf_ph_entry_t *entry, as_t *as);
+
+/** ELF loader
+ *
+ * @param header Pointer to ELF header in memory
+ * @param as Created and properly mapped address space
+ * @return EE_OK on success
+ */
+int elf_load(elf_header_t *header, as_t * as)
+{
+	int i, rc;
+
+	/* Identify ELF */
+	if (header->e_ident[EI_MAG0] != ELFMAG0 || header->e_ident[EI_MAG1] != ELFMAG1 || 
+	    header->e_ident[EI_MAG2] != ELFMAG2 || header->e_ident[EI_MAG3] != ELFMAG3) {
+		return EE_INVALID;
+	}
+	
+	/* Identify ELF compatibility */
+	if (header->e_ident[EI_DATA] != ELF_DATA_ENCODING || header->e_machine != ELF_MACHINE || 
+	    header->e_ident[EI_VERSION] != EV_CURRENT || header->e_version != EV_CURRENT ||
+	    header->e_ident[EI_CLASS] != ELF_CLASS) {
+		return EE_INCOMPATIBLE;
+	}
+
+	if (header->e_phentsize != sizeof(elf_ph_entry_t))
+		return EE_INCOMPATIBLE;
+
+	/* Check if the object type is supported. */
+	if (header->e_type != ET_EXEC)
+		return EE_UNSUPPORTED;
+
+	/* Walk through all program header entries and process them. */
+	for (i = 0; i < header->e_phnum; i++) {
+		rc = program_header_entry(header, &((elf_ph_entry_t *)(((__u8 *) header) + header->e_phoff))[i], as);
+		if (rc != EE_OK)
+			return rc;
+	}
+
+	return EE_OK;
+}
+
+/** Print error message according to error code.
+ *
+ * @param rc Return code returned by elf_load().
+ *
+ * @return NULL terminated description of error.
+ */
+char *elf_error(int rc)
+{
+	ASSERT(rc < sizeof(error_codes)/sizeof(char *));
+
+	return error_codes[rc];
+}
+
+/** Process program header entry.
+ *
+ * @param entry Program header entry.
+ * @param as Address space into wich the ELF is being loaded.
+ *
+ * @return EE_OK on success, error code otherwise.
+ */
+static int program_header_entry(elf_header_t *header, elf_ph_entry_t *entry, as_t *as)
+{
+	switch (entry->p_type) {
+	    case PT_NULL:
+	    case PT_PHDR:
+		break;
+	    case PT_LOAD:
+		return load_segment(header, entry, as);
+		break;
+	    case PT_DYNAMIC:
+	    case PT_INTERP:
+	    case PT_SHLIB:
+	    case PT_NOTE:
+	    case PT_LOPROC:
+	    case PT_HIPROC:
+	    default:
+		return EE_UNSUPPORTED;
+		break;
+	}
+	return EE_OK;
+}
+
+/** Load segment described by program header entry.
+ *
+ * @param entry Program header entry describing segment to be loaded.
+ * @parma as Address space into wich the ELF is being loaded.
+ *
+ * @return EE_OK on success, error code otherwise.
+ */
+int load_segment(elf_header_t *header, elf_ph_entry_t *entry, as_t *as)
+{
+	as_area_t *a;
+	int i, type = 0;
+
+	if (entry->p_align > 1) {
+		if ((entry->p_offset % entry->p_align) != (entry->p_vaddr % entry->p_align)) {
+			return EE_INVALID;
+		}
+	}
+
+	/*
+	 * Check if the segment doesn't interfere with kernel address space.
+	 */
+	if (entry->p_vaddr + ALIGN_UP(entry->p_memsz, PAGE_SIZE) >= USER_ADDRESS_SPACE_END)
+		return EE_MEMORY;
+	
+	if (entry->p_flags & PF_X) {
+		type = AS_AREA_TEXT;
+	} else if (entry->p_flags & PF_W) {
+		type = AS_AREA_DATA;
+	} else {
+		return EE_UNSUPPORTED;
+	}
+
+	a = as_area_create(as, AS_AREA_TEXT, SIZE2FRAMES(entry->p_memsz), entry->p_vaddr);
+	if (!a)
+		return EE_IRRECOVERABLE;
+	
+	for (i = 0; i < SIZE2FRAMES(entry->p_filesz); i++) {
+		as_set_mapping(as, entry->p_vaddr + i*PAGE_SIZE, KA2PA(((__address) header) + entry->p_offset + i*PAGE_SIZE));
+	}
+	
+	return EE_OK;
+}
Index: generic/src/lib/elf32.c
===================================================================
--- generic/src/lib/elf32.c	(revision a82500ce45577f8d8eb985c998aee0e0223090c1)
+++ 	(revision )
@@ -1,58 +1,0 @@
-/*
- * Copyright (C) 2006 Sergey Bondari
- * 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.
- */
-
-#include <elf.h>
-
-/** 32bit ELF loader
- *
- * @param header Pointer to ELF header in memory
- * @param as Created and properly mapped address space
- * @return EE_OK on success
- */
-int elf32_load(__address header, as_t * as) {
-	elf32_header_t * e_header;
-
-	e_header = (elf32_header_t *) header;
-	
-	/* Identify ELF */
-	if (	e_header->e_ident[EI_MAG0] != ELFMAG0 || e_header->e_ident[EI_MAG1] != ELFMAG1 || 
-		e_header->e_ident[EI_MAG2] != ELFMAG2 || e_header->e_ident[EI_MAG3] != ELFMAG3
-		) {
-		return EE_INVALID;
-	}
-	
-	/* Identify ELF compatibility */
-	if (	e_header->e_ident[EI_DATA] != ELF_DATA_ENCODING || e_header->e_machine != ELF_MACHINE || 
-		e_header->e_ident[EI_VERSION] != EV_CURRENT || e_header->e_ident[EI_CLASS] != ELF_CLASS
-		) {
-		return EE_UNSUPPORTED;
-	}
-	
-
-	return EE_UNSUPPORTED;	
-}
Index: generic/src/lib/elf64.c
===================================================================
--- generic/src/lib/elf64.c	(revision a82500ce45577f8d8eb985c998aee0e0223090c1)
+++ 	(revision )
@@ -1,39 +1,0 @@
-/*
- * Copyright (C) 2006 Sergey Bondari
- * 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.
- */
-
-#include <elf.h>
-#include <elf64.h>
-/** 64bit ELF loader
- *
- * @param header Pointer to ELF header in memory
- * @param as Created and properly mapped address space
- * @return EE_OK on success
- */
-int elf64_load(__address header, as_t * as) {
-	return EE_UNSUPPORTED;	
-}
Index: generic/src/main/kinit.c
===================================================================
--- generic/src/main/kinit.c	(revision a82500ce45577f8d8eb985c998aee0e0223090c1)
+++ generic/src/main/kinit.c	(revision de6b301a63efb6d81e9db05625bc3438102b9842)
@@ -47,4 +47,5 @@
 #include <interrupt.h>
 #include <console/kconsole.h>
+#include <elf.h>
 
 #ifdef CONFIG_SMP
@@ -72,7 +73,5 @@
 	as_t *as;
 	as_area_t *a;
-	__address frame;
-	count_t frames;
-	int i;
+	int rc;
 	task_t *u;
 
@@ -151,36 +150,25 @@
 		if (!as)
 			panic("as_create\n");
-		u = task_create(as);
-		if (!u)
-			panic("task_create\n");
-		t = thread_create(uinit, NULL, u, THREAD_USER_STACK);
-		if (!t)
-			panic("thread_create\n");
+
+		rc = elf_load((elf_header_t *) config.init_addr, as);
+		if (rc != EE_OK) {
+			printf("elf_load failed: %s\n", elf_error(rc));
+		} else {
+			u = task_create(as);
+			if (!u)
+				panic("task_create\n");
+			t = thread_create(uinit, (void *)((elf_header_t *) config.init_addr)->e_entry, u, THREAD_USER_STACK);
+			if (!t)
+				panic("thread_create\n");
 		
-		/*
-		 * Create the text as_area and initialize its mapping.
-		 */
-		
-		frame = config.init_addr;
-		if (IS_KA(frame))
-			frame = KA2PA(frame);
+			/*
+			 * Create the data as_area.
+			 */
+			a = as_area_create(as, AS_AREA_STACK, 1, USTACK_ADDRESS);
+			if (!a)
+				panic("as_area_create: stack\n");
 
-		frames = SIZE2FRAMES(config.init_size);
-		
-		a = as_area_create(as, AS_AREA_TEXT, frames, UTEXT_ADDRESS);
-		if (!a)
-			panic("as_area_create: text\n");
-
-		for (i = 0; i < frames; i++)
-			as_set_mapping(as, UTEXT_ADDRESS + i * PAGE_SIZE, frame + i * FRAME_SIZE);
-
-		/*
-		 * Create the data as_area.
-		 */
-		a = as_area_create(as, AS_AREA_STACK, 1, USTACK_ADDRESS);
-		if (!a)
-			panic("as_area_create: stack\n");
-
-		thread_ready(t);
+			thread_ready(t);
+		}
 	}
 
Index: generic/src/main/uinit.c
===================================================================
--- generic/src/main/uinit.c	(revision a82500ce45577f8d8eb985c998aee0e0223090c1)
+++ generic/src/main/uinit.c	(revision de6b301a63efb6d81e9db05625bc3438102b9842)
@@ -33,8 +33,7 @@
 #include <print.h>
 
-
 void uinit(void *arg)
 {
 	printf("USER task, uinit thread: kernel mode\n");
-	userspace();
+	userspace((__address)(arg));
 }
