summaryrefslogtreecommitdiff
path: root/libre/memtest86+/multiboot.patch
blob: a3b9e46448cf7f5e88e7411d76a4b77e63bd40f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
commit 90bdb3dff10753cc10f3580473d379972176e3cb
Author: Robert Millan <rmh.debian@aybabtu.com>
Date:   Sun Jan 17 17:06:16 2010 +0100

    git-debimport memtest86+_4.00-2.2.diff.gz

Index: memtest86+/Makefile
===================================================================
--- memtest86+.orig/Makefile
+++ memtest86+/Makefile
@@ -14,11 +14,15 @@ CC=gcc
 
 CFLAGS= -Wall -march=i486 -m32 -O1 -fomit-frame-pointer -fno-builtin \
 	-ffreestanding -fPIC $(SMP_FL) -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 cpuid.o linuxbios.o pci.o memsize.o spd.o error.o dmi.o controller.o \
-      smp.o vmem.o random.o
-      
+      smp.o vmem.o random.o multiboot.o
 
 all: clean memtest.bin memtest 
 		 scp memtest.bin root@192.168.0.12:/srv/tftp/mt86plus
Index: memtest86+/head.S
===================================================================
--- memtest86+.orig/head.S
+++ memtest86+/head.S
@@ -13,9 +13,11 @@
 
 .text
 #define __ASSEMBLY__
+#define ASM_FILE
 #include "defs.h"
 #include "config.h"
 #include "test.h"
+#include "multiboot.h"
 
 	.code32
 	.globl startup_32
@@ -23,6 +25,13 @@ startup_32:
 	cld
 	cli
 
+	/* Store MBI pointer */
+	xorl	%ecx, %ecx
+	cmpl	$MULTIBOOT_BOOTLOADER_MAGIC, %eax
+	jne 0f
+	movl	%ebx, %ecx
+0:
+
 	/* Ensure I have a boot_stack pointer */
 	testl	%esp, %esp
 	jnz 0f
@@ -35,7 +44,21 @@ startup_32:
 0:	popl	%ebx
 	addl	$_GLOBAL_OFFSET_TABLE_+[.-0b], %ebx
 
-	/* Pick the appropriate boot_stack address */
+	/* 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	boot_stack_top@GOTOFF(%ebx), %esp
 
 	/* Reload all of the segment registers */
@@ -780,6 +803,9 @@ prot:
 	movl	$1, %eax
 	ret
 
+.globl mbiptr
+mbiptr:
+	.long	0
 realptr:
 	.word	real - RSTART
 	.word	0x0000
Index: memtest86+/init.c
===================================================================
--- memtest86+.orig/init.c
+++ memtest86+/init.c
@@ -19,8 +19,7 @@
 #include "smp.h"
 #include "io.h"
 #include "spd.h"
-#include "pci.h"
-#include "controller.h"
+#include "multiboot.h"
 
 extern struct tseq tseq[];
 extern short memsz_mode;
Index: memtest86+/main.c
===================================================================
--- memtest86+.orig/main.c
+++ memtest86+/main.c
@@ -16,6 +16,7 @@
 #include "cpuid.h"
 #include "smp.h"
 #include "config.h"
+#include "multiboot.h"
 #undef TEST_TIMES
 #define DEFTESTS 9
 #define FIRST_DIVISER 3
@@ -41,6 +42,8 @@ extern struct	barrier_s *barr;
 extern int 	num_cpus;
 extern int 	act_cpus;
 
+extern struct multiboot_info *mbiptr;
+
 static int	find_ticks_for_test(int test);
 void		find_ticks_for_pass(void);
 int		find_chunks(int test);
@@ -286,11 +289,15 @@ static void parse_command_line(void)
 		cpu_mask[i] = 1;
 	}
 
-	if (*OLD_CL_MAGIC_ADDR != OLD_CL_MAGIC)
-		return;
+	if (mbiptr && (mbiptr->flags & MULTIBOOT_INFO_CMDLINE)) {
+		cp = (void *) mbiptr->cmdline;
+	} else {
+		if (*OLD_CL_MAGIC_ADDR != OLD_CL_MAGIC)
+			return;
 
-	unsigned short offset = *OLD_CL_OFFSET_ADDR;
-	cp = MK_PTR(INITSEG, offset);
+		unsigned short offset = *OLD_CL_OFFSET_ADDR;
+		cp = MK_PTR(INITSEG, offset);
+	}
 
 	/* skip leading spaces */
 	while (*cp == ' ')
Index: memtest86+/memsize.c
===================================================================
--- memtest86+.orig/memsize.c
+++ memtest86+/memsize.c
@@ -36,7 +36,9 @@ void mem_size(void)
 
 	/* Get the memory size from the BIOS */
         /* Determine the memory map */
-	if (query_linuxbios()) {
+	if (query_multiboot()) {
+                flag = 2;
+        } else if (query_linuxbios()) {
 		flag = 1;
 	} else if (query_pcbios()) {
 		flag = 2;
Index: memtest86+/test.h
===================================================================
--- memtest86+.orig/test.h
+++ memtest86+/test.h
@@ -113,6 +113,7 @@ int strstr(char *str1, char *str2);
 int strlen(char *string);
 int query_linuxbios(void);
 int query_pcbios(void);
+int query_multiboot(void);
 int insertaddress(ulong);
 void printpatn(void);
 void printpatn(void);
@@ -307,6 +308,7 @@ struct vars {
 #define FIRMWARE_UNKNOWN   0
 #define FIRMWARE_PCBIOS    1
 #define FIRMWARE_LINUXBIOS 2
+#define FIRMWARE_MULTIBOOT 3
 
 extern struct vars * const v;
 extern unsigned char _start[], _end[], startup_32[];
diff --git a/multiboot.c b/multiboot.c
new file mode 100644
index 0000000..a81ebc2
--- /dev/null
+++ b/multiboot.c
@@ -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 --git a/multiboot.h b/multiboot.h
new file mode 100644
index 0000000..686a6b4
--- /dev/null
+++ b/multiboot.h
@@ -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 */