Index: arch/ppc32/loader/Makefile
===================================================================
--- arch/ppc32/loader/Makefile	(revision 032a9b3b68a7bf038e2293725598f993e1115202)
+++ arch/ppc32/loader/Makefile	(revision 1fbe8da2af1d5a724e631943229284b31516a08f)
@@ -66,5 +66,5 @@
 
 image.boot: depend $(OBJECTS) kernel.o
-	$(LD) -no-check-sections -N -T _link.ld $(OBJECTS) kernel.o -o $@
+	$(LD) -no-check-sections -N -T _link.ld -Map map $(OBJECTS) kernel.o -o $@
 
 depend:
Index: arch/ppc32/loader/_link.ld
===================================================================
--- arch/ppc32/loader/_link.ld	(revision 032a9b3b68a7bf038e2293725598f993e1115202)
+++ arch/ppc32/loader/_link.ld	(revision 1fbe8da2af1d5a724e631943229284b31516a08f)
@@ -10,4 +10,5 @@
 	.image 0x10000000: AT (0) { 
 		*(BOOTSTRAP)
+		*(REALMODE)
 		*(.text);
 		
Index: arch/ppc32/loader/asm.S
===================================================================
--- arch/ppc32/loader/asm.S	(revision 032a9b3b68a7bf038e2293725598f993e1115202)
+++ arch/ppc32/loader/asm.S	(revision 1fbe8da2af1d5a724e631943229284b31516a08f)
@@ -181,5 +181,52 @@
 
 jump_to_kernel:
+	
+	# r3 = kernel_start (va)
+	# r4 = memmap (pa)
+	# r5 = real_mode (pa)
+	
+	mtspr srr0, r5
+	
+	# jumps to real_mode
+	
+	mfmsr r5
+	lis r6, ~0@h
+	ori r6, r6, ~(msr_ir | msr_dr)@l
+	and r5, r5, r6
+	mtspr srr1, r5
+	rfi
+
+.section REALMODE
+.align 12
+.global real_mode
+
+real_mode:
+
+	# fill segment registers
+
+	li r5, 16
+	mtctr r5
+	li r5, 0
+	li r6, 0
+	
+	seg_fill:
+	
+		mtsrin r6, r5
+		addis r5, r5, 0x1000    # move to next SR
+		addis r6, r6, 0x10      # add 256 MB, move to next SR
+		
+		bdnz seg_fill
+	
+	# bootstrap kernel
+	#
+	# r3 = kernel_start (va)
+	# r4 = memmap (pa)       -> r10
+	
+	mtspr srr0, r3
+	
+	mfmsr r5
+	ori r5, r5, (msr_ir | msr_dr)@l
+	mtspr srr1, r5
+	
 	mr r10, r4
-	mtlr r3
-	blr
+	rfi
Index: arch/ppc32/loader/asm.h
===================================================================
--- arch/ppc32/loader/asm.h	(revision 032a9b3b68a7bf038e2293725598f993e1115202)
+++ arch/ppc32/loader/asm.h	(revision 1fbe8da2af1d5a724e631943229284b31516a08f)
@@ -31,5 +31,6 @@
 
 void flush_instruction_cache(void);
-void jump_to_kernel(void *code, void *memmap) __attribute__((noreturn));
+void jump_to_kernel(void *code, void *memmap, void *real_mode) __attribute__((noreturn));
+void real_mode(void *code, void *memmap);
 
 #define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
Index: arch/ppc32/loader/main.c
===================================================================
--- arch/ppc32/loader/main.c	(revision 032a9b3b68a7bf038e2293725598f993e1115202)
+++ arch/ppc32/loader/main.c	(revision 1fbe8da2af1d5a724e631943229284b31516a08f)
@@ -53,6 +53,5 @@
 	printf("total memory %d MB\n", memmap.total >> 20);
 	
-	// FIXME: map just the kernel
-	if (ofw_map((void *) KERNEL_PHYSICAL_ADDRESS, (void *) KERNEL_VIRTUAL_ADDRESS, memmap.total - 64 * 1024 * 1024, 0) != 0) {
+	if (ofw_map((void *) KERNEL_PHYSICAL_ADDRESS, (void *) KERNEL_VIRTUAL_ADDRESS, KERNEL_SIZE + KERNEL_BOOT_OFFSET, 0) != 0) {
 		printf("Unable to map kernel memory at %L (physical %L)\n", KERNEL_VIRTUAL_ADDRESS, KERNEL_PHYSICAL_ADDRESS);
 		halt();
@@ -66,7 +65,9 @@
 	ofw_map((void *) 0x80816000, (void *) 0xf2000000, 0x00018000, 0);
 	
+	void *tramp = ofw_translate(&real_mode);
+	printf("bootstrap trampoline at %L (physical %L)\n", &real_mode, tramp);
 	printf("Booting the kernel...\n");
 	
 	flush_instruction_cache();
-	jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS + KERNEL_BOOT_OFFSET, ofw_translate(&memmap));
+	jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS + KERNEL_BOOT_OFFSET, ofw_translate(&memmap), tramp);
 }
