Patchwork Re: RE : RE : First coreboot build for Tyan s2895 K8WE mobo with seabios payload, computer starts, but graphical ubuntu 64bits is crashing

login
register
about
Submitter Juhana Helovuo
Date 2010-09-18 16:23:54
Message ID <1284827034.3702.59.camel@bart>
Download mbox | patch
Permalink /patch/1959/
State Not Applicable
Headers show

Comments

Juhana Helovuo - 2010-09-18 16:23:54
On Sat, 2010-09-18 at 00:14 +0200, STEMMELIN, FREDERIC (FREDERIC)** CTR
** wrote:
> In the mean time i checked RAM with memtest86+ v4.0 provided with
> Ubuntu 10.04, and it is not working at all, 0kb RAM detected with
> coreboot+seabios.
> On tyan bios all the RAM is detected properly (no errors on tests
> too).
> 
> I have 4*2GB ECC RAM from crucial, dont remember ref, can probably find it somewhere.

Hello,

My guess from your memtest86+ printouts is the following:

With Tyan BIOS, memtest86+ uses BIOS call "e820" to find out the
available RAM.

With Coreboot + SeaBIOS, memtes86+ detects that there are Coreboot
tables in memory ("LxBIOS"), but for some reason thinks that the table
reports 0k memory. This may be because your memtest86+ version does not
support Coreboot "high tables", and therefore detects the presence of
Coreboot, but cannot read the contents of the table. 

Coreboot does not implement the e820 interface, but SeaBIOS should have
it available. However, when memtest86+ detects that Coreboot is present,
it ignores the e820 interface and tries to read the Coreboot tables.


I have made a patch for memtest86+ v4.10, which adds better support for
Coreboot and also multiboot tables. The patch is not my original work,
but a combination of two patches, so the credit belongs to the original
authors.

Application instructions:

* Download memtest86+ v 4.10 sources .tar.gz and untar

* Apply patch, e.g. patch -p1 < ../coreboot-v4-and-multiboot-support-for-memtest86+-4.10.patch

* Manually rename two files:
% mv linuxbios.c coreboot.c
% mv linuxbios_tables.h coreboot_tables.h

* Build memtest86+ using "make"

The build process creates two versions of the memtest86+ binary.
"memtest" is multiboot-compatible ELF executable and "memtest.bin" is
bootable image like a Linux kernel image. Choosing between these two
depends on your boot method: BIOS, Coreboot only, Coreboot+SeaBIOS, or a
bootloader.

My success with memtest86+ has been rather limited, but maybe this works
for you.

Best regards,
Juhana Helovuo
Thank you very much for your help, in the mean time i have very goods news, yes my Tyan s2895 is BOOTING now :)

I found what was the origin of teh crashes after i was trying to boot a debian livecd with "noapic noapm" and such other things as kernel parameters (i didnt change the defaut settings).
I saw a kerneloops on screen after kernel was trying to set a IRQ for the intel network card, with error -39 (or -38 i dont remember exactly).

Now after remowing my Intel PRO1000MT server network card from PCI-X slot 6, i can boot without any problems :)
Memtest86+ v 4.0 is still not working, but less important now that i am sure my problem was not RAM related :)
I will anyway try your instructions with patchs and report back.

By the way, i was not able to compile following with coreboot v4:
- corinfo => compile errors
- tint => same
- memtest as payload => same

I tried several things like changing Makefile, but it didnt work as i dont understand what it doest exactly.

Thank's for your support.

PS: If needed i can provide all informations what mayy necessary to find the PCI-X bug with teh network card, if you wish.
Now here are my results with the patched Memtest86+ version 4.1.
Check the attached files.

As you can see it is far way better, even if it is not working, at least i can see that the memory is recognized correctly, wich is pretty good.
Memtest86+ is still crashing on test starting (after 3%), but really not important so far, as long as my computer does not crash in normal operation mode.

Another question, what may the consequences be not supporting e820 in bios, for other OS like windows for example ? Does another OS use this feature e820 ?

Cheers
Frédéric
Peter Stuge - 2010-09-19 14:48:43
STEMMELIN, FREDERIC (FREDERIC)** CTR ** wrote:
> Thank you very much for your help, in the mean time i have very
> goods news, yes my Tyan s2895 is BOOTING now :)

Nice, but..

> kerneloops on screen after kernel was trying to set a IRQ for the
> intel network card, with error -39 (or -38 i dont remember
> exactly).
> 
> Now after remowing my Intel PRO1000MT server network card from
> PCI-X slot 6, i can boot without any problems :)

..the PCI-X should also work. I think it may be good to investigate
why it gets such a high bus number.


> Now here are my results with the patched Memtest86+ version 4.1.
> Check the attached files.
> 
> As you can see it is far way better, even if it is not working, at
> least i can see that the memory is recognized correctly, wich is
> pretty good.
> Memtest86+ is still crashing on test starting (after 3%), but
> really not important so far, as long as my computer does not crash
> in normal operation mode.

I think it is important. memtest should not crash, if it does, then
I don't think everything is right with the memory setup, and that
will lead to your computer crashing, it will just take some time;
until you have started filling the RAM with stuff that you don't want
to lose.


> Another question, what may the consequences be not supporting e820
> in bios,

*Please* remember that coreboot is not a BIOS. e820 memory maps are a
BIOS-specific interface, and coreboot does not provide this. coreboot
still provides a memory map, within the coreboot tables.

SeaBIOS provides BIOS interfaces, among other things it implements
"e820" memory maps, based on the coreboot tables memory map.


> for other OS like windows for example ? Does another OS use this
> feature e820 ?

Nearly every OS on the PC so far assumes that the 30-year old BIOS
interface will be present.

Because systems do not understand the coreboot memory map format
they require legacy BIOS compatibility and can only start using
SeaBIOS. In a way this is also true for Linux, but mkelfImage helps
bridge the gap so that no BIOS is needed.

Obviously everything that uses libpayload is also free of BIOS
requirements.

memtest86 understands both e820 and coreboot tables, but the coreboot
support in memtest86 was not updated to interpret the latest version
of coreboot tables, or rather the specific high tables feature.

So an unpatched memtest86 will notice that coreboot is available even
if you have SeaBIOS, it just does not know how to correctly interpret
the coreboot tables.


//Peter
Myles Watson - 2010-09-20 14:59:54
>> Now after remowing my Intel PRO1000MT server network card from
>> PCI-X slot 6, i can boot without any problems :)
>
> ..the PCI-X should also work. I think it may be good to investigate
> why it gets such a high bus number.

The K8 code assigns bus numbers that way.  The primary southbridge
link gets bus 0x0, the next HT link gets 0x40...  That's just the way
it was written.

Thanks,
Myles

Patch

diff -Naur memtest86+-4.10.orig//dmi.c memtest86+-4.10-patched//dmi.c
--- memtest86+-4.10.orig//dmi.c	2010-04-28 15:11:15.000000000 +0300
+++ memtest86+-4.10-patched//dmi.c	2010-09-12 18:27:58.890297051 +0300
@@ -10,7 +10,7 @@ 
 
 
 #include "test.h"
-#include <stdint.h>
+#include "types.h"
 
 
 #define round_up(x,y) (((x) + (y) - 1) & ~((y)-1))
diff -Naur memtest86+-4.10.orig//error.c memtest86+-4.10-patched//error.c
--- memtest86+-4.10.orig//error.c	2010-04-28 15:11:15.000000000 +0300
+++ memtest86+-4.10-patched//error.c	2010-09-12 18:27:58.890297051 +0300
@@ -11,7 +11,6 @@ 
  
 #include "test.h"
 #include "config.h"
-#include <sys/io.h>
 #include "dmi.h"
 #define NULL 0
 
diff -Naur memtest86+-4.10.orig//head.S memtest86+-4.10-patched//head.S
--- memtest86+-4.10.orig//head.S	2010-04-28 15:11:15.000000000 +0300
+++ memtest86+-4.10-patched//head.S	2010-09-14 01:04:00.568368834 +0300
@@ -13,9 +13,11 @@ 
 
 .text
 #define __ASSEMBLY__
+#define ASM_FILE
 #include "defs.h"
 #include "config.h"
 #include "test.h"
+#include "multiboot.h"
 
 /*
  * References to members of the boot_cpu_data structure.
@@ -54,6 +56,13 @@ 
 	cld
 	cli
 
+        /* Store MBI pointer */
+        xorl    %ecx, %ecx
+        cmpl    $MULTIBOOT_BOOTLOADER_MAGIC, %eax
+        jne 0f
+        movl    %ebx, %ecx
+0:
+
 	/* Ensure I have a stack pointer */
 	testl	%esp, %esp
 	jnz 0f
@@ -66,6 +75,20 @@ 
 0:	popl	%ebx
 	addl	$_GLOBAL_OFFSET_TABLE_+[.-0b], %ebx
 
+       /* Move MBI pointer to a safe place */
+       testl   %ecx, %ecx
+       je      0f
+       movl    %ecx, mbiptr@GOTOFF(%ebx)
+0:
+
+       jmp     0f
+       /* Multiboot header */
+.align 4
+       .long   MULTIBOOT_HEADER_MAGIC
+       .long   0
+       .long   -MULTIBOOT_HEADER_MAGIC
+0:
+
 	/* Pick the appropriate stack address */
 	leal	stack_top@GOTOFF(%ebx), %esp
 
@@ -1003,6 +1026,10 @@ 
 	movl	$1, %eax
 	ret
 
+.globl mbiptr
+mbiptr:
+       .long   0
+
 realptr:
 	.word	real - RSTART
 	.word	0x0000
diff -Naur memtest86+-4.10.orig//init.c memtest86+-4.10-patched//init.c
--- memtest86+-4.10.orig//init.c	2010-04-28 15:11:15.000000000 +0300
+++ memtest86+-4.10-patched//init.c	2010-09-14 01:00:40.307244410 +0300
@@ -98,8 +98,11 @@ 
 	/* Determine the memory map */
 	if ((firmware == FIRMWARE_UNKNOWN) &&
 		(memsz_mode != SZ_MODE_PROBE)) {
-		if (query_linuxbios()) {
-			firmware = FIRMWARE_LINUXBIOS;
+                if (query_multiboot()) {
+                        firmware = FIRMWARE_MULTIBOOT;
+                }
+	        else if (query_coreboot()) {
+			firmware = FIRMWARE_COREBOOT;
 		}
 		else if (query_pcbios()) {
 			firmware = FIRMWARE_PCBIOS;
diff -Naur memtest86+-4.10.orig//io.h memtest86+-4.10-patched//io.h
--- memtest86+-4.10.orig//io.h	2010-04-28 15:11:15.000000000 +0300
+++ memtest86+-4.10-patched//io.h	2010-09-12 18:27:58.890297051 +0300
@@ -116,4 +116,18 @@ 
 ((__builtin_constant_p((port)) && (port) < 256) ? \
 	__inlc(port) : \
 	__inl(port))
+
+/* for test.c, but probably all IO functions should be declared explicitly */
+static inline unsigned char inb_p(unsigned short port)
+{
+	unsigned char value;
+	__asm__ __volatile__("inb %w1,%b0\noutb %%al,$0x80" : "=a"(value) : "Nd"(port));
+	return value;
+}
+
+static inline void outb_p(unsigned char value, unsigned short port)
+{
+	  __asm__ __volatile__ ("outb %b0,%w1\noutb %%al,$0x80" : : "a"(value), "Nd"(port));
+}
+
 #endif
diff -Naur memtest86+-4.10.orig//linuxbios.c memtest86+-4.10-patched//linuxbios.c
--- memtest86+-4.10.orig//linuxbios.c	2010-04-28 15:11:15.000000000 +0300
+++ memtest86+-4.10-patched//linuxbios.c	2010-09-12 18:41:04.472342086 +0300
@@ -1,4 +1,4 @@ 
-#include "linuxbios_tables.h"
+#include "coreboot_tables.h"
 #include "test.h"
 
 static unsigned long ip_compute_csum(void *addr, unsigned long length)
@@ -53,32 +53,32 @@ 
 	
 }
 
-#define for_each_lbrec(head, rec) \
-	for(rec = (struct lb_record *)(((char *)head) + sizeof(*head)); \
+#define for_each_cbrec(head, rec) \
+	for(rec = (struct cb_record *)(((char *)head) + sizeof(*head)); \
 		(((char *)rec) < (((char *)head) + sizeof(*head) + head->table_bytes))  && \
 		(rec->size >= 1) && \
 		((((char *)rec) + rec->size) <= (((char *)head) + sizeof(*head) + head->table_bytes)); \
-		rec = (struct lb_record *)(((char *)rec) + rec->size)) 
+		rec = (struct cb_record *)(((char *)rec) + rec->size)) 
 		
 
-static int count_lb_records(struct lb_header *head)
+static int count_cb_records(struct cb_header *head)
 {
-	struct lb_record *rec;
+	struct cb_record *rec;
 	int count;
 	count = 0;
-	for_each_lbrec(head, rec) {
+	for_each_cbrec(head, rec) {
 		count++;
 	}
 	return count;
 }
 
-static struct lb_header * __find_lb_table(unsigned long start, unsigned long end)
+static struct cb_header * __find_cb_table(unsigned long start, unsigned long end)
 {
 	unsigned long addr;
 	/* For now be stupid.... */
 	for(addr = start; addr < end; addr += 16) {
-		struct lb_header *head = (struct lb_header *)addr;
-		struct lb_record *recs = (struct lb_record *)(addr + sizeof(*head));
+		struct cb_header *head = (struct cb_header *)addr;
+		struct cb_record *recs = (struct cb_record *)(addr + sizeof(*head));
 		if (memcmp(head->signature, "LBIO", 4) != 0)
 			continue;
 		if (head->header_bytes != sizeof(*head))
@@ -88,42 +88,62 @@ 
 		if (ip_compute_csum((unsigned char *)recs, head->table_bytes) 
 			!= head->table_checksum)
 			continue;
-		if (count_lb_records(head) != head->table_entries)
+		if (count_cb_records(head) != head->table_entries)
 			continue;
 		return head;
 	};
 	return 0;
 }
 
-static struct lb_header * find_lb_table(void)
+static struct cb_header * find_cb_table(void)
 {
-	struct lb_header *head;
+	struct cb_header *head;
+	struct cb_record *rec;
+	struct cb_forward *forward;
 	head = 0;
 	if (!head) {
 		/* First try at address 0 */
-		head = __find_lb_table(0x00000, 0x1000);
+		head = __find_cb_table(0x00000, 0x1000);
 	}
 	if (!head) {
 		/* Then try at address 0xf0000 */
-		head = __find_lb_table(0xf0000, 0x100000);
+		head = __find_cb_table(0xf0000, 0x100000);
 	}
+	forward = 0;
+	if (head) {
+		/* Check whether there is a forward header */
+		for_each_cbrec(head, rec) {
+			if (rec->tag == CB_TAG_FORWARD) {
+				forward = (struct cb_forward *)rec;
+				break;
+			}
+		}
+	}
+	if (forward) {
+		/* if there is, all valid information is in the 
+		 * referenced coreboot table
+		 */
+		head = __find_cb_table(forward->forward, 
+				       forward->forward + 0x1000);
+	}
+
 	return head;
 }
 
-int query_linuxbios(void)
+int query_coreboot(void)
 {
-	struct lb_header *head;
-	struct lb_record *rec;
-	struct lb_memory *mem;
+	struct cb_header *head;
+	struct cb_record *rec;
+	struct cb_memory *mem;
 	int i, entries;
-	head = find_lb_table();
+	head = find_cb_table();
 	if (!head) {
 		return 0;
 	}
 	mem = 0;
-	for_each_lbrec(head, rec) {
-		if (rec->tag == LB_TAG_MEMORY) {
-			mem = (struct lb_memory *)rec;
+	for_each_cbrec(head, rec) {
+		if (rec->tag == CB_TAG_MEMORY) {
+			mem = (struct cb_memory *)rec;
 			break;
 		}
 	}
@@ -143,7 +163,7 @@ 
 		}
 		start = mem->map[i].start;
 		size = mem->map[i].size;
-		type = (mem->map[i].type == LB_MEM_RAM)?E820_RAM: E820_RESERVED;
+		type = (mem->map[i].type == CB_MEM_RAM)?E820_RAM: E820_RESERVED;
 		mem_info.e820[mem_info.e820_nr].addr = start;
 		mem_info.e820[mem_info.e820_nr].size = size;
 		mem_info.e820[mem_info.e820_nr].type = type;
diff -Naur memtest86+-4.10.orig//linuxbios_tables.h memtest86+-4.10-patched//linuxbios_tables.h
--- memtest86+-4.10.orig//linuxbios_tables.h	2010-04-28 15:11:15.000000000 +0300
+++ memtest86+-4.10-patched//linuxbios_tables.h	2010-09-12 18:27:58.923297297 +0300
@@ -1,9 +1,9 @@ 
-#ifndef LINUXBIOS_TABLES_H
-#define LINUXBIOS_TABLES_H
+#ifndef COREBOOT_TABLES_H
+#define COREBOOT_TABLES_H
 
 #include "stdint.h"
 
-/* The linuxbios table information is for conveying information
+/* The coreboot table information is for conveying information
  * from the firmware to the loaded OS image.  Primarily this
  * is expected to be information that cannot be discovered by
  * other means, such as quering the hardware directly.
@@ -32,7 +32,7 @@ 
  */
 
 
-struct lb_header
+struct cb_header
 {
 	uint8_t  signature[4]; /* LBIO */
 	uint32_t header_bytes;
@@ -48,35 +48,39 @@ 
  * boot enviroment record if you don't know what it easy.  This allows
  * forward compatibility with records not yet defined.
  */
-struct lb_record {
+struct cb_record {
 	uint32_t tag;		/* tag ID */
 	uint32_t size;		/* size of record (in bytes) */
 };
 
-#define LB_TAG_UNUSED	0x0000
+#define CB_TAG_UNUSED	0x0000
 
-#define LB_TAG_MEMORY	0x0001
+#define CB_TAG_MEMORY	0x0001
 
-struct lb_memory_range {
+struct cb_memory_range {
 	uint64_t start;
 	uint64_t size;
 	uint32_t type;
-#define LB_MEM_RAM      1
-#define LB_MEM_RESERVED 2
-	
+#define CB_MEM_RAM		 1	/* Memory anyone can use */
+#define CB_MEM_RESERVED		 2	/* Don't use this memory region */
+#define CB_MEM_ACPI		 3	/* ACPI Tables */
+#define CB_MEM_NVS		 4	/* ACPI NVS Memory */
+#define CB_MEM_UNUSABLE		 5	/* Unusable address space */
+#define CB_MEM_VENDOR_RSVD	 6	/* Vendor Reserved */
+#define CB_MEM_TABLE		16	/* Ram configuration tables are kept in */
 };
 
-struct lb_memory {
+struct cb_memory {
 	uint32_t tag;
 	uint32_t size;
-	struct lb_memory_range map[0];
+	struct cb_memory_range map[0];
 };
 
-#define LB_TAG_HWRPB	0x0002
-struct lb_hwrpb {
+#define CB_TAG_FORWARD	0x0011
+struct cb_forward {
 	uint32_t tag;
 	uint32_t size;
-	uint64_t hwrpb;
+	uint64_t forward;
 };
 
-#endif /* LINUXBIOS_TABLES_H */
+#endif /* COREBOOT_TABLES_H */
diff -Naur memtest86+-4.10.orig//main.c memtest86+-4.10-patched//main.c
--- memtest86+-4.10.orig//main.c	2010-04-28 15:11:15.000000000 +0300
+++ memtest86+-4.10-patched//main.c	2010-09-14 00:59:34.431713210 +0300
@@ -11,9 +11,12 @@ 
 #include "test.h"
 #include "defs.h"
 #include "config.h"
+#include "multiboot.h"
 #undef TEST_TIMES
 #define DEFTESTS 9
 
+extern struct multiboot_info *mbiptr;
+
 extern void bzero();
 
 const struct tseq tseq[] = {
@@ -151,11 +154,14 @@ 
 	if (cmdline_parsed)
 		return;
 
-	if (*OLD_CL_MAGIC_ADDR != OLD_CL_MAGIC)
-		return;
-
-	unsigned short offset = *OLD_CL_OFFSET_ADDR;
-	cmdline = MK_PTR(INITSEG, offset);
+       if (mbiptr && (mbiptr->flags & MULTIBOOT_INFO_CMDLINE)) {
+               cmdline = (void *) mbiptr->cmdline;
+       } else {
+               if (*OLD_CL_MAGIC_ADDR != OLD_CL_MAGIC)
+                       return;
+               unsigned short offset = *OLD_CL_OFFSET_ADDR;
+               cmdline = MK_PTR(INITSEG, offset);
+       }
 
 	/* skip leading spaces */
 	while (*cmdline == ' ')
diff -Naur memtest86+-4.10.orig//Makefile memtest86+-4.10-patched//Makefile
--- memtest86+-4.10.orig//Makefile	2010-04-28 15:11:15.000000000 +0300
+++ memtest86+-4.10-patched//Makefile	2010-09-18 21:19:26.351170669 +0300
@@ -8,14 +8,22 @@ 
 #
 FDISK=/dev/fd0
 
-AS=as -32
-CC=gcc
+AS=$(CROSS)as -32
+CC=$(CROSS)gcc
+LD=$(CROSS)ld
+OBJCOPY=$(CROSS)objcopy
 
 CFLAGS= -Wall -march=i486 -m32 -O2 -fomit-frame-pointer -fno-builtin -ffreestanding -fPIC -fno-stack-protector
 
-OBJS= head.o reloc.o main.o test.o init.o lib.o patn.o screen_buffer.o \
-      config.o linuxbios.o memsize.o pci.o controller.o random.o spd.o \
-      error.o dmi.o cpuid.o
+# This reverts a change introduced with recent binutils (post
+# http://sourceware.org/bugzilla/show_bug.cgi?id=10569).  Needed to
+# ensure Multiboot header is within the limit offset.
+LD += -z max-page-size=0x1000
+
+
+OBJS= head.pre.o reloc.o main.o test.o init.o lib.o patn.o screen_buffer.o \
+      config.o coreboot.o memsize.o pci.o controller.o random.o spd.o \
+      error.o dmi.o cpuid.o multiboot.o
 
 all: memtest.bin memtest
 
@@ -28,22 +36,22 @@ 
 	$(LD) -shared -Bsymbolic -T memtest_shared.lds -o $@ $(OBJS)
 
 memtest_shared.bin: memtest_shared
-	objcopy -O binary $< memtest_shared.bin
+	$(OBJCOPY) -O binary $< memtest_shared.bin
 
 memtest: memtest_shared.bin memtest.lds
 	$(LD) -s -T memtest.lds -b binary memtest_shared.bin -o $@
 
-head.s: head.S config.h defs.h test.h
+head.pre.s: head.S config.h defs.h test.h
 	$(CC) -E -traditional $< -o $@
 
-bootsect.s: bootsect.S config.h defs.h
+bootsect.pre.s: bootsect.S config.h defs.h
 	$(CC) -E -traditional $< -o $@
 
-setup.s: setup.S config.h defs.h
+setup.pre.s: setup.S config.h defs.h
 	$(CC) -E -traditional $< -o $@
 
-memtest.bin: memtest_shared.bin bootsect.o setup.o memtest.bin.lds
-	$(LD) -T memtest.bin.lds bootsect.o setup.o -b binary \
+memtest.bin: memtest_shared.bin bootsect.pre.o setup.pre.o memtest.bin.lds
+	$(LD) -T memtest.bin.lds bootsect.pre.o setup.pre.o -b binary \
 	memtest_shared.bin -o memtest.bin
 
 reloc.o: reloc.c
@@ -53,7 +61,7 @@ 
 	$(CC) -c -Wall -march=i486 -m32 -Os -fomit-frame-pointer -fno-builtin -ffreestanding test.c
 
 clean:
-	rm -f *.o *.s *.iso memtest.bin memtest memtest_shared memtest_shared.bin
+	rm -f *.o *.pre.s *.iso memtest.bin memtest memtest_shared memtest_shared.bin
 
 asm:
 	@./makedos.sh
@@ -68,7 +76,7 @@ 
 
 install-precomp:
 	dd <precomp.bin >$(FDISK) bs=8192
-	
+
 dos: all
 	cat mt86+_loader memtest.bin > memtest.exe
 
diff -Naur memtest86+-4.10.orig//Makefile~ memtest86+-4.10-patched//Makefile~
--- memtest86+-4.10.orig//Makefile~	1970-01-01 02:00:00.000000000 +0200
+++ memtest86+-4.10-patched//Makefile~	2010-09-14 00:51:09.020297088 +0300
@@ -0,0 +1,82 @@ 
+# Makefile for MemTest86+
+#
+# Author:		Chris Brady
+# Created:		January 1, 1996
+
+#
+# Path for the floppy disk device
+#
+FDISK=/dev/fd0
+
+AS=$(CROSS)as -32
+CC=$(CROSS)gcc
+LD=$(CROSS)ld
+OBJCOPY=$(CROSS)objcopy
+
+CFLAGS= -Wall -march=i486 -m32 -O2 -fomit-frame-pointer -fno-builtin -ffreestanding -fPIC -fno-stack-protector
+
+# This reverts a change introduced with recent binutils (post
+# http://sourceware.org/bugzilla/show_bug.cgi?id=10569).  Needed to
+# ensure Multiboot header is within the limit offset.
+LD += -z max-page-size=0x1000
+
+
+OBJS= head.o reloc.o main.o test.o init.o lib.o patn.o screen_buffer.o \
+      config.o coreboot.o memsize.o pci.o controller.o random.o spd.o \
+      error.o dmi.o cpuid.o multiboot.o
+
+all: memtest.bin memtest
+
+# Link it statically once so I know I don't have undefined
+# symbols and then link it dynamically so I have full
+# relocation information
+memtest_shared: $(OBJS) memtest_shared.lds Makefile
+	$(LD) --warn-constructors --warn-common -static -T memtest_shared.lds \
+	-o $@ $(OBJS) && \
+	$(LD) -shared -Bsymbolic -T memtest_shared.lds -o $@ $(OBJS)
+
+memtest_shared.bin: memtest_shared
+	$(OBJCOPY) -O binary $< memtest_shared.bin
+
+memtest: memtest_shared.bin memtest.lds
+	$(LD) -s -T memtest.lds -b binary memtest_shared.bin -o $@
+
+head.pre.s: head.S config.h defs.h test.h
+	$(CC) -E -traditional $< -o $@
+
+bootsect.pre.s: bootsect.S config.h defs.h
+	$(CC) -E -traditional $< -o $@
+
+setup.pre.s: setup.S config.h defs.h
+	$(CC) -E -traditional $< -o $@
+
+memtest.bin: memtest_shared.bin bootsect.pre.o setup.pre.o memtest.bin.lds
+	$(LD) -T memtest.bin.lds bootsect.pre.o setup.pre.o -b binary \
+	memtest_shared.bin -o memtest.bin
+
+reloc.o: reloc.c
+	$(CC) -c $(CFLAGS) -fno-strict-aliasing reloc.c
+
+test.o: test.c
+	$(CC) -c -Wall -march=i486 -m32 -Os -fomit-frame-pointer -fno-builtin -ffreestanding test.c
+
+clean:
+	rm -f *.o *.pre.s *.iso memtest.bin memtest memtest_shared memtest_shared.bin
+
+asm:
+	@./makedos.sh
+
+iso:
+	make all
+	./makeiso.sh
+	rm -f *.o *.s memtest.bin memtest memtest_shared memtest_shared.bin
+
+install: all
+	dd <memtest.bin >$(FDISK) bs=8192
+
+install-precomp:
+	dd <precomp.bin >$(FDISK) bs=8192
+
+dos: all
+	cat mt86+_loader memtest.bin > memtest.exe
+
diff -Naur memtest86+-4.10.orig//memsize.c memtest86+-4.10-patched//memsize.c
--- memtest86+-4.10.orig//memsize.c	2010-04-28 15:11:15.000000000 +0300
+++ memtest86+-4.10-patched//memsize.c	2010-09-14 00:43:59.515230859 +0300
@@ -26,7 +26,7 @@ 
 static void memsize_801(void);
 static int sanitize_e820_map(struct e820entry *orig_map,
 	struct e820entry *new_bios, short old_nr);
-static void memsize_linuxbios();
+static void memsize_coreboot(void);
 static void memsize_probe(void);
 static int check_ram(void);
 
@@ -75,11 +75,11 @@ 
 
 static void memsize_bios()
 {
-	if (firmware == FIRMWARE_PCBIOS) {
+	if (firmware == FIRMWARE_PCBIOS || firmware == FIRMWARE_MULTIBOOT) {
 		memsize_820();
 	}
-	else if (firmware == FIRMWARE_LINUXBIOS) {
-		memsize_linuxbios();
+	else if (firmware == FIRMWARE_COREBOOT) {
+		memsize_coreboot();
 	}
 }
 
@@ -107,7 +107,7 @@ 
 		}
 	}
 }
-static void memsize_linuxbios(void)
+static void memsize_coreboot(void)
 {
 	int i, n;
 	/* Build the memory map for testing */
@@ -125,7 +125,7 @@ 
 		n++;
 	}
 	v->msegs = n;
-	cprint(LINE_INFO, COL_MMAP, "LxBIOS");
+	cprint(LINE_INFO, COL_MMAP, "corebt");
 }
 static void memsize_820()
 {
diff -Naur memtest86+-4.10.orig//multiboot.c memtest86+-4.10-patched//multiboot.c
--- memtest86+-4.10.orig//multiboot.c	1970-01-01 02:00:00.000000000 +0200
+++ memtest86+-4.10-patched//multiboot.c	2010-09-14 00:46:49.534029011 +0300
@@ -0,0 +1,49 @@ 
+/* multiboot.c
+ *
+ * Copyright (C) 2008,2009 Robert Millan
+ *
+ * Loosely based on linuxbios.c, which is:
+ *
+ * Released under version 2 of the Gnu Public License.
+ * By Eric Biederman
+ */
+
+#include "multiboot.h"
+#include "test.h"
+
+extern struct multiboot_info *mbiptr;
+
+int query_multiboot(void)
+{
+	struct multiboot_mmap_entry *mem;
+	int i;
+
+	if (!mbiptr) {
+		return 0;
+	}
+	if (!mbiptr->mmap_addr) {
+		return 1;
+	}
+	if ((mbiptr->flags & MULTIBOOT_INFO_MEM_MAP) == 0) {
+		return 1;
+	}
+
+	mem = (struct multiboot_mmap_entry *) mbiptr->mmap_addr;
+	mem_info.e820_nr = 0;
+
+	for (i = 0; i < E820MAX; i++) {
+		if ((multiboot_uint32_t) mem >= (mbiptr->mmap_addr + mbiptr->mmap_length)) {
+			break;
+		}
+
+		mem_info.e820[mem_info.e820_nr].addr = mem->addr;
+		mem_info.e820[mem_info.e820_nr].size = mem->len;
+		/* Multiboot spec defines available / reserved types to match with E820.  */
+		mem_info.e820[mem_info.e820_nr].type = mem->type;
+		mem_info.e820_nr++;
+
+		mem = (struct multiboot_mmap_entry *) ((multiboot_uint32_t) mem + mem->size + sizeof (mem->size));
+	}
+
+	return 1;
+}
diff -Naur memtest86+-4.10.orig//multiboot.h memtest86+-4.10-patched//multiboot.h
--- memtest86+-4.10.orig//multiboot.h	1970-01-01 02:00:00.000000000 +0200
+++ memtest86+-4.10-patched//multiboot.h	2010-09-14 00:53:57.895247970 +0300
@@ -0,0 +1,259 @@ 
+/*  multiboot.h - Multiboot header file.  */
+/*  Copyright (C) 1999,2003,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to
+ *  deal in the Software without restriction, including without limitation the
+ *  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ *  sell copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL ANY
+ *  DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+ *  IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef MULTIBOOT_HEADER
+#define MULTIBOOT_HEADER 1
+
+/* How many bytes from the start of the file we search for the header.  */
+#define MULTIBOOT_SEARCH			8192
+
+/* The magic field should contain this.  */
+#define MULTIBOOT_HEADER_MAGIC			0x1BADB002
+
+/* This should be in %eax.  */
+#define MULTIBOOT_BOOTLOADER_MAGIC		0x2BADB002
+
+/* Alignment of multiboot modules.  */
+#define MULTIBOOT_MOD_ALIGN			0x00001000
+
+/* Alignment of the multiboot info structure.  */
+#define MULTIBOOT_INFO_ALIGN			0x00000004
+
+/* Flags set in the 'flags' member of the multiboot header.  */
+
+/* Align all boot modules on i386 page (4KB) boundaries.  */
+#define MULTIBOOT_PAGE_ALIGN			0x00000001
+
+/* Must pass memory information to OS.  */
+#define MULTIBOOT_MEMORY_INFO			0x00000002
+
+/* Must pass video information to OS.  */
+#define MULTIBOOT_VIDEO_MODE			0x00000004
+
+/* This flag indicates the use of the address fields in the header.  */
+#define MULTIBOOT_AOUT_KLUDGE			0x00010000
+
+/* Flags to be set in the 'flags' member of the multiboot info structure.  */
+
+/* is there basic lower/upper memory information? */
+#define MULTIBOOT_INFO_MEMORY			0x00000001
+/* is there a boot device set? */
+#define MULTIBOOT_INFO_BOOTDEV			0x00000002
+/* is the command-line defined? */
+#define MULTIBOOT_INFO_CMDLINE			0x00000004
+/* are there modules to do something with? */
+#define MULTIBOOT_INFO_MODS			0x00000008
+
+/* These next two are mutually exclusive */
+
+/* is there a symbol table loaded? */
+#define MULTIBOOT_INFO_AOUT_SYMS		0x00000010
+/* is there an ELF section header table? */
+#define MULTIBOOT_INFO_ELF_SHDR			0X00000020
+
+/* is there a full memory map? */
+#define MULTIBOOT_INFO_MEM_MAP			0x00000040
+
+/* Is there drive info?  */
+#define MULTIBOOT_INFO_DRIVE_INFO		0x00000080
+
+/* Is there a config table?  */
+#define MULTIBOOT_INFO_CONFIG_TABLE		0x00000100
+
+/* Is there a boot loader name?  */
+#define MULTIBOOT_INFO_BOOT_LOADER_NAME		0x00000200
+
+/* Is there a APM table?  */
+#define MULTIBOOT_INFO_APM_TABLE		0x00000400
+
+/* Is there video information?  */
+#define MULTIBOOT_INFO_VBE_INFO		        0x00000800
+#define MULTIBOOT_INFO_FRAMEBUFFER_INFO	        0x00001000
+
+#ifndef ASM_FILE
+
+typedef unsigned char		multiboot_uint8_t;
+typedef unsigned short		multiboot_uint16_t;
+typedef unsigned int		multiboot_uint32_t;
+typedef unsigned long long	multiboot_uint64_t;
+
+struct multiboot_header
+{
+  /* Must be MULTIBOOT_MAGIC - see above.  */
+  multiboot_uint32_t magic;
+
+  /* Feature flags.  */
+  multiboot_uint32_t flags;
+
+  /* The above fields plus this one must equal 0 mod 2^32. */
+  multiboot_uint32_t checksum;
+
+  /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set.  */
+  multiboot_uint32_t header_addr;
+  multiboot_uint32_t load_addr;
+  multiboot_uint32_t load_end_addr;
+  multiboot_uint32_t bss_end_addr;
+  multiboot_uint32_t entry_addr;
+
+  /* These are only valid if MULTIBOOT_VIDEO_MODE is set.  */
+  multiboot_uint32_t mode_type;
+  multiboot_uint32_t width;
+  multiboot_uint32_t height;
+  multiboot_uint32_t depth;
+};
+
+/* The symbol table for a.out.  */
+struct multiboot_aout_symbol_table
+{
+  multiboot_uint32_t tabsize;
+  multiboot_uint32_t strsize;
+  multiboot_uint32_t addr;
+  multiboot_uint32_t reserved;
+};
+typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
+
+/* The section header table for ELF.  */
+struct multiboot_elf_section_header_table
+{
+  multiboot_uint32_t num;
+  multiboot_uint32_t size;
+  multiboot_uint32_t addr;
+  multiboot_uint32_t shndx;
+};
+typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
+
+struct multiboot_color
+{
+  multiboot_uint8_t red;
+  multiboot_uint8_t green;
+  multiboot_uint8_t blue;
+};
+
+struct multiboot_info
+{
+  /* Multiboot info version number */
+  multiboot_uint32_t flags;
+
+  /* Available memory from BIOS */
+  multiboot_uint32_t mem_lower;
+  multiboot_uint32_t mem_upper;
+
+  /* "root" partition */
+  multiboot_uint32_t boot_device;
+
+  /* Kernel command line */
+  multiboot_uint32_t cmdline;
+
+  /* Boot-Module list */
+  multiboot_uint32_t mods_count;
+  multiboot_uint32_t mods_addr;
+
+  union
+  {
+    multiboot_aout_symbol_table_t aout_sym;
+    multiboot_elf_section_header_table_t elf_sec;
+  } u;
+
+  /* Memory Mapping buffer */
+  multiboot_uint32_t mmap_length;
+  multiboot_uint32_t mmap_addr;
+
+  /* Drive Info buffer */
+  multiboot_uint32_t drives_length;
+  multiboot_uint32_t drives_addr;
+
+  /* ROM configuration table */
+  multiboot_uint32_t config_table;
+
+  /* Boot Loader Name */
+  multiboot_uint32_t boot_loader_name;
+
+  /* APM table */
+  multiboot_uint32_t apm_table;
+
+  /* Video */
+  multiboot_uint32_t vbe_control_info;
+  multiboot_uint32_t vbe_mode_info;
+  multiboot_uint16_t vbe_mode;
+  multiboot_uint16_t vbe_interface_seg;
+  multiboot_uint16_t vbe_interface_off;
+  multiboot_uint16_t vbe_interface_len;
+
+  multiboot_uint64_t framebuffer_addr;
+  multiboot_uint32_t framebuffer_pitch;
+  multiboot_uint32_t framebuffer_width;
+  multiboot_uint32_t framebuffer_height;
+  multiboot_uint8_t framebuffer_bpp;
+#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED	0
+#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB		1
+#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT	2
+  multiboot_uint8_t framebuffer_type;
+  union
+  {
+    /* Indexed color.  */
+    struct
+    {
+      struct multiboot_color *framebuffer_palette_addr;
+      multiboot_uint16_t framebuffer_palette_num_colors;
+    };
+
+    /* Direct RGB color.  */
+    struct
+    {
+      multiboot_uint8_t framebuffer_red_field_position;
+      multiboot_uint8_t framebuffer_red_mask_size;
+      multiboot_uint8_t framebuffer_green_field_position;
+      multiboot_uint8_t framebuffer_green_mask_size;
+      multiboot_uint8_t framebuffer_blue_field_position;
+      multiboot_uint8_t framebuffer_blue_mask_size;
+    };
+  };
+};
+typedef struct multiboot_info multiboot_info_t;
+
+struct multiboot_mmap_entry
+{
+  multiboot_uint32_t size;
+  multiboot_uint64_t addr;
+  multiboot_uint64_t len;
+#define MULTIBOOT_MEMORY_AVAILABLE		1
+#define MULTIBOOT_MEMORY_RESERVED		2
+  multiboot_uint32_t type;
+} __attribute__((packed));
+typedef struct multiboot_mmap_entry multiboot_memory_map_t;
+
+struct multiboot_mod_list
+{
+  /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
+  multiboot_uint32_t mod_start;
+  multiboot_uint32_t mod_end;
+
+  /* Module command line */
+  multiboot_uint32_t cmdline;
+
+  /* padding to take it to 16 bytes (must be zero) */
+  multiboot_uint32_t pad;
+};
+typedef struct multiboot_mod_list multiboot_module_t;
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! MULTIBOOT_HEADER */
diff -Naur memtest86+-4.10.orig//reloc.c memtest86+-4.10-patched//reloc.c
--- memtest86+-4.10.orig//reloc.c	2010-04-28 15:11:15.000000000 +0300
+++ memtest86+-4.10-patched//reloc.c	2010-09-12 18:27:58.923297297 +0300
@@ -1,7 +1,6 @@ 
 #include <stddef.h>
 #include "stdint.h"
 #include "elf.h"
-#include <string.h>
 
 #define __ELF_NATIVE_CLASS 32
 #define ELF_MACHINE_NO_RELA 1
diff -Naur memtest86+-4.10.orig//test.c memtest86+-4.10-patched//test.c
--- memtest86+-4.10.orig//test.c	2010-04-28 15:11:15.000000000 +0300
+++ memtest86+-4.10-patched//test.c	2010-09-12 18:27:58.923297297 +0300
@@ -11,9 +11,9 @@ 
 
 #include "test.h"
 #include "config.h"
-#include <sys/io.h>
+#include "io.h"
 #include "dmi.h"
-#include <inttypes.h>
+#include "types.h"
 
 extern int segs, bail;
 extern volatile ulong *p;
diff -Naur memtest86+-4.10.orig//test.h memtest86+-4.10-patched//test.h
--- memtest86+-4.10.orig//test.h	2010-04-28 15:11:15.000000000 +0300
+++ memtest86+-4.10-patched//test.h	2010-09-14 00:56:25.629333240 +0300
@@ -104,8 +104,9 @@ 
 int memcmp(const void *s1, const void *s2, ulong count);
 int strncmp(const char *s1, const char *s2, ulong n);
 void *memmove(void *dest, const void *src, ulong n);
-int query_linuxbios(void);
+int query_coreboot(void);
 int query_pcbios(void);
+int query_multiboot(void);
 int insertaddress(ulong);
 void printpatn(void);
 void printpatn(void);
@@ -350,7 +351,8 @@ 
 
 #define FIRMWARE_UNKNOWN   0
 #define FIRMWARE_PCBIOS    1
-#define FIRMWARE_LINUXBIOS 2
+#define FIRMWARE_COREBOOT  2
+#define FIRMWARE_MULTIBOOT 3
 
 extern struct vars * const v;
 extern unsigned char _start[], _end[], startup_32[];
@@ -364,4 +366,4 @@ 
 #define CPM_SEQ    3
 
 #endif /* __ASSEMBLY__ */
-#endif /* _TEST_H_ */
\ No newline at end of file
+#endif /* _TEST_H_ */
diff -Naur memtest86+-4.10.orig//types.h memtest86+-4.10-patched//types.h
--- memtest86+-4.10.orig//types.h	1970-01-01 02:00:00.000000000 +0200
+++ memtest86+-4.10-patched//types.h	2010-09-12 18:27:58.923297297 +0300
@@ -0,0 +1,8 @@ 
+/* memtest86+ is self contained, so it may not use system include files */
+typedef unsigned int * uintptr_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef char int8_t;
+typedef short int16_t;
+typedef int int32_t;