Index: arch/amd64/src/boot/boot.S
===================================================================
--- arch/amd64/src/boot/boot.S	(revision 8dfef11fc8d83f91532e1905a1f846c9a6fb4da9)
+++ arch/amd64/src/boot/boot.S	(revision b6b576cff6e554b94baf578554e7488d2ac08253)
@@ -173,6 +173,6 @@
 		
 		mods_invalid:
-		movq %rcx, init_size
-		movq %rdx, init_addr
+#		movq %rcx, init_size
+#		movq %rdx, init_addr
 		
 		bt $6, %eax								# mbi->flags[6] (mmap_length, mmap_addr valid)	
Index: arch/ia32/src/boot/boot.S
===================================================================
--- arch/ia32/src/boot/boot.S	(revision 8dfef11fc8d83f91532e1905a1f846c9a6fb4da9)
+++ arch/ia32/src/boot/boot.S	(revision b6b576cff6e554b94baf578554e7488d2ac08253)
@@ -100,25 +100,38 @@
 		movl %ecx, e801memorysize
 		
-		bt $3, %eax								# mbi->flags[3] (mods_count, mods_addr valid)	
+		bt $3, %eax								# mbi->flags[3] (mods_count, mods_addr valid)
 		jc mods_valid
 			
 			xorl %ecx, %ecx
-			xorl %edx, %edx
-			jmp mods_invalid
+			movl %ecx, init
+			jmp mods_end
 		
 		mods_valid:
+		
 		movl 20(%ebx), %ecx						# mbi->mods_count
+		movl %ecx, init
+		
 		cmpl $0, %ecx
-		je mods_invalid
+		je mods_end
 		
 		movl 24(%ebx), %esi						# mbi->mods_addr
-		movl 0(%esi), %edx						# mods->mod_start
-		movl 4(%esi), %ecx						# mods->mod_end
-		subl %edx, %ecx
-		addl $0x80000000, %edx
-		
-		mods_invalid:
-		movl %ecx, init_size
-		movl %edx, init_addr
+		movl $init, %edi
+		
+		mods_loop:
+		
+			movl 0(%esi), %edx					# mods->mod_start
+			addl $0x80000000, %edx
+			movl %edx, 4(%edi)
+			
+			movl 4(%esi), %edx
+			subl 0(%esi), %edx					# mods->mod_end - mods->mod_start
+			movl %edx, 8(%edi)
+			
+			addl $16, %esi
+			addl $8	, %edi
+			
+			loop mods_loop
+			
+		mods_end:
 		
 		bt $6, %eax								# mbi->flags[6] (mmap_length, mmap_addr valid)	
Index: arch/mips32/src/mips32.c
===================================================================
--- arch/mips32/src/mips32.c	(revision 8dfef11fc8d83f91532e1905a1f846c9a6fb4da9)
+++ arch/mips32/src/mips32.c	(revision b6b576cff6e554b94baf578554e7488d2ac08253)
@@ -94,7 +94,9 @@
 	console_init();
 	debugger_init();
-	/* Setup usermode...*/
-	config.init_addr = INIT_ADDRESS;
-	config.init_size = INIT_SIZE;
+	
+	/* Setup usermode */
+	init.cnt = 1;
+	init.tasks[0].addr = INIT_ADDRESS;
+	init.tasks[0].size = INIT_SIZE;
 }
 
Index: generic/include/config.h
===================================================================
--- generic/include/config.h	(revision 8dfef11fc8d83f91532e1905a1f846c9a6fb4da9)
+++ generic/include/config.h	(revision b6b576cff6e554b94baf578554e7488d2ac08253)
@@ -36,8 +36,19 @@
 #define STACK_SIZE		PAGE_SIZE
 
-#define CONFIG_MEMORY_SIZE	(8*1024*1024)
+#define CONFIG_MEMORY_SIZE	(8 * 1024 * 1024)
 #define CONFIG_STACK_SIZE	STACK_SIZE
+#define CONFIG_INIT_TASKS	32
 
-struct config {
+typedef struct {
+	__address addr;
+	size_t size;
+} init_task_t;
+
+typedef struct {
+	count_t cnt;
+	init_task_t tasks[CONFIG_INIT_TASKS];
+} init_t;
+
+typedef struct {
 	count_t cpu_count;
 	volatile count_t cpu_active;
@@ -45,12 +56,9 @@
 	__address base;
 	size_t memory_size;
-	
-	__address init_addr;
-	size_t init_size;
-	
 	size_t kernel_size;           /**< Size of memory in bytes taken by kernel and stack */
-};
+} config_t;
 
 extern config_t config;
+extern init_t init;
 
 #endif
Index: generic/include/typedefs.h
===================================================================
--- generic/include/typedefs.h	(revision 8dfef11fc8d83f91532e1905a1f846c9a6fb4da9)
+++ generic/include/typedefs.h	(revision b6b576cff6e554b94baf578554e7488d2ac08253)
@@ -41,5 +41,4 @@
 typedef unsigned long long task_id_t;
 
-typedef struct config config_t;
 typedef struct cpu_info cpu_info_t;
 
Index: generic/src/main/kinit.c
===================================================================
--- generic/src/main/kinit.c	(revision 8dfef11fc8d83f91532e1905a1f846c9a6fb4da9)
+++ generic/src/main/kinit.c	(revision b6b576cff6e554b94baf578554e7488d2ac08253)
@@ -133,14 +133,15 @@
 
 	interrupts_enable();
-
-	if (config.init_size > 0) {
+	
+	count_t i;
+	for (i = 0; i < init.cnt; i++) {
 		/*
-		 * Create the first user task.
+		 * Run user tasks.
 		 */
 		
-		if (config.init_addr % FRAME_SIZE)
-			panic("config.init_addr is not frame aligned");
+		if (init.tasks[i].addr % FRAME_SIZE)
+			panic("init[%d].addr is not frame aligned", i);
 
-		utask = task_run_program((void *)config.init_addr);
+		utask = task_run_program((void *) init.tasks[i].addr);
 		if (utask) 
 			ipc_phone_0 = &utask->answerbox;
Index: generic/src/main/main.c
===================================================================
--- generic/src/main/main.c	(revision 8dfef11fc8d83f91532e1905a1f846c9a6fb4da9)
+++ generic/src/main/main.c	(revision b6b576cff6e554b94baf578554e7488d2ac08253)
@@ -64,4 +64,5 @@
 
 config_t config;	/**< Global configuration structure. */
+init_t init = {0};  /**< Initial user-space tasks */
 
 context_t ctx;
@@ -75,7 +76,4 @@
 size_t hardcoded_ktext_size = 0;
 size_t hardcoded_kdata_size = 0;
-
-__address init_addr = 0;
-size_t init_size = 0;
 
 void main_bsp(void);
@@ -111,19 +109,20 @@
 	config.base = hardcoded_load_address;
 	config.memory_size = get_memory_size();
-	config.init_addr = init_addr;
-	config.init_size = init_size;
 	
 	config.kernel_size = ALIGN_UP(hardcoded_ktext_size + hardcoded_kdata_size, PAGE_SIZE);
 	stackaddr = config.base + config.kernel_size;
+	
 	/* Avoid placing kernel on top of init */
-	if (overlaps(stackaddr,CONFIG_STACK_SIZE,
-		     config.init_addr, config.init_size)) {
-		
-		stackaddr = ALIGN_UP(config.init_addr+config.init_size,
-				     CONFIG_STACK_SIZE);
-		config.init_size = ALIGN_UP(config.init_size,CONFIG_STACK_SIZE) + CONFIG_STACK_SIZE;
-	} else {
+	count_t i;
+	bool overlap = false;
+	for (i = 0; i < init.cnt; i++)
+		if (overlaps(stackaddr, CONFIG_STACK_SIZE, init.tasks[i].addr, init.tasks[i].size)) {
+			stackaddr = ALIGN_UP(init.tasks[i].addr + init.tasks[i].size, CONFIG_STACK_SIZE);
+			init.tasks[i].size = ALIGN_UP(init.tasks[i].size, CONFIG_STACK_SIZE) + CONFIG_STACK_SIZE;
+			overlap = true;
+		}
+	
+	if (!overlap)
 		config.kernel_size += CONFIG_STACK_SIZE;
-	}
 	
 	context_save(&ctx);
@@ -152,5 +151,5 @@
 	 */
 	kconsole_init();
-
+	
 	/*
 	 * Exception handler initialization, before architecture
@@ -190,6 +189,7 @@
 	thread_init();
 	
-	if (config.init_size > 0)
-		printf("config.init_addr=%P, config.init_size=%d\n", config.init_addr, config.init_size);
+	count_t i;
+	for (i = 0; i < init.cnt; i++)
+		printf("init[%d].addr=%P, init[%d].size=%d\n", i, init.tasks[i].addr, i, init.tasks[i].size);
 	
 	ipc_init();
Index: generic/src/mm/frame.c
===================================================================
--- generic/src/mm/frame.c	(revision 8dfef11fc8d83f91532e1905a1f846c9a6fb4da9)
+++ generic/src/mm/frame.c	(revision b6b576cff6e554b94baf578554e7488d2ac08253)
@@ -135,7 +135,7 @@
 	spinlock_lock(&zones.lock);
 	/* Try to merge */
-	if (zones.count+1 == ZONES_MAX)
+	if (zones.count + 1 == ZONES_MAX)
 		panic("Maximum zone(%d) count exceeded.", ZONES_MAX);
-	for (i=0; i < zones.count; i++) {
+	for (i = 0; i < zones.count; i++) {
 		/* Check for overflow */
 		z = zones.info[i];
@@ -149,6 +149,6 @@
 	}
 	/* Move other zones up */
-	for (j=i;j < zones.count;j++)
-		zones.info[j+1] = zones.info[j];
+	for (j = i;j < zones.count; j++)
+		zones.info[j + 1] = zones.info[j];
 	zones.info[i] = newzone;
 	zones.count++;
@@ -690,6 +690,6 @@
 	/* Replace existing zones in zoneinfo list */
 	zones.info[z1] = newzone;
-	for (i=z2+1;i < zones.count;i++)
-		zones.info[i-1] = zones.info[i];
+	for (i = z2 + 1; i < zones.count; i++)
+		zones.info[i - 1] = zones.info[i];
 	zones.count--;
 
@@ -809,17 +809,22 @@
 	confcount = SIZE2FRAMES(zone_conf_size(count));
 	if (confframe >= start && confframe < start+count) {
-		for (;confframe < start+count;confframe++) {
+		for (;confframe < start + count; confframe++) {
 			addr = PFN2ADDR(confframe);
-			if (overlaps(addr, PFN2ADDR(confcount),
-				     KA2PA(config.base),config.kernel_size))
+			if (overlaps(addr, PFN2ADDR(confcount), KA2PA(config.base), config.kernel_size))
 				continue;
-			if (config.init_addr)
-				if (overlaps(addr,PFN2ADDR(confcount), 
-					     KA2PA(config.init_addr),
-					     config.init_size))
-					continue;
+			
+			bool overlap = false;
+			count_t i;
+			for (i = 0; i < init.cnt; i++)
+				if (overlaps(addr, PFN2ADDR(confcount), KA2PA(init.tasks[i].addr), init.tasks[i].size)) {
+					overlap = true;
+					break;
+				}
+			if (overlap)
+				continue;
+			
 			break;
 		}
-		if (confframe >= start+count)
+		if (confframe >= start + count)
 			panic("Cannot find configuration data for zone.");
 	}
@@ -990,7 +995,8 @@
 		pfn_t lastframe = ADDR2PFN(KA2PA(config.base+config.kernel_size));
 		frame_mark_unavailable(firstframe,lastframe-firstframe+1);
-		if (config.init_size > 0)
-			frame_mark_unavailable(ADDR2PFN(KA2PA(config.init_addr)),
-					       SIZE2FRAMES(config.init_size));
+		
+		count_t i;
+		for (i = 0; i < init.cnt; i++)
+			frame_mark_unavailable(ADDR2PFN(KA2PA(init.tasks[i].addr)), SIZE2FRAMES(init.tasks[i].size));
 	}
 }
@@ -1010,5 +1016,5 @@
 	printf("#  Base address\tFree Frames\tBusy Frames\n");
 	printf("   ------------\t-----------\t-----------\n");
-	for (i=0;i<zones.count;i++) {
+	for (i = 0; i < zones.count; i++) {
 		zone = zones.info[i];
 		spinlock_lock(&zone->lock);
@@ -1033,5 +1039,5 @@
 	spinlock_lock(&zones.lock);
 
-	for (i=0;i < zones.count; i++) {
+	for (i = 0; i < zones.count; i++) {
 		if (i == num || PFN2ADDR(zones.info[i]->base) == num) {
 			zone = zones.info[i];
