This may look right, but it is a bad kludge. Open Firmware, when "biosload"ed, 
expects a top-of-RAM at physical address 0x1004 ( mem-info-pa 4 + ) , as a 
little endian pointer. LinuxBIOS however only provides its tables. There's 
currently code in the queue from Jens Freimann to parse the LB tables, and 
OFW should ideally get its info from that, but the stuff is not yet stable 
(right, Jens?) and providing the table info to the /memory device init is 
still to be written.

Until openfirmware/cpu/x86/pc/biosload/probemem.fth is changed or maybe even 
an openfirmware/cpu/x86/pc/linuxbiosload is created, use this evil hack. The 
memory map is parsed anyway to find a RAM buffer for the payload, so I just 
hook in here to find a 32-bit pointer to the top of RAM, clipped to 3GB, to 
not confuse the payload :)

Recommendation: do _NOT_ apply!

--- CVS/LinuxBIOSv2/src/boot/elfboot.c	2007-07-25 18:26:10.000000000 +0200
+++ tmp/LinuxBIOSv2/src/boot/elfboot.c	2007-08-27 00:14:37.000000000 +0200
@@ -17,6 +17,7 @@
 
 extern unsigned char _ram_seg;
 extern unsigned char _eram_seg;
+static unsigned long long  top_of_contigram = 0xa0000LL;
 
 struct segment {
 	struct segment *next;
@@ -120,6 +121,13 @@ static unsigned long get_bounce_buffer(s
 		unsigned long tbuffer;
 		if (mem->map[i].type != LB_MEM_RAM)
 			continue;
+		printk_spew("buf@ 0x%lx is 0x%lx\n", 
+			     unpack_lb64(mem->map[i].start),
+			     unpack_lb64(mem->map[i].size));
+		if (unpack_lb64(mem->map[i].start) == 0x100000)
+			top_of_contigram =
+			  unpack_lb64(mem->map[i].start) +
+			  unpack_lb64(mem->map[i].size);
 		if (unpack_lb64(mem->map[i].start) > MAX_ADDR)
 			continue;
 		if (unpack_lb64(mem->map[i].size) < lb_size)
@@ -134,6 +142,7 @@ static unsigned long get_bounce_buffer(s
 			continue;
 		buffer = tbuffer;
 	}
+	printk_spew("top of contiguous RAM = 0x%lx\n", top_of_contigram);
 	return buffer;
 }
 
@@ -589,6 +598,14 @@ int elfload(struct lb_memory *mem,
 	printk_debug("Jumping to boot code at 0x%x\n", entry);
 	post_code(0xfe);
 
+	/* 3 gigabytes should be well enough to get the system booted,
+	 * and it will be understood by 32-bit payloads.
+	 */
+	if (top_of_contigram > 0xC0000000LL) 
+		top_of_contigram=0xC0000000LL;
+
+	*(unsigned long *)0x1004 = top_of_contigram & 0xFFFFFFFF;
+
 	/* Jump to kernel */
 	jmp_to_elf_entry(entry, bounce_buffer);
 	return 1;
-- 
linuxbios mailing list
linuxbios@linuxbios.org
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to