* libcurses++, libc++ and liblightOS++ are installed into the crosscompiler directory
[lightOS.git] / toolchain / grub_x86_64.patch
blob480e38fceb7bd66a18f4ab9adde57b119fa0e985
1 diff -Naur grub-0.97.orig/docs/multiboot.h grub-0.97.patched/docs/multiboot.h
2 --- grub-0.97.orig/docs/multiboot.h 2003-07-09 05:45:36.000000000 -0600
3 +++ grub-0.97.patched/docs/multiboot.h 2006-08-26 22:44:02.000000000 -0600
4 @@ -44,76 +44,81 @@
5 /* Do not include here in boot.S. */
7 /* Types. */
8 +#ifndef __x86_64__
9 +typedef unsigned long UINT32;
10 +#else
11 +typedef unsigned UINT32;
12 +#endif
14 /* The Multiboot header. */
15 typedef struct multiboot_header
17 - unsigned long magic;
18 - unsigned long flags;
19 - unsigned long checksum;
20 - unsigned long header_addr;
21 - unsigned long load_addr;
22 - unsigned long load_end_addr;
23 - unsigned long bss_end_addr;
24 - unsigned long entry_addr;
25 + UINT32 magic;
26 + UINT32 flags;
27 + UINT32 checksum;
28 + UINT32 header_addr;
29 + UINT32 load_addr;
30 + UINT32 load_end_addr;
31 + UINT32 bss_end_addr;
32 + UINT32 entry_addr;
33 } multiboot_header_t;
35 /* The symbol table for a.out. */
36 typedef struct aout_symbol_table
38 - unsigned long tabsize;
39 - unsigned long strsize;
40 - unsigned long addr;
41 - unsigned long reserved;
42 + UINT32 tabsize;
43 + UINT32 strsize;
44 + UINT32 addr;
45 + UINT32 reserved;
46 } aout_symbol_table_t;
48 /* The section header table for ELF. */
49 typedef struct elf_section_header_table
51 - unsigned long num;
52 - unsigned long size;
53 - unsigned long addr;
54 - unsigned long shndx;
55 + UINT32 num;
56 + UINT32 size;
57 + UINT32 addr;
58 + UINT32 shndx;
59 } elf_section_header_table_t;
61 /* The Multiboot information. */
62 typedef struct multiboot_info
64 - unsigned long flags;
65 - unsigned long mem_lower;
66 - unsigned long mem_upper;
67 - unsigned long boot_device;
68 - unsigned long cmdline;
69 - unsigned long mods_count;
70 - unsigned long mods_addr;
71 + UINT32 flags;
72 + UINT32 mem_lower;
73 + UINT32 mem_upper;
74 + UINT32 boot_device;
75 + UINT32 cmdline;
76 + UINT32 mods_count;
77 + UINT32 mods_addr;
78 union
80 aout_symbol_table_t aout_sym;
81 elf_section_header_table_t elf_sec;
82 } u;
83 - unsigned long mmap_length;
84 - unsigned long mmap_addr;
85 + UINT32 mmap_length;
86 + UINT32 mmap_addr;
87 } multiboot_info_t;
89 /* The module structure. */
90 typedef struct module
92 - unsigned long mod_start;
93 - unsigned long mod_end;
94 - unsigned long string;
95 - unsigned long reserved;
96 + UINT32 mod_start;
97 + UINT32 mod_end;
98 + UINT32 string;
99 + UINT32 reserved;
100 } module_t;
102 /* The memory map. Be careful that the offset 0 is base_addr_low
103 but no size. */
104 typedef struct memory_map
106 - unsigned long size;
107 - unsigned long base_addr_low;
108 - unsigned long base_addr_high;
109 - unsigned long length_low;
110 - unsigned long length_high;
111 - unsigned long type;
112 + UINT32 size;
113 + UINT32 base_addr_low;
114 + UINT32 base_addr_high;
115 + UINT32 length_low;
116 + UINT32 length_high;
117 + UINT32 type;
118 } memory_map_t;
120 #endif /* ! ASM */
121 diff -Naur grub-0.97.orig/docs/x86_64.txt grub-0.97.patched/docs/x86_64.txt
122 --- grub-0.97.orig/docs/x86_64.txt 1969-12-31 17:00:00.000000000 -0700
123 +++ grub-0.97.patched/docs/x86_64.txt 2006-10-10 10:39:42.000000000 -0600
124 @@ -0,0 +1,81 @@
125 +[PATCH] - Make GRUB recognize and boot an x86_64 elf image
128 +HOW IT WORKS
129 +------------
130 +* Grub interface is unchanged.
131 +* Upon passing an elf-x86_64 file via "kernel=", GRUB will load and parse it
132 + correctly.
133 +* Upon the "boot" directive, GRUB will switch from protected 32-bit
134 + mode to long 64-bit mode and transfer control to the image's entrypoint.
137 +INSTALL
138 +-------
139 +cd grub-0.97
140 +patch -p1 < grub-x86_64-elf.patch
141 +./configure
142 +make
143 +su -c "make install"
145 +Note: You do not need to re-install your bootsectors, but you WILL need
146 + to copy the modified stage2 file(s) from /usr/share/grub to
147 + your actual boot filesystem (usually /boot/grub for GNU/Linux).
150 +WHY?
151 +----
152 +Because in our world, all elves and elf images are created equal, and have
153 +been endowed with the ability to be bootable. :-)
156 +THE NITTY GRITTY - GRUB SIDE
157 +----------------------------
158 +* Since paging is manditory in 64-bit long mode, the first 4GB of physical
159 + memory (whether present or not) is identity mapped into the linear
160 + address space using 2MB pages.
161 +* Paging data structures are written to physical 0x70000-0x75fff in the
162 + same area reserved for the raw device buffer. This happens after the
163 + "boot" command is issued so the raw device buffer won't mind. Paging
164 + can be relocated and reconfigured after the kernel is running.
165 +* Header files have been added to describe the x86_64 elf image structure.
168 +THE NITTY GRITTY - KERNEL SIDE
169 +------------------------------
170 +* Parameters passed to the assembly entrypoint are unchanged including
171 + magic number and pointer to multiboot info structure.
172 +* The assembly entrypoint should be designated as ".code64".
173 +* The Global Descriptor Table (GDT) shared by the GRUB and KERNEL sides
174 + has been expanded to include 3 additional 64-bit ('L' bit set) segments:
175 + 0x28 (code) and 0x30 (data).
176 +* An updated "multiboot.h" file is provided to reflect the difference in
177 + "unsigned long" sizes between i386 and x86_64 architectures for use by
178 + the client kernel.
181 +CAVEATS
182 +-------
183 +Possible collisions with existing GRUB patch sets are unknown. Use "darcs"
184 +and worry not.
186 + http://abridgegame.org/darcs
188 +(An intelligent alternative to cvs and greying hair in the distributed
189 +post-mainframe age.)
192 +DOCUMENTATION CHANGES
193 +---------------------
194 +This is it. Sorry, stuff to do.
197 +APOLOGIES TO GRUB2
198 +------------------
199 +We would have liked to use GRUB2 for this, but needed it today for our
200 +kernel. Of course there is probably no technical reason why this
201 +functionality cannot be in included in GRUB2 at a future time. Thank you
202 +for a way cool bootloader and may all your boots be bogon (and Vogon) free.
204 +<mcnster@gmail.com>
205 +October 10, 2006
206 diff -Naur grub-0.97.orig/grub/asmstub.c grub-0.97.patched/grub/asmstub.c
207 --- grub-0.97.orig/grub/asmstub.c 2005-02-16 13:45:14.000000000 -0700
208 +++ grub-0.97.patched/grub/asmstub.c 2006-08-26 22:43:24.000000000 -0600
209 @@ -313,6 +313,12 @@
210 stop ();
213 +void
214 +multi_boot_64bit_doit (int start, int mb_info)
216 + stop ();
219 /* sets it to linear or wired A20 operation */
220 void
221 gateA20 (int linear)
222 diff -Naur grub-0.97.orig/stage2/asm.S grub-0.97.patched/stage2/asm.S
223 --- grub-0.97.orig/stage2/asm.S 2004-06-19 10:55:22.000000000 -0600
224 +++ grub-0.97.patched/stage2/asm.S 2006-09-25 14:59:48.000000000 -0600
225 @@ -1809,6 +1809,54 @@
226 /* error */
227 call EXT_C(stop)
229 +ENTRY(multi_boot_64bit_doit)
230 + call EXT_C(stop_floppy)
232 + /* dont squash these! */
233 + movl 0x8(%esp), %esi
234 + movl 0x4(%esp), %edi
236 + cli
238 + mov %cr0, %eax
239 + and $0x7fffffff, %eax
240 + mov %eax, %cr0
242 + /* enable pae */
243 + mov %cr4, %eax
244 + or $0x20, %eax
245 + mov %eax, %cr4
247 + /* load cr3 with pml4 */
248 + mov $PML4, %eax
249 + mov %eax, %cr3
251 + /* trigger long mode */
252 + mov $0xc0000080, %ecx
253 + rdmsr
254 + or $0x100, %eax
255 + wrmsr
257 + /* enable paging to actually switch modes */
258 + mov %cr0, %eax
259 + or $0x80000000, %eax
260 + mov %eax, %cr0
262 + /* jump to relocation, flush prefetch queue, and reload %cs */
263 + ljmp $0x28, $longmode
264 +.code64
265 +longmode:
266 + mov $0x2BADB002, %eax
268 + mov %rsi, %rbx
269 + and $0xffffffff, %rsi
271 + and $0xffffffff, %rdi
272 + call *%rdi
273 + /* NOTREACHED */
274 + call EXT_C(stop)
276 +.code32
277 #endif /* ! STAGE1_5 */
280 @@ -2341,27 +2389,35 @@
282 .p2align 2 /* force 4-byte alignment */
283 gdt:
284 - .word 0, 0
285 + .word 0, 0 /* 0x0000 */
286 .byte 0, 0, 0, 0
288 - /* code segment */
289 + /* code segment */ /* 0x0008 */
290 .word 0xFFFF, 0
291 .byte 0, 0x9A, 0xCF, 0
293 - /* data segment */
294 + /* data segment */ /* 0x0010 */
295 .word 0xFFFF, 0
296 .byte 0, 0x92, 0xCF, 0
298 - /* 16 bit real mode CS */
299 + /* 16 bit real mode CS */ /* 0x0018 */
300 .word 0xFFFF, 0
301 .byte 0, 0x9E, 0, 0
303 - /* 16 bit real mode DS */
304 + /* 16 bit real mode DS/SS */ /* 0x0020 */
305 .word 0xFFFF, 0
306 .byte 0, 0x92, 0, 0
308 + /* 64 bit long mode CS */ /* 0x0028 */
309 + .word 0xFFFF, 0
310 + .byte 0, 0x9A, 0xAF, 0
312 + /* 64-bit long mode SS */ /* 0x0030 */
313 + .word 0xFFFF, 0
314 + .byte 0, 0x92, 0xAF, 0
316 /* this is the GDT descriptor */
317 gdtdesc:
318 - .word 0x27 /* limit */
319 + .word 0x33 /* limit */
320 .long gdt /* addr */
321 + .long 0 /* in case we go to 64-bit mode */
322 diff -Naur grub-0.97.orig/stage2/boot.c grub-0.97.patched/stage2/boot.c
323 --- grub-0.97.orig/stage2/boot.c 2004-03-30 04:44:08.000000000 -0700
324 +++ grub-0.97.patched/stage2/boot.c 2006-08-25 22:20:17.000000000 -0600
325 @@ -23,10 +23,11 @@
327 #include "freebsd.h"
328 #include "imgact_aout.h"
329 -#include "i386-elf.h"
330 +#include "elf.h"
332 static int cur_addr;
333 entry_func entry_addr;
334 +unsigned long_64bit_mode = 0;
335 static struct mod_list mll[99];
336 static int linux_mem_size;
338 @@ -50,7 +51,7 @@
340 struct multiboot_header *mb;
341 struct exec *aout;
342 - Elf32_Ehdr *elf;
343 + Elf_Ehdr *elf;
346 /* presuming that MULTIBOOT_SEARCH is large enough to encompass an
347 @@ -100,21 +101,25 @@
348 || pu.elf->e_ident[EI_OSABI] == ELFOSABI_FREEBSD
349 || grub_strcmp (pu.elf->e_ident + EI_BRAND, "FreeBSD") == 0
350 || suggested_type == KERNEL_TYPE_NETBSD)
351 - && len > sizeof (Elf32_Ehdr)
352 - && BOOTABLE_I386_ELF ((*((Elf32_Ehdr *) buffer))))
353 + && len > SIZEOF_ELF_EHDR (pu.elf)
354 + && (BOOTABLE_I386_ELF ((*((Elf32_Ehdr *) buffer)))
355 + || BOOTABLE_X86_64_ELF ((*((Elf64_Ehdr *) buffer)))))
357 + if (BOOTABLE_X86_64_ELF ((*((Elf64_Ehdr *) buffer))))
358 + long_64bit_mode = 1;
360 if (type == KERNEL_TYPE_MULTIBOOT)
361 - entry_addr = (entry_func) pu.elf->e_entry;
362 + entry_addr = (entry_func) E_ENTRY (pu.elf);
363 else
364 - entry_addr = (entry_func) (pu.elf->e_entry & 0xFFFFFF);
365 + entry_addr = (entry_func) (E_ENTRY (pu.elf) & 0xFFFFFF);
367 if (entry_addr < (entry_func) 0x100000)
368 errnum = ERR_BELOW_1MB;
370 /* don't want to deal with ELF program header at some random
371 place in the file -- this generally won't happen */
372 - if (pu.elf->e_phoff == 0 || pu.elf->e_phnum == 0
373 - || ((pu.elf->e_phoff + (pu.elf->e_phentsize * pu.elf->e_phnum))
374 + if (E_PHOFF (pu.elf) == 0 || E_PHNUM (pu.elf) == 0
375 + || ((E_PHOFF (pu.elf) + (E_PHENTSIZE (pu.elf) * E_PHNUM (pu.elf)))
376 >= len))
377 errnum = ERR_EXEC_FORMAT;
378 str = "elf";
379 @@ -590,39 +595,38 @@
380 /* ELF executable */
382 unsigned loaded = 0, memaddr, memsiz, filesiz;
383 - Elf32_Phdr *phdr;
384 + Elf_Phdr *phdr;
386 /* reset this to zero for now */
387 cur_addr = 0;
389 /* scan for program segments */
390 - for (i = 0; i < pu.elf->e_phnum; i++)
391 + for (i = 0; i < E_PHNUM (pu.elf); i++)
393 - phdr = (Elf32_Phdr *)
394 - (pu.elf->e_phoff + ((int) buffer)
395 - + (pu.elf->e_phentsize * i));
396 - if (phdr->p_type == PT_LOAD)
397 + phdr = (Elf_Phdr *) (E_PHOFF (pu.elf) + ((int) buffer)
398 + + (E_PHENTSIZE (pu.elf) * i));
399 + if (P_TYPE (pu.elf, phdr) == PT_LOAD)
401 /* offset into file */
402 - grub_seek (phdr->p_offset);
403 - filesiz = phdr->p_filesz;
404 + grub_seek (P_OFFSET (pu.elf, phdr));
405 + filesiz = P_FILESZ (pu.elf, phdr);
407 if (type == KERNEL_TYPE_FREEBSD || type == KERNEL_TYPE_NETBSD)
408 - memaddr = RAW_ADDR (phdr->p_paddr & 0xFFFFFF);
409 + memaddr = RAW_ADDR (P_PADDR (pu.elf, phdr) & 0xFFFFFF);
410 else
411 - memaddr = RAW_ADDR (phdr->p_paddr);
412 + memaddr = RAW_ADDR (P_PADDR (pu.elf, phdr));
414 - memsiz = phdr->p_memsz;
415 + memsiz = P_MEMSZ (pu.elf, phdr);
416 if (memaddr < RAW_ADDR (0x100000))
417 errnum = ERR_BELOW_1MB;
419 /* If the memory range contains the entry address, get the
420 physical address here. */
421 if (type == KERNEL_TYPE_MULTIBOOT
422 - && (unsigned) entry_addr >= phdr->p_vaddr
423 - && (unsigned) entry_addr < phdr->p_vaddr + memsiz)
424 + && (unsigned) entry_addr >= P_VADDR (pu.elf, phdr)
425 + && (unsigned) entry_addr < P_VADDR (pu.elf, phdr) + memsiz)
426 real_entry_addr = (entry_func) ((unsigned) entry_addr
427 - + memaddr - phdr->p_vaddr);
428 + + memaddr - P_VADDR (pu.elf, phdr));
430 /* make sure we only load what we're supposed to! */
431 if (filesiz > memsiz)
432 @@ -654,26 +658,26 @@
433 else
435 /* Load ELF symbols. */
436 - Elf32_Shdr *shdr = NULL;
437 + Elf_Shdr *shdr = NULL;
438 int tab_size, sec_size;
439 int symtab_err = 0;
441 - mbi.syms.e.num = pu.elf->e_shnum;
442 - mbi.syms.e.size = pu.elf->e_shentsize;
443 - mbi.syms.e.shndx = pu.elf->e_shstrndx;
444 + mbi.syms.e.num = E_SHNUM (pu.elf);
445 + mbi.syms.e.size = E_SHENTSIZE (pu.elf);
446 + mbi.syms.e.shndx = E_SHSTRNDX (pu.elf);
448 /* We should align to a 4K boundary here for good measure. */
449 if (align_4k)
450 cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;
452 - tab_size = pu.elf->e_shentsize * pu.elf->e_shnum;
453 + tab_size = E_SHENTSIZE (pu.elf) * E_SHNUM (pu.elf);
455 - grub_seek (pu.elf->e_shoff);
456 + grub_seek (E_SHOFF (pu.elf));
457 if (grub_read ((char *) RAW_ADDR (cur_addr), tab_size)
458 == tab_size)
460 mbi.syms.e.addr = cur_addr;
461 - shdr = (Elf32_Shdr *) mbi.syms.e.addr;
462 + shdr = (Elf_Shdr *) mbi.syms.e.addr;
463 cur_addr += tab_size;
465 printf (", shtab=0x%x", cur_addr);
466 @@ -682,20 +686,20 @@
468 /* This section is a loaded section,
469 so we don't care. */
470 - if (shdr[i].sh_addr != 0)
471 + if (SH_ADDR_AT (pu.elf, shdr, i) != 0)
472 continue;
474 /* This section is empty, so we don't care. */
475 - if (shdr[i].sh_size == 0)
476 + if (SH_SIZE_AT (pu.elf, shdr, i) == 0)
477 continue;
479 /* Align the section to a sh_addralign bits boundary. */
480 - cur_addr = ((cur_addr + shdr[i].sh_addralign) &
481 - - (int) shdr[i].sh_addralign);
482 + cur_addr = ((cur_addr + SH_ADDRALIGN_AT (pu.elf, shdr, i)) &
483 + - (int) SH_ADDRALIGN_AT (pu.elf, shdr, i));
485 - grub_seek (shdr[i].sh_offset);
486 + grub_seek (SH_OFFSET_AT (pu.elf, shdr, i));
488 - sec_size = shdr[i].sh_size;
489 + sec_size = SH_SIZE_AT (pu.elf, shdr, i);
491 if (! (memcheck (cur_addr, sec_size)
492 && (grub_read ((char *) RAW_ADDR (cur_addr),
493 @@ -706,7 +710,7 @@
494 break;
497 - shdr[i].sh_addr = cur_addr;
498 + SET_SH_ADDR_AT (pu.elf, shdr, i, cur_addr);
499 cur_addr += sec_size;
502 diff -Naur grub-0.97.orig/stage2/builtins.c grub-0.97.patched/stage2/builtins.c
503 --- grub-0.97.orig/stage2/builtins.c 2005-02-15 14:58:23.000000000 -0700
504 +++ grub-0.97.patched/stage2/builtins.c 2006-09-25 14:59:16.000000000 -0600
505 @@ -81,6 +81,7 @@
506 /* Prototypes for allowing straightfoward calling of builtins functions
507 inside other functions. */
508 static int configfile_func (char *arg, int flags);
509 +static void multi_boot_64bit (int entry_addr, int mbi);
511 /* Initialize the data for builtins. */
512 void
513 @@ -297,8 +298,11 @@
514 break;
516 case KERNEL_TYPE_MULTIBOOT:
517 - /* Multiboot */
518 - multi_boot ((int) entry_addr, (int) &mbi);
520 + if (long_64bit_mode)
521 + multi_boot_64bit((int) entry_addr, (int) &mbi);
522 + else
523 + multi_boot ((int) entry_addr, (int) &mbi);
524 break;
526 default:
527 @@ -309,6 +313,73 @@
528 return 0;
531 +#define TABLE_BITS 0x7 /* user, r/w, present */
532 +#define PAGE_BITS 0x87 /* not pat, not global, not dirty, not accessed, user, r/w, present */
534 +#define NOT_PRESENT_TABLE 0x6
535 +#define NOT_PRESENT_PAGE 0x86
538 +static void
539 +multi_boot_64bit (int entry_addr, int mbi)
541 + unsigned *pml4 = PML4;
542 + unsigned *pdpt0x000 = PDPT0x000;
543 + unsigned *pd0x000_000 = PD0x000_000;
544 + unsigned *pd0x000_001 = PD0x000_001;
545 + unsigned *pd0x000_002 = PD0x000_002;
546 + unsigned *pd0x000_003 = PD0x000_003;
547 + int i;
548 + unsigned long base;
550 + /* identity map 1st 4 GB */
552 + for (i = 0; i < 512; i++)
554 + pml4[i * 2 + 0] = NOT_PRESENT_TABLE;
555 + pml4[i * 2 + 1] = 0;
557 + pdpt0x000[i * 2 + 0] = NOT_PRESENT_TABLE;
558 + pdpt0x000[i * 2 + 1] = 0;
560 + pd0x000_000[i * 2 + 0] = NOT_PRESENT_PAGE;
561 + pd0x000_000[i * 2 + 1] = 0;
562 + pd0x000_001[i * 2 + 0] = NOT_PRESENT_PAGE;
563 + pd0x000_001[i * 2 + 1] = 0;
564 + pd0x000_002[i * 2 + 0] = NOT_PRESENT_PAGE;
565 + pd0x000_002[i * 2 + 1] = 0;
566 + pd0x000_003[i * 2 + 0] = NOT_PRESENT_PAGE;
567 + pd0x000_003[i * 2 + 1] = 0;
570 + pml4[0x000 * 2 + 0] = PDPT0x000 + TABLE_BITS;
571 + pml4[0x000 * 2 + 1] = 0;
573 + pdpt0x000[0x000 * 2 + 0] = PD0x000_000 + TABLE_BITS;
574 + pdpt0x000[0x000 * 2 + 1] = 0;
575 + pdpt0x000[0x001 * 2 + 0] = PD0x000_001 + TABLE_BITS;
576 + pdpt0x000[0x001 * 2 + 1] = 0;
577 + pdpt0x000[0x002 * 2 + 0] = PD0x000_002 + TABLE_BITS;
578 + pdpt0x000[0x002 * 2 + 1] = 0;
579 + pdpt0x000[0x003 * 2 + 0] = PD0x000_003 + TABLE_BITS;
580 + pdpt0x000[0x003 * 2 + 1] = 0;
582 + for (i = 0, base = 0; i < 1005; i++, base += 0x200000)
584 + pd0x000_000[i * 2 + 0] = base + PAGE_BITS;
585 + pd0x000_000[i * 2 + 1] = 0;
586 + pd0x000_001[i * 2 + 0] = base + (1 * 0x200 * 0x20000) + PAGE_BITS;
587 + pd0x000_001[i * 2 + 1] = 0;
588 + pd0x000_002[i * 2 + 0] = base + (2 * 0x200 * 0x20000) + PAGE_BITS;
589 + pd0x000_002[i * 2 + 1] = 0;
590 + pd0x000_003[i * 2 + 0] = base + (3 * 0x200 * 0x20000) + PAGE_BITS;
591 + pd0x000_003[i * 2 + 1] = 0;
594 + multi_boot_64bit_doit (entry_addr, mbi);
595 + /* NOTREACHED */
598 static struct builtin builtin_boot =
600 "boot",
601 diff -Naur grub-0.97.orig/stage2/elf.h grub-0.97.patched/stage2/elf.h
602 --- grub-0.97.orig/stage2/elf.h 1969-12-31 17:00:00.000000000 -0700
603 +++ grub-0.97.patched/stage2/elf.h 2006-08-25 21:58:37.000000000 -0600
604 @@ -0,0 +1,79 @@
606 + * GRUB -- GRand Unified Bootloader
607 + * Copyright (C) 2001,2002,2006 Free Software Foundation, Inc.
609 + * This program is free software; you can redistribute it and/or modify
610 + * it under the terms of the GNU General Public License as published by
611 + * the Free Software Foundation; either version 2 of the License, or
612 + * (at your option) any later version.
614 + * This program is distributed in the hope that it will be useful,
615 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
616 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
617 + * GNU General Public License for more details.
619 + * You should have received a copy of the GNU General Public License
620 + * along with this program; if not, write to the Free Software
621 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
622 + */
625 +#include "i386-elf.h"
626 +#include "x86-64-elf.h"
629 +typedef union
631 + unsigned char e_ident[EI_NIDENT];
632 + Elf32_Ehdr elf32;
633 + Elf64_Ehdr elf64;
635 +Elf_Ehdr;
638 +typedef union
640 + Elf32_Phdr elf32;
641 + Elf64_Phdr elf64;
643 +Elf_Phdr;
646 +typedef union
648 + Elf32_Shdr elf32;
649 + Elf64_Shdr elf64;
651 +Elf_Shdr;
654 +#define SIZEOF_ELF_EHDR(h) (h->e_ident[EI_CLASS] == ELFCLASS32 ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr))
656 +#define E_ENTRY(h) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? h->elf32.e_entry : h->elf64.e_entry))
657 +#define E_PHOFF(h) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? h->elf32.e_phoff : h->elf64.e_phoff))
658 +#define E_PHNUM(h) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? h->elf32.e_phnum : h->elf64.e_phnum))
659 +#define E_PHENTSIZE(h) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? h->elf32.e_phentsize : h->elf64.e_phentsize))
660 +#define E_SHNUM(h) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? h->elf32.e_shnum : h->elf64.e_shnum))
661 +#define E_SHENTSIZE(h) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? h->elf32.e_shentsize : h->elf64.e_shentsize))
662 +#define E_SHSTRNDX(h) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? h->elf32.e_shstrndx : h->elf64.e_shstrndx))
663 +#define E_SHOFF(h) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? h->elf32.e_shoff : h->elf64.e_shoff))
665 +#define P_TYPE(h, p) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? p->elf32.p_type : p->elf64.p_type))
666 +#define P_OFFSET(h, p) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? p->elf32.p_offset : p->elf64.p_offset))
667 +#define P_PADDR(h, p) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? p->elf32.p_paddr : p->elf64.p_paddr))
668 +#define P_MEMSZ(h, p) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? p->elf32.p_memsz : p->elf64.p_memsz))
669 +#define P_VADDR(h, p) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? p->elf32.p_vaddr : p->elf64.p_vaddr))
670 +#define P_FILESZ(h, p) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? p->elf32.p_filesz : p->elf64.p_filesz))
672 +#define SH_ADDR_AT(h, sh, i) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? ((&(sh->elf32))[i]).sh_addr : ((&(sh->elf64))[i]).sh_addr))
673 +#define SH_SIZE_AT(h, sh, i) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? ((&(sh->elf32))[i]).sh_size : ((&(sh->elf64))[i]).sh_size))
674 +#define SH_ADDRALIGN_AT(h, sh, i) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? ((&(sh->elf32))[i]).sh_addralign : ((&(sh->elf64))[i]).sh_addralign))
675 +#define SH_OFFSET_AT(h, sh, i) ((unsigned) (h->e_ident[EI_CLASS] == ELFCLASS32 ? ((&(sh->elf32))[i]).sh_offset : ((&(sh->elf64))[i]).sh_offset))
677 +#define SET_SH_ADDR_AT(h, sh, i, v) \
678 + { \
679 + if (h->e_ident[EI_CLASS] == ELFCLASS32) \
680 + ((&(sh->elf32))[i]).sh_addr = v; \
681 + else \
682 + ((&(sh->elf64))[i]).sh_addr = v; \
684 diff -Naur grub-0.97.orig/stage2/shared.h grub-0.97.patched/stage2/shared.h
685 --- grub-0.97.orig/stage2/shared.h 2004-06-19 10:40:09.000000000 -0600
686 +++ grub-0.97.patched/stage2/shared.h 2006-09-25 14:54:53.000000000 -0600
687 @@ -70,6 +70,13 @@
689 #define BOOT_PART_TABLE RAW_ADDR (0x07be)
691 +#define PML4 0x70000
692 +#define PDPT0x000 0x71000
693 +#define PD0x000_000 0x72000
694 +#define PD0x000_001 0x73000
695 +#define PD0x000_002 0x74000
696 +#define PD0x000_003 0x75000
699 * BIOS disk defines
701 @@ -692,6 +699,8 @@
703 extern entry_func entry_addr;
705 +extern unsigned long_64bit_mode;
707 /* Enter the stage1.5/stage2 C code after the stack is set up. */
708 void cmain (void);
710 @@ -739,6 +748,9 @@
711 /* booting a multiboot executable */
712 void multi_boot (int start, int mb_info) __attribute__ ((noreturn));
714 +/* boot into 64-bit long mode */
715 +void multi_boot_64bit_doit (int start, int mb_info) __attribute__ ((noreturn));
717 /* If LINEAR is nonzero, then set the Intel processor to linear mode.
718 Otherwise, bit 20 of all memory accesses is always forced to zero,
719 causing a wraparound effect for bugwards compatibility with the
720 diff -Naur grub-0.97.orig/stage2/x86-64-elf.h grub-0.97.patched/stage2/x86-64-elf.h
721 --- grub-0.97.orig/stage2/x86-64-elf.h 1969-12-31 17:00:00.000000000 -0700
722 +++ grub-0.97.patched/stage2/x86-64-elf.h 2006-08-26 21:45:22.000000000 -0600
723 @@ -0,0 +1,86 @@
725 + * GRUB -- GRand Unified Bootloader
726 + * Copyright (C) 2001,2002,2006 Free Software Foundation, Inc.
728 + * This program is free software; you can redistribute it and/or modify
729 + * it under the terms of the GNU General Public License as published by
730 + * the Free Software Foundation; either version 2 of the License, or
731 + * (at your option) any later version.
733 + * This program is distributed in the hope that it will be useful,
734 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
735 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
736 + * GNU General Public License for more details.
738 + * You should have received a copy of the GNU General Public License
739 + * along with this program; if not, write to the Free Software
740 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
741 + */
744 +typedef unsigned short Elf64_Half;
745 +typedef unsigned long Elf64_Word;
746 +typedef unsigned long long Elf64_Off;
747 +typedef unsigned long long Elf64_Addr;
748 +typedef unsigned long long Elf64_Xword;
751 +typedef struct
753 + unsigned char e_ident[EI_NIDENT]; /* basic identification block */
754 + Elf64_Half e_type; /* file types */
755 + Elf64_Half e_machine; /* machine types */
756 + Elf64_Word e_version; /* use same as "EI_VERSION" above */
757 + Elf64_Addr e_entry; /* entry point of the program */
758 + Elf64_Off e_phoff; /* program header table file offset */
759 + Elf64_Off e_shoff; /* section header table file offset */
760 + Elf64_Word e_flags; /* flags */
761 + Elf64_Half e_ehsize; /* elf header size in bytes */
762 + Elf64_Half e_phentsize; /* program header entry size */
763 + Elf64_Half e_phnum; /* number of entries in program header */
764 + Elf64_Half e_shentsize; /* section header entry size */
765 + Elf64_Half e_shnum; /* number of entries in section header */
766 + Elf64_Half e_shstrndx; /* section header table index */
768 +Elf64_Ehdr;
771 +typedef struct
773 + Elf64_Word p_type;
774 + Elf64_Word p_flags;
775 + Elf64_Off p_offset;
776 + Elf64_Addr p_vaddr;
777 + Elf64_Addr p_paddr;
778 + Elf64_Xword p_filesz;
779 + Elf64_Xword p_memsz;
780 + Elf64_Xword p_align;
782 +Elf64_Phdr;
785 +typedef struct
787 + Elf64_Word sh_name; /* Section name (string tbl index) */
788 + Elf64_Word sh_type; /* Section type */
789 + Elf64_Xword sh_flags; /* Section flags */
790 + Elf64_Addr sh_addr; /* Section virtual addr at execution */
791 + Elf64_Off sh_offset; /* Section file offset */
792 + Elf64_Xword sh_size; /* Section size in bytes */
793 + Elf64_Word sh_link; /* Link to another section */
794 + Elf64_Word sh_info; /* Additional section information */
795 + Elf64_Xword sh_addralign; /* Section alignment */
796 + Elf64_Xword sh_entsize; /* Entry size if section holds table */
798 +Elf64_Shdr;
800 +#define ELFCLASS64 2
802 +#define EM_X86_64 0x3e
804 +#define BOOTABLE_X86_64_ELF(h) \
805 + ((h.e_ident[EI_MAG0] == ELFMAG0) & (h.e_ident[EI_MAG1] == ELFMAG1) \
806 + & (h.e_ident[EI_MAG2] == ELFMAG2) & (h.e_ident[EI_MAG3] == ELFMAG3) \
807 + & (h.e_ident[EI_CLASS] == ELFCLASS64) & (h.e_ident[EI_DATA] == ELFDATA2LSB) \
808 + & (h.e_ident[EI_VERSION] == EV_CURRENT) & (h.e_type == ET_EXEC) \
809 + & (h.e_machine == EM_X86_64) & (h.e_version == EV_CURRENT))