Index: kernel/generic/src/main/kinit.c
===================================================================
--- kernel/generic/src/main/kinit.c	(revision 41deb2ae92352629298dc5b5343d48f3edee449f)
+++ kernel/generic/src/main/kinit.c	(revision d46732962adcfcbf946c2c3f032af0f7fadb285c)
@@ -57,4 +57,5 @@
 #include <mm/as.h>
 #include <mm/frame.h>
+#include <mm/km.h>
 #include <print.h>
 #include <memstr.h>
@@ -68,4 +69,5 @@
 #include <str.h>
 #include <sysinfo/stats.h>
+#include <align.h>
 
 #ifdef CONFIG_SMP
@@ -178,5 +180,5 @@
 	
 	for (i = 0; i < init.cnt; i++) {
-		if (init.tasks[i].addr % FRAME_SIZE) {
+		if (init.tasks[i].paddr % FRAME_SIZE) {
 			printf("init[%zu]: Address is not frame aligned\n", i);
 			programs[i].task = NULL;
@@ -199,7 +201,24 @@
 		str_cpy(namebuf + INIT_PREFIX_LEN,
 		    TASK_NAME_BUFLEN - INIT_PREFIX_LEN, name);
-		
-		int rc = program_create_from_image((void *) init.tasks[i].addr,
-		    namebuf, &programs[i]);
+
+		/*
+		 * Create virtual memory mappings for init task images.
+		 */
+		size_t size = ALIGN_UP(init.tasks[i].size, PAGE_SIZE);
+		size_t offs;
+		uintptr_t page = km_page_alloc(size, PAGE_SIZE);
+		uintptr_t frame = init.tasks[i].paddr;
+
+		page_table_lock(AS_KERNEL, true);
+		for (offs = 0; offs < size; offs += PAGE_SIZE) {
+			page_mapping_insert(AS_KERNEL, page + offs,
+			    frame + offs,
+			    PAGE_READ | PAGE_WRITE | PAGE_CACHEABLE |
+			    PAGE_PRESENT);
+		}
+		page_table_unlock(AS_KERNEL, true);
+		
+		int rc = program_create_from_image((void *) page, namebuf,
+		    &programs[i]);
 		
 		if (rc == 0) {
@@ -224,5 +243,5 @@
 			 * Assume the last task is the RAM disk.
 			 */
-			init_rd((void *) init.tasks[i].addr, init.tasks[i].size);
+			init_rd((void *) frame, init.tasks[i].size);
 		} else
 			printf("init[%zu]: Init binary load failed (error %d)\n", i, rc);
Index: kernel/generic/src/main/main.c
===================================================================
--- kernel/generic/src/main/main.c	(revision 41deb2ae92352629298dc5b5343d48f3edee449f)
+++ kernel/generic/src/main/main.c	(revision d46732962adcfcbf946c2c3f032af0f7fadb285c)
@@ -151,8 +151,15 @@
 	size_t i;
 	for (i = 0; i < init.cnt; i++) {
-		if (PA_OVERLAPS(config.stack_base, config.stack_size,
-		    init.tasks[i].addr, init.tasks[i].size))
-			config.stack_base = ALIGN_UP(init.tasks[i].addr +
-			    init.tasks[i].size, config.stack_size);
+		if (overlaps(KA2PA(config.stack_base), config.stack_size,
+		    init.tasks[i].paddr, init.tasks[i].size)) {
+			/*
+			 * The init task overlaps with the memory behind the
+			 * kernel image so it must be in low memory and we can
+			 * use PA2KA on the init task's physical address.
+			 */
+			config.stack_base = ALIGN_UP(
+			    PA2KA(init.tasks[i].paddr) + init.tasks[i].size,
+			    config.stack_size);
+		}
 	}
 	
