Index: arch/ppc32/loader/_link.ld
===================================================================
--- arch/ppc32/loader/_link.ld	(revision 272c219e3ddf80a692df97f90426eb3342bcfe13)
+++ arch/ppc32/loader/_link.ld	(revision eebd1727f19f91cad2c6b8735c13af094078d172)
@@ -8,5 +8,5 @@
 
 SECTIONS {
-	.image 0x80000000: AT (0x80000000) { 
+	.image 0x10000000: AT (0) { 
 		*(BOOTSTRAP)
 		*(.text);
Index: arch/ppc32/loader/asm.S
===================================================================
--- arch/ppc32/loader/asm.S	(revision 272c219e3ddf80a692df97f90426eb3342bcfe13)
+++ arch/ppc32/loader/asm.S	(revision eebd1727f19f91cad2c6b8735c13af094078d172)
@@ -39,4 +39,5 @@
 .global memsetb
 .global memcpy
+.global flush_instruction_cache
 .global jump_to_kernel
 
@@ -181,10 +182,5 @@
 
 jump_to_kernel:
-	mtspr SPRN_SRR0, r3
-	mfmsr r3
-	lis r4, ~0@h
-	ori r4, r4, ~(MSR_IR | MSR_DR)@l
-	and r3, r3, r4
-	mtspr SPRN_SRR1, r3
-	bl flush_instruction_cache
-	rfi
+	mtlr r3
+	blr
+
Index: arch/ppc32/loader/asm.h
===================================================================
--- arch/ppc32/loader/asm.h	(revision 272c219e3ddf80a692df97f90426eb3342bcfe13)
+++ arch/ppc32/loader/asm.h	(revision eebd1727f19f91cad2c6b8735c13af094078d172)
@@ -30,4 +30,5 @@
 #define __ASM_H__
 
+void flush_instruction_cache(void);
 void jump_to_kernel(void *addr) __attribute__((noreturn));
 
Index: arch/ppc32/loader/main.c
===================================================================
--- arch/ppc32/loader/main.c	(revision 272c219e3ddf80a692df97f90426eb3342bcfe13)
+++ arch/ppc32/loader/main.c	(revision eebd1727f19f91cad2c6b8735c13af094078d172)
@@ -32,5 +32,6 @@
 #include "asm.h"
 
-#define KERNEL_LOAD_ADDRESS 0x400000
+#define KERNEL_PHYSICAL_ADDRESS 0x1000
+#define KERNEL_VIRTUAL_ADDRESS 0x80001000
 #define KERNEL_START &_binary_____________kernel_kernel_bin_start
 #define KERNEL_END &_binary_____________kernel_kernel_bin_end
@@ -41,17 +42,22 @@
 	printf("\nHelenOS PPC Bootloader\n");
 	
-	void *loader = ofw_translate(&start);
-	printf("loaded at %L (physical %L)\n", &start, loader);
-	printf("kernel load address %L (size %d)\n", KERNEL_LOAD_ADDRESS, KERNEL_SIZE);
+	void *phys = ofw_translate(&start);
+	printf("loaded at %L (physical %L)\n", &start, phys);
 	
-	void *addr = ofw_claim((void *) KERNEL_LOAD_ADDRESS, KERNEL_SIZE, 1);
-	if (addr == NULL) {
-		printf("Error: Unable to claim memory");
+	// FIXME: map just the kernel
+	if (ofw_map((void *) KERNEL_PHYSICAL_ADDRESS, (void *) KERNEL_VIRTUAL_ADDRESS, 1024 * 1024, 0) != 0) {
+		printf("Unable to map kernel memory at %L (physical %L)\n", KERNEL_VIRTUAL_ADDRESS, KERNEL_PHYSICAL_ADDRESS);
 		halt();
 	}
-	printf("Claimed memory at %L\n", addr);
-	memcpy(addr, KERNEL_START, KERNEL_SIZE);
+	printf("kernel memory mapped at %L (physical %L, size %d bytes)\n", KERNEL_VIRTUAL_ADDRESS, KERNEL_PHYSICAL_ADDRESS, KERNEL_SIZE);
+	// FIXME: relocate the kernel in real mode
+	memcpy((void *) KERNEL_VIRTUAL_ADDRESS, KERNEL_START, KERNEL_SIZE);
+	
+	// FIXME: proper framebuffer mapping
+	ofw_map((void *) 0x84000000, (void *) 0x84000000, 2 * 1024 * 1024, 0);
 	
 	printf("Booting the kernel...\n");
-	jump_to_kernel(addr);
+	
+	flush_instruction_cache();
+	jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS);
 }
Index: arch/ppc32/loader/ofw.c
===================================================================
--- arch/ppc32/loader/ofw.c	(revision 272c219e3ddf80a692df97f90426eb3342bcfe13)
+++ arch/ppc32/loader/ofw.c	(revision eebd1727f19f91cad2c6b8735c13af094078d172)
@@ -79,8 +79,5 @@
 	ofw(&args);
 	
-	if (nret > 0)
-		return args.args[nargs + nret - 1];
-	else
-		return 0;
+	return args.args[nargs];
 }
 
@@ -113,12 +110,12 @@
 
 
-void *ofw_claim(const void *addr, const int size, const int align)
+void *ofw_translate(const void *virt)
 {
-	return (void *) ofw_call("claim", 3, 1, addr, size, align);
+	return (void *) ofw_call("call-method", 7, 1, "translate", ofw_mmu, virt, 0, 0, 0, 0);
 }
 
 
-void *ofw_translate(const void *virt)
+int ofw_map(const void *phys, const void *virt, const int size, const int mode)
 {
-	return (void *) ofw_call_method(ofw_mmu, "translate", 1, 5, virt);
+	return ofw_call("call-method", 6, 1, "map", ofw_mmu, mode, size, virt, phys);
 }
Index: arch/ppc32/loader/ofw.h
===================================================================
--- arch/ppc32/loader/ofw.h	(revision 272c219e3ddf80a692df97f90426eb3342bcfe13)
+++ arch/ppc32/loader/ofw.h	(revision eebd1727f19f91cad2c6b8735c13af094078d172)
@@ -61,11 +61,10 @@
 extern int ofw_get_property(const phandle device, const char *name, const void *buf, const int buflen);
 extern int ofw_call(const char *service, const int nargs, const int nret, ...);
-#define ofw_call_method(instance, method, nargs, nret, ...) ofw_call("call-method", (nargs + 2), nret, method, instance, ##__VA_ARGS__)
 
 extern ihandle ofw_open(const char *name);
 extern void ofw_write(const char *str, const int len);
 
-extern void *ofw_claim(const void *addr, const int size, const int align);
 extern void *ofw_translate(const void *virt);
+extern int ofw_map(const void *phys, const void *virt, const int size, const int mode);
 
 #endif
