Index: arch/mips32/Makefile.inc
===================================================================
--- arch/mips32/Makefile.inc	(revision 2d1a1d4c2542f956c141f8a30e4ee0f37611ad14)
+++ arch/mips32/Makefile.inc	(revision 25f089b982bba230a83e2b3d69302ff8c9d388f7)
@@ -30,5 +30,5 @@
 
 image.boot: kernel uspace
-	make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNEL=../../../$(KERNELDIR)/kernel.bin
+	make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR)
 	cp arch/$(ARCH)/loader/image.boot image.boot
 
Index: arch/mips32/loader/Makefile
===================================================================
--- arch/mips32/loader/Makefile	(revision 2d1a1d4c2542f956c141f8a30e4ee0f37611ad14)
+++ arch/mips32/loader/Makefile	(revision 25f089b982bba230a83e2b3d69302ff8c9d388f7)
@@ -52,10 +52,22 @@
 SOURCES = \
 	main.c \
+	msim.c \
 	printf.c \
-	msim.c \
 	asm.S \
 	boot.S
 
+COMPONENTS = \
+	$(KERNELDIR)/kernel.bin \
+	$(USPACEDIR)/ns/ns \
+	$(USPACEDIR)/init/init \
+	$(USPACEDIR)/fb/fb \
+	$(USPACEDIR)/kbd/kbd \
+	$(USPACEDIR)/console/console \
+	$(USPACEDIR)/tetris/tetris \
+	$(USPACEDIR)/ipcc/ipcc \
+	$(USPACEDIR)/klog/klog
+
 OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS))))
 
 .PHONY: all clean depend
@@ -65,6 +77,6 @@
 -include Makefile.depend
 
-image.boot: depend $(OBJECTS) kernel.o
-	$(LD) -no-check-sections -N -T _link.ld $(OBJECTS) kernel.o -o $@
+image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) kernel.o 
+	$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@
 
 depend:
@@ -72,8 +84,8 @@
 
 clean:
-	-rm -f $(OBJECTS) image.boot kernel.o Makefile.depend
+	-rm -f _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) image.boot Makefile.depend
 
-kernel.o: $(KERNEL)
-	$(OBJCOPY) -I binary -O elf32-tradlittlemips -B mips $(KERNEL) $@
+_components.h _link.ld $(COMPONENT_OBJECTS): $(COMPONENTS)
+	./pack $(OBJCOPY) $(COMPONENTS)
 
 %.o: %.S
Index: ch/mips32/loader/_link.ld
===================================================================
--- arch/mips32/loader/_link.ld	(revision 2d1a1d4c2542f956c141f8a30e4ee0f37611ad14)
+++ 	(revision )
@@ -1,24 +1,0 @@
-/*
- *  MIPS linker script
- *
- */
-
-OUTPUT_FORMAT(binary)
-ENTRY(start)
-
-SECTIONS {
-	.image 0xbfc00000: AT (0) { 
-		*(BOOTSTRAP)
-		*(.text);
-		
-		*(.rodata);
-		*(.rodata.*);
-		*(.data);		/* initialized data */
-		*(.sdata);
-		*(.sdata2);
-		*(.sbss);
-		*(.bss);		/* uninitialized static variables */	
-		*(COMMON); 		/* global variables */
-		*(.reginfo);
-	}
-}
Index: arch/mips32/loader/asm.S
===================================================================
--- arch/mips32/loader/asm.S	(revision 2d1a1d4c2542f956c141f8a30e4ee0f37611ad14)
+++ arch/mips32/loader/asm.S	(revision 25f089b982bba230a83e2b3d69302ff8c9d388f7)
@@ -36,4 +36,5 @@
 
 .global halt
+.global memcpy
 .global jump_to_kernel
 
@@ -41,4 +42,67 @@
 	b halt
 	nop
+	
+memcpy:
+	addiu	$v0,$a1,3
+	li	$v1,-4			# 0xfffffffffffffffc
+	and	$v0,$v0,$v1
+	beq	$a1,$v0,3f
+	move	$t0,$a0
+
+0:
+	beq	$a2,$zero,2f
+	move	$a3,$zero
+
+1:
+	addu	$v0,$a1,$a3
+	lbu	$a0,0($v0)
+	addu	$v1,$t0,$a3
+	addiu	$a3,$a3,1
+	bne	$a3,$a2,1b
+	sb	$a0,0($v1)
+
+2:
+	jr	$ra
+	move	$v0,$a1
+
+3:
+	addiu	$v0,$a0,3
+	and	$v0,$v0,$v1
+	bne	$a0,$v0,0b
+	srl	$t1,$a2,2
+
+	beq	$t1,$zero,5f
+	move	$a3,$zero
+
+	move	$a3,$zero
+	move	$a0,$zero
+4:
+	addu	$v0,$a1,$a0
+	lw	$v1,0($v0)
+	addiu	$a3,$a3,1
+	addu	$v0,$t0,$a0
+	sw	$v1,0($v0)
+	bne	$a3,$t1,4b
+	addiu	$a0,$a0,4
+
+5:
+	andi	$a2,$a2,0x3
+	beq	$a2,$zero,2b
+	nop
+
+	sll	$v0,$a3,2
+	addu	$t1,$v0,$t0
+	move	$a3,$zero
+	addu	$t0,$v0,$a1
+6:
+	addu	$v0,$t0,$a3
+	lbu	$a0,0($v0)
+	addu	$v1,$t1,$a3
+	addiu	$a3,$a3,1
+	bne	$a3,$a2,6b
+	sb	$a0,0($v1)
+
+	jr	$ra
+	move	$v0,$a1
 
 jump_to_kernel:
Index: arch/mips32/loader/asm.h
===================================================================
--- arch/mips32/loader/asm.h	(revision 2d1a1d4c2542f956c141f8a30e4ee0f37611ad14)
+++ arch/mips32/loader/asm.h	(revision 25f089b982bba230a83e2b3d69302ff8c9d388f7)
@@ -30,5 +30,10 @@
 #define __ASM_H__
 
-void jump_to_kernel(void *code) __attribute__((noreturn));
+#define PAGE_SIZE 16384
+#define PAGE_WIDTH 14
+
+#define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
+
+void jump_to_kernel(void *entry, void *bootinfo, unsigned int bootinfo_size) __attribute__((noreturn));
 
 #endif
Index: arch/mips32/loader/boot.S
===================================================================
--- arch/mips32/loader/boot.S	(revision 2d1a1d4c2542f956c141f8a30e4ee0f37611ad14)
+++ arch/mips32/loader/boot.S	(revision 25f089b982bba230a83e2b3d69302ff8c9d388f7)
@@ -29,5 +29,5 @@
 #include "regname.h"
 
-#define INITIAL_STACK 0x10000
+#define INITIAL_STACK 0x40000
 
 .set noat
@@ -40,6 +40,6 @@
 start:
 	lui $sp, INITIAL_STACK >> 16
-    ori $sp, $sp, INITIAL_STACK & 0xffff	
-
+	ori $sp, $sp, INITIAL_STACK & 0xffff
+	
 	j bootstrap
 	nop
Index: arch/mips32/loader/main.c
===================================================================
--- arch/mips32/loader/main.c	(revision 2d1a1d4c2542f956c141f8a30e4ee0f37611ad14)
+++ arch/mips32/loader/main.c	(revision 25f089b982bba230a83e2b3d69302ff8c9d388f7)
@@ -31,26 +31,41 @@
 #include "msim.h"
 #include "asm.h"
+#include "_components.h"
 
 #define KERNEL_VIRTUAL_ADDRESS 0x80100000
-#define KERNEL_START &_binary_____________kernel_kernel_bin_start
-#define KERNEL_END &_binary_____________kernel_kernel_bin_end
-#define KERNEL_SIZE ((unsigned int) KERNEL_END - (unsigned int) KERNEL_START)
 
 void bootstrap(void)
 {
 	printf("HelenOS MIPS Bootloader\n");
-	printf("loaded at %L\n", &start);
-	printf("kernel memory at %L (size %d bytes)\n", KERNEL_VIRTUAL_ADDRESS, KERNEL_SIZE);
 	
-	// TODO: implement memcpy
-	int i;
-	for (i = 0; i < KERNEL_SIZE; i++) {
-		if (i % 4096 == 0)
-			printf(".");
-		((char *) KERNEL_VIRTUAL_ADDRESS)[i] = ((char *) KERNEL_START)[i];
+	component_t components[COMPONENTS];
+	bootinfo_t bootinfo;
+	init_components(components);
+	
+	printf("\nMemory statistics\n");
+	printf(" kernel entry point at %L\n", KERNEL_VIRTUAL_ADDRESS);
+	printf(" %L: boot info structure\n", &bootinfo);
+	
+	unsigned int i;
+	for (i = 0; i < COMPONENTS; i++)
+		printf(" %L: %s image (size %d bytes)\n", components[i].start, components[i].name, components[i].size);
+	
+	printf("\nCopying components\n");
+	unsigned int top = 0;
+	bootinfo.cnt = 0;
+	for (i = 0; i < COMPONENTS; i++) {
+		printf(" %s...", components[i].name);
+		top = ALIGN_UP(top, PAGE_SIZE);
+		memcpy(((void *) KERNEL_VIRTUAL_ADDRESS) + top, components[i].start, components[i].size);
+		if (i > 0) {
+			bootinfo.tasks[bootinfo.cnt].addr = ((void *) KERNEL_VIRTUAL_ADDRESS) + top;
+			bootinfo.tasks[bootinfo.cnt].size = components[i].size;
+			bootinfo.cnt++;
+		}
+		top += components[i].size;
+		printf("done.\n");
 	}
 	
 	printf("\nBooting the kernel...\n");
-	
-	jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS);
+	jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, &bootinfo, sizeof(bootinfo));
 }
Index: arch/mips32/loader/main.h
===================================================================
--- arch/mips32/loader/main.h	(revision 2d1a1d4c2542f956c141f8a30e4ee0f37611ad14)
+++ arch/mips32/loader/main.h	(revision 25f089b982bba230a83e2b3d69302ff8c9d388f7)
@@ -30,6 +30,23 @@
 #define __MAIN_H__
 
-extern int _binary_____________kernel_kernel_bin_start;
-extern int _binary_____________kernel_kernel_bin_end;
+/** Align to the nearest higher address.
+ *
+ * @param addr  Address or size to be aligned.
+ * @param align Size of alignment, must be power of 2.
+ */
+#define ALIGN_UP(addr, align) (((addr) + ((align) - 1)) & ~((align) - 1))
+
+#define TASKMAP_MAX_RECORDS 32
+
+typedef struct {
+	void *addr;
+	unsigned int size;
+} task_t;
+
+typedef struct {
+	unsigned int cnt;
+	task_t tasks[TASKMAP_MAX_RECORDS];
+} bootinfo_t;
+
 extern void start(void);
 extern void bootstrap(void);
Index: arch/mips32/loader/pack
===================================================================
--- arch/mips32/loader/pack	(revision 25f089b982bba230a83e2b3d69302ff8c9d388f7)
+++ arch/mips32/loader/pack	(revision 25f089b982bba230a83e2b3d69302ff8c9d388f7)
@@ -0,0 +1,113 @@
+#! /bin/sh
+
+#
+# Copyright (C) 2006 Martin Decky
+# 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.
+#
+
+[ "$#" -lt 1 ] && exit 1
+
+OBJCOPY="$1"
+LINK="_link.ld"
+HEADER="_components.h"
+
+shift
+
+echo 'OUTPUT_FORMAT("binary")
+ENTRY(start)
+
+SECTIONS {
+	.boot 0xbfc00000: AT (0) {
+		*(BOOTSTRAP);
+		*(.text);
+		
+		*(.rodata);
+		*(.rodata.*);
+		*(.data);		/* initialized data */
+		*(.sdata);
+		*(.sdata2);
+		*(.sbss);
+		*(.scommon);
+		*(.bss);		/* uninitialized static variables */	
+		*(COMMON); 		/* global variables */
+		*(.reginfo);' > "$LINK"
+
+echo '#ifndef ___COMPONENTS_H__
+#define ___COMPONENTS_H__
+
+typedef struct {
+	char *name;
+	
+	void *start;
+	void *end;
+	unsigned int size;
+} component_t;' > "$HEADER"
+
+COUNT="0"
+DATA=""
+
+for TASK in "$@" ; do
+	BASENAME="`basename "$TASK" | sed 's/^\(.*\)\.[^.]*$/\1/'`"
+	OBJECT="${BASENAME}.o"
+	SYMBOL="`echo "_binary_$TASK" | tr "./" "__"`"
+	MACRO="`echo "$BASENAME" | tr [:lower:] [:upper:]`"
+	echo "$TASK -> $OBJECT"
+	
+	echo "
+		. = ALIGN(4096);
+		*(.${BASENAME}_image);" >> "$LINK"
+	
+	echo "
+extern int ${SYMBOL}_start;
+extern int ${SYMBOL}_end;
+
+#define ${MACRO}_START ((void *) &${SYMBOL}_start)
+#define ${MACRO}_END ((void *) &${SYMBOL}_end)
+#define ${MACRO}_SIZE ((unsigned int) ${MACRO}_END - (unsigned int) ${MACRO}_START)" >> "$HEADER"
+	
+	"$OBJCOPY" -I binary -O elf32-tradlittlemips -B mips --rename-section ".data=.${BASENAME}_image" "$TASK" "$OBJECT"
+		
+	DATA="${DATA}
+	components[$COUNT].name = \"${BASENAME}\";
+	components[$COUNT].start = ${MACRO}_START;
+	components[$COUNT].end = ${MACRO}_END;
+	components[$COUNT].size = ${MACRO}_SIZE;";
+	COUNT="`expr "$COUNT" + 1`"
+done
+
+echo '	}
+}' >> "$LINK"
+
+echo "
+#define COMPONENTS $COUNT
+
+static void init_components(component_t components[])
+{
+$DATA
+}
+
+#endif
+" >> "$HEADER"
Index: arch/mips32/loader/printf.h
===================================================================
--- arch/mips32/loader/printf.h	(revision 2d1a1d4c2542f956c141f8a30e4ee0f37611ad14)
+++ arch/mips32/loader/printf.h	(revision 25f089b982bba230a83e2b3d69302ff8c9d388f7)
@@ -39,6 +39,6 @@
 typedef unsigned char __u8;
 typedef unsigned short __u16;
-typedef unsigned long __u32;
-typedef long long __u64;
+typedef unsigned int __u32;
+typedef unsigned long long __u64;
 
 typedef __u32 __address;
