Index: kernel/generic/include/config.h
===================================================================
--- kernel/generic/include/config.h	(revision 7943c43ec7446695410d2e5521eb8121555e8c0c)
+++ kernel/generic/include/config.h	(revision 4dee0cb265758a5ee4132e646c801b976b22f908)
@@ -53,5 +53,5 @@
 
 typedef struct {
-	uintptr_t addr;
+	uintptr_t paddr;
 	size_t size;
 	char name[CONFIG_TASK_NAME_BUFLEN];
Index: kernel/generic/src/lib/rd.c
===================================================================
--- kernel/generic/src/lib/rd.c	(revision 7943c43ec7446695410d2e5521eb8121555e8c0c)
+++ kernel/generic/src/lib/rd.c	(revision 4dee0cb265758a5ee4132e646c801b976b22f908)
@@ -54,5 +54,5 @@
 void init_rd(void *data, size_t size)
 {
-	uintptr_t base = KA2PA((uintptr_t) data);
+	uintptr_t base = (uintptr_t) data;
 	ASSERT((base % FRAME_SIZE) == 0);
 	
Index: kernel/generic/src/main/kinit.c
===================================================================
--- kernel/generic/src/main/kinit.c	(revision 7943c43ec7446695410d2e5521eb8121555e8c0c)
+++ kernel/generic/src/main/kinit.c	(revision 4dee0cb265758a5ee4132e646c801b976b22f908)
@@ -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 7943c43ec7446695410d2e5521eb8121555e8c0c)
+++ kernel/generic/src/main/main.c	(revision 4dee0cb265758a5ee4132e646c801b976b22f908)
@@ -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);
+		}
 	}
 	
Index: kernel/generic/src/mm/backend_elf.c
===================================================================
--- kernel/generic/src/mm/backend_elf.c	(revision 7943c43ec7446695410d2e5521eb8121555e8c0c)
+++ kernel/generic/src/mm/backend_elf.c	(revision 4dee0cb265758a5ee4132e646c801b976b22f908)
@@ -318,5 +318,11 @@
 			dirty = true;
 		} else {
-			frame = KA2PA(base + i * FRAME_SIZE);
+			pte_t *pte = page_mapping_find(AS_KERNEL,
+			    base + i * FRAME_SIZE, true);
+
+			ASSERT(pte);
+			ASSERT(PTE_PRESENT(pte));
+
+			frame = PTE_GET_FRAME(pte);
 		}	
 	} else if (upage >= start_anon) {
Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision 7943c43ec7446695410d2e5521eb8121555e8c0c)
+++ kernel/generic/src/mm/frame.c	(revision 4dee0cb265758a5ee4132e646c801b976b22f908)
@@ -924,5 +924,5 @@
 				for (i = 0; i < init.cnt; i++)
 					if (overlaps(addr, PFN2ADDR(confcount),
-					    KA2PA(init.tasks[i].addr),
+					    init.tasks[i].paddr,
 					    init.tasks[i].size)) {
 						overlap = true;
@@ -1251,5 +1251,5 @@
 		size_t i;
 		for (i = 0; i < init.cnt; i++) {
-			pfn_t pfn = ADDR2PFN(KA2PA(init.tasks[i].addr));
+			pfn_t pfn = ADDR2PFN(init.tasks[i].paddr);
 			frame_mark_unavailable(pfn,
 			    SIZE2FRAMES(init.tasks[i].size));
