Index: boot/arch/sparc64/loader/main.c
===================================================================
--- boot/arch/sparc64/loader/main.c	(revision ddee70820f4858a2e9e0b986ad80d7f6246fac41)
+++ boot/arch/sparc64/loader/main.c	(revision 4365d108fca11d735aaf46f7098b7f1d5c2cbb52)
@@ -93,5 +93,5 @@
 	for (i = 0; i < COMPONENTS; i++)
 		printf(" %P: %s image (size %d bytes)\n", components[i].start,
-			components[i].name, components[i].size);
+		    components[i].name, components[i].size);
 
 	void * base = (void *) KERNEL_VIRTUAL_ADDRESS;
@@ -103,8 +103,22 @@
 		printf(" %s...", components[i].name);
 		top = ALIGN_UP(top, PAGE_SIZE);
+
+		/*
+		 * At this point, we claim the physical memory that we are
+		 * going to use. We should be safe in case of the virtual
+		 * address space because the OpenFirmware, according to its
+		 * SPARC binding, should restrict its use of virtual memory
+		 * to addresses from [0xffd00000; 0xffefffff] and
+		 * [0xfe000000; 0xfeffffff].
+		 */
+		(void) ofw_claim_phys(bootinfo.physmem_start + base + top,
+		    ALIGN_UP(components[i].size, PAGE_SIZE));
+		    
 		memcpy(base + top, components[i].start, components[i].size);
 		if (i > 0) {
-			bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = base + top;
-			bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = components[i].size;
+			bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr =
+			    base + top;
+			bootinfo.taskmap.tasks[bootinfo.taskmap.count].size =
+			    components[i].size;
 			bootinfo.taskmap.count++;
 		}
@@ -113,5 +127,12 @@
 	}
 
-	balloc_init(&bootinfo.ballocs, ALIGN_UP(((uintptr_t) base) + top, PAGE_SIZE));
+	/*
+	 * Claim the physical memory for the boot allocator.
+	 * Initialize the boot allocator.
+	 */
+	(void) ofw_claim_phys(bootinfo.physmem_start +
+	    base + ALIGN_UP(top, PAGE_SIZE), BALLOC_MAX_SIZE);
+	balloc_init(&bootinfo.ballocs, ALIGN_UP(((uintptr_t) base) + top,
+	    PAGE_SIZE));
 
 	printf("\nCanonizing OpenFirmware device tree...");
@@ -128,4 +149,6 @@
 	printf("\nBooting the kernel...\n");
 	jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS,
-		bootinfo.physmem_start | BSP_PROCESSOR,	&bootinfo, sizeof(bootinfo));
+	    bootinfo.physmem_start | BSP_PROCESSOR, &bootinfo,
+	    sizeof(bootinfo));
 }
+
Index: boot/genarch/balloc.c
===================================================================
--- boot/genarch/balloc.c	(revision ddee70820f4858a2e9e0b986ad80d7f6246fac41)
+++ boot/genarch/balloc.c	(revision 4365d108fca11d735aaf46f7098b7f1d5c2cbb52)
@@ -48,5 +48,8 @@
 	
 	addr = ballocs->base + ALIGN_UP(ballocs->size, alignment);
-	
+
+	if (ALIGN_UP(ballocs->size, alignment) + size > BALLOC_MAX_SIZE)
+		return NULL;
+		
 	ballocs->size = ALIGN_UP(ballocs->size, alignment) + size;
 	
Index: boot/genarch/balloc.h
===================================================================
--- boot/genarch/balloc.h	(revision ddee70820f4858a2e9e0b986ad80d7f6246fac41)
+++ boot/genarch/balloc.h	(revision 4365d108fca11d735aaf46f7098b7f1d5c2cbb52)
@@ -32,4 +32,6 @@
 #include <types.h>
 
+#define BALLOC_MAX_SIZE		(1024 * 1024)
+
 typedef struct {
 	uintptr_t base;
Index: boot/genarch/ofw.c
===================================================================
--- boot/genarch/ofw.c	(revision ddee70820f4858a2e9e0b986ad80d7f6246fac41)
+++ boot/genarch/ofw.c	(revision 4365d108fca11d735aaf46f7098b7f1d5c2cbb52)
@@ -39,4 +39,5 @@
 phandle ofw_root;
 ihandle ofw_mmu;
+ihandle ofw_memory_prop;
 phandle ofw_memory;
 phandle ofw_aliases;
@@ -48,5 +49,5 @@
 		halt();
 	
-	if (ofw_get_property(ofw_chosen, "stdout",  &ofw_stdout, sizeof(ofw_stdout)) <= 0)
+	if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, sizeof(ofw_stdout)) <= 0)
 		ofw_stdout = 0;
 	
@@ -57,6 +58,10 @@
 	}
 	
-	if (ofw_get_property(ofw_chosen, "mmu",  &ofw_mmu, sizeof(ofw_mmu)) <= 0) {
+	if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu, sizeof(ofw_mmu)) <= 0) {
 		puts("\r\nError: Unable to get mmu property, halted.\r\n");
+		halt();
+	}
+	if (ofw_get_property(ofw_chosen, "memory", &ofw_memory_prop, sizeof(ofw_memory_prop)) <= 0) {
+		puts("\r\nError: Unable to get memory property, halted.\r\n");
 		halt();
 	}
@@ -201,11 +206,10 @@
 		shift = 0;
 
-	return (void *) ((result[2]<<shift)|result[3]);
-}
-
-void *ofw_claim(const void *virt, const int len)
+	return (void *) ((result[2] << shift) | result[3]);
+}
+
+void *ofw_claim_virt(const void *virt, const int len)
 {
 	ofw_arg_t retaddr;
-	int shift;
 
 	if (ofw_call("call-method", 5, 2, &retaddr, "claim", ofw_mmu, 0, len, virt) != 0) {
@@ -215,4 +219,40 @@
 
 	return (void *) retaddr;
+}
+
+void *ofw_claim_phys(const void *phys, const int len)
+{
+	ofw_arg_t retaddr[2];
+	int shift;
+
+	if (sizeof(unative_t) == 8) {
+		shift = 32;
+		if (ofw_call("call-method", 6, 3, retaddr, "claim",
+		    ofw_memory_prop, 0, len, ((uintptr_t) phys) >> shift,
+		    ((uintptr_t) phys) & ((uint32_t) -1)) != 0) {
+			/*
+			 * Note that this will help us to discover
+			 * conflicts between OpenFirmware allocations
+			 * and our use of physical memory.
+			 * It is better to detect collisions here
+			 * than to cope with weird errors later.
+			 *
+			 * So this is really not to make the loader
+			 * more generic; it is here for debugging
+			 * purposes.
+			 */
+			puts("Error: memory method claim() failed, halting.\n");
+			halt();
+		}
+	} else {
+		shift = 0;
+		/*
+		 * FIXME: the number of arguments is probably different...
+		 */
+		puts("Error: 32-bit ofw_claim_phys not implemented.\n");
+		halt();
+	}
+
+	return (void *) ((retaddr[0] << shift) | retaddr[1]);
 }
 
@@ -231,5 +271,5 @@
 
 	return ofw_call("call-method", 7, 1, NULL, "map", ofw_mmu, mode, size, virt,
-		phys_hi, phys_lo);
+	    phys_hi, phys_lo);
 }
 
@@ -253,6 +293,6 @@
 	map->total = 0;
 	map->count = 0;
-	for (pos = 0; (pos < ret / sizeof(uint32_t)) && (map->count <
-		MEMMAP_MAX_RECORDS); pos += ac + sc) {
+	for (pos = 0; (pos < ret / sizeof(uint32_t)) &&
+	    (map->count < MEMMAP_MAX_RECORDS); pos += ac + sc) {
 		void * start = (void *) ((uintptr_t) buf[pos + ac - 1]);
 		unsigned int size = buf[pos + ac + sc - 1];
Index: boot/genarch/ofw.h
===================================================================
--- boot/genarch/ofw.h	(revision ddee70820f4858a2e9e0b986ad80d7f6246fac41)
+++ boot/genarch/ofw.h	(revision 4365d108fca11d735aaf46f7098b7f1d5c2cbb52)
@@ -118,5 +118,6 @@
 extern void *ofw_translate(const void *virt);
 extern int ofw_translate_failed(ofw_arg_t flag);
-extern void *ofw_claim(const void *virt, const int len);
+extern void *ofw_claim_virt(const void *virt, const int len);
+extern void *ofw_claim_phys(const void *virt, const int len);
 extern int ofw_map(const void *phys, const void *virt, const int size, const int mode);
 extern int ofw_memmap(memmap_t *map);
