[2224] 2009-05-17 Vladimir Serbinenko <[email protected]>

Vladimir Serbinenko <[email protected]>
Newsgroups gmane.comp.boot-loaders.grub.cvs
Message-ID <[email protected]>
Revision: 2224
          http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=2224
Author:   phcoder
Date:     2009-05-17 11:27:08 +0000 (Sun, 17 May 2009)
Log Message:
-----------
2009-05-17  Vladimir Serbinenko  <[email protected]>

	trampoline for linux on 64-bit platform

	* conf/x86_64-efi.rmk (linux_mod_SOURCES): added 
	loader/i386/efi/linux_trampoline.S 
	* include/grub/x86_64/efi/loader.h (grub_linux_real_boot): removed 
	declration
	* kern/x86_64/efi/startup.S (grub_linux_real_boot): moved from here
	* loader/i386/linux_trampoline.S: moved here
	* loader/i386/efi/linux.c (allocate_pages): reserve space for trampoline
	(jumpvector): removed
	(grub_linux_trampoline_start): new declaration
	(grub_linux_trampoline_end): likewise
	(grub_linux_boot): use trampoline when on 64-bit platform
	* loader/i386/linux.c: likewise

Modified Paths:
--------------
    trunk/grub2/ChangeLog
    trunk/grub2/conf/x86_64-efi.rmk
    trunk/grub2/include/grub/x86_64/efi/loader.h
    trunk/grub2/kern/x86_64/efi/startup.S
    trunk/grub2/loader/i386/efi/linux.c
    trunk/grub2/loader/i386/linux.c

Added Paths:
-----------
    trunk/grub2/loader/i386/linux_trampoline.S

Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog	2009-05-17 00:37:10 UTC (rev 2223)
+++ trunk/grub2/ChangeLog	2009-05-17 11:27:08 UTC (rev 2224)
@@ -1,3 +1,20 @@
+2009-05-17  Vladimir Serbinenko  <[email protected]>
+
+	trampoline for linux on 64-bit platform
+
+	* conf/x86_64-efi.rmk (linux_mod_SOURCES): added 
+	loader/i386/efi/linux_trampoline.S 
+	* include/grub/x86_64/efi/loader.h (grub_linux_real_boot): removed 
+	declration
+	* kern/x86_64/efi/startup.S (grub_linux_real_boot): moved from here
+	* loader/i386/linux_trampoline.S: moved here
+	* loader/i386/efi/linux.c (allocate_pages): reserve space for trampoline
+	(jumpvector): removed
+	(grub_linux_trampoline_start): new declaration
+	(grub_linux_trampoline_end): likewise
+	(grub_linux_boot): use trampoline when on 64-bit platform
+	* loader/i386/linux.c: likewise
+
 2009-05-16  Pavel Roskin  <[email protected]>
 
 	* script/lua/grub_lib.c (grub_lua_getenv): Make name and value

Modified: trunk/grub2/conf/x86_64-efi.rmk
===================================================================
--- trunk/grub2/conf/x86_64-efi.rmk	2009-05-17 00:37:10 UTC (rev 2223)
+++ trunk/grub2/conf/x86_64-efi.rmk	2009-05-17 11:27:08 UTC (rev 2224)
@@ -137,7 +137,7 @@
 appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For linux.mod.
-linux_mod_SOURCES = loader/i386/efi/linux.c
+linux_mod_SOURCES = loader/i386/efi/linux.c loader/i386/linux_trampoline.S
 linux_mod_CFLAGS = $(COMMON_CFLAGS)
 linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
 

Modified: trunk/grub2/include/grub/x86_64/efi/loader.h
===================================================================
--- trunk/grub2/include/grub/x86_64/efi/loader.h	2009-05-17 00:37:10 UTC (rev 2223)
+++ trunk/grub2/include/grub/x86_64/efi/loader.h	2009-05-17 11:27:08 UTC (rev 2224)
@@ -22,6 +22,5 @@
 #include <grub/types.h>
 #include <grub/symbol.h>
 
-void EXPORT_FUNC(grub_linux_real_boot) (void);
 
 #endif /* ! GRUB_LOADER_MACHINE_HEADER */

Modified: trunk/grub2/kern/x86_64/efi/startup.S
===================================================================
--- trunk/grub2/kern/x86_64/efi/startup.S	2009-05-17 00:37:10 UTC (rev 2223)
+++ trunk/grub2/kern/x86_64/efi/startup.S	2009-05-17 11:27:08 UTC (rev 2224)
@@ -61,26 +61,3 @@
 	call	EXT_C(grub_main)
 	ret
 
-	.code32
-
-FUNCTION(grub_linux_real_boot)
-        /* Turn off PG bit in CR0 and set CR3 to zero.  */
-        movl    %cr0, %eax
-        andl    $0x7FFFFFFF, %eax
-        movl    %eax, %cr0
-
-        /* Setup EFER (Extended Feature Enable Register).  */
-        movl    $0xc0000080, %ecx
-        rdmsr
-
-        /* Disable Long Mode.  */
-        andl    $0xFFFFFEFF, %eax
-
-        /* Make changes effective.  */
-        wrmsr
-
-        /* Disable PAE.  */
-        xorl    %eax, %eax
-        movl    %eax, %cr4
-
-        jmp     *%ebx

Modified: trunk/grub2/loader/i386/efi/linux.c
===================================================================
--- trunk/grub2/loader/i386/efi/linux.c	2009-05-17 00:37:10 UTC (rev 2223)
+++ trunk/grub2/loader/i386/efi/linux.c	2009-05-17 11:27:08 UTC (rev 2224)
@@ -241,7 +241,7 @@
 	      
   /* Next, find free pages for the protected mode code.  */
   /* XXX what happens if anything is using this address?  */
-  prot_mode_mem = grub_efi_allocate_pages (0x100000, prot_mode_pages);
+  prot_mode_mem = grub_efi_allocate_pages (0x100000, prot_mode_pages + 1);
   if (! prot_mode_mem)
     {
       grub_error (GRUB_ERR_OUT_OF_MEMORY,
@@ -286,11 +286,8 @@
 }
 
 #ifdef __x86_64__
-struct
-{
-  grub_uint32_t kernel_entry;
-  grub_uint32_t kernel_cs;
-} jumpvector;
+extern grub_uint8_t grub_linux_trampoline_start[];
+extern grub_uint8_t grub_linux_trampoline_end[];
 #endif
 
 static grub_err_t
@@ -384,6 +381,18 @@
       params->v0204.efi_mmap_size = mmap_size;
     }
 
+#ifdef __x86_64__
+  
+  grub_memcpy ((char *) prot_mode_mem + (prot_mode_pages << 12), 
+	       grub_linux_trampoline_start, 
+	       grub_linux_trampoline_end - grub_linux_trampoline_start);
+  
+  ((void (*) (unsigned long, void *)) ((char *) prot_mode_mem 
+                                     + (prot_mode_pages << 12)))
+    (params->code32_start, real_mode_mem);
+
+#else
+
   /* Hardware interrupts are not safe any longer.  */
   asm volatile ("cli" : : );
   
@@ -391,18 +400,6 @@
   asm volatile ("lidt %0" : : "m" (idt_desc));
   asm volatile ("lgdt %0" : : "m" (gdt_desc));
 
-#ifdef __x86_64__
-
-  jumpvector.kernel_entry = (grub_uint64_t) grub_linux_real_boot;
-  jumpvector.kernel_cs = 0x10;
-
-  asm volatile ( "mov %0, %%rbx" : : "m" (params->code32_start));
-  asm volatile ( "mov %0, %%rsi" : : "m" (real_mode_mem));
-
-  asm volatile ( "ljmp *%0" : : "m" (jumpvector));
-
-#else
-
   /* Pass parameters.  */
   asm volatile ("movl %0, %%ecx" : : "m" (params->code32_start));
   asm volatile ("movl %0, %%esi" : : "m" (real_mode_mem));

Modified: trunk/grub2/loader/i386/linux.c
===================================================================
--- trunk/grub2/loader/i386/linux.c	2009-05-17 00:37:10 UTC (rev 2223)
+++ trunk/grub2/loader/i386/linux.c	2009-05-17 11:27:08 UTC (rev 2224)
@@ -433,11 +433,8 @@
 }
 
 #ifdef __x86_64__
-struct
-{
-  grub_uint32_t kernel_entry;
-  grub_uint32_t kernel_cs;
-} jumpvector;
+extern grub_uint8_t grub_linux_trampoline_start[];
+extern grub_uint8_t grub_linux_trampoline_end[];
 #endif
 
 static grub_err_t
@@ -549,7 +546,17 @@
   grub_mmap_iterate (hook);
   params->mmap_size = e820_num;
 
+#ifdef __x86_64__
 
+  grub_memcpy ((char *) prot_mode_mem + (prot_mode_pages << 12), 
+	       grub_linux_trampoline_start, 
+	       grub_linux_trampoline_end - grub_linux_trampoline_start);
+  
+  ((void (*) (unsigned long, void *)) ((char *) prot_mode_mem 
+				       + (prot_mode_pages << 12)))
+    (params->code32_start, real_mode_mem);
+#else
+
   /* Hardware interrupts are not safe any longer.  */
   asm volatile ("cli" : : );
   
@@ -557,18 +564,6 @@
   asm volatile ("lidt %0" : : "m" (idt_desc));
   asm volatile ("lgdt %0" : : "m" (gdt_desc));
 
-#ifdef __x86_64__
-
-  jumpvector.kernel_entry = (grub_uint64_t) grub_linux_real_boot;
-  jumpvector.kernel_cs = 0x10;
-
-  asm volatile ( "mov %0, %%rbx" : : "m" (params->code32_start));
-  asm volatile ( "mov %0, %%rsi" : : "m" (real_mode_mem));
-
-  asm volatile ( "ljmp *%0" : : "m" (jumpvector));
-
-#else
-
   /* Pass parameters.  */
   asm volatile ("movl %0, %%ecx" : : "m" (params->code32_start));
   asm volatile ("movl %0, %%esi" : : "m" (real_mode_mem));

Added: trunk/grub2/loader/i386/linux_trampoline.S
===================================================================
--- trunk/grub2/loader/i386/linux_trampoline.S	                        (rev 0)
+++ trunk/grub2/loader/i386/linux_trampoline.S	2009-05-17 11:27:08 UTC (rev 2224)
@@ -0,0 +1,112 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+	
+
+	.p2align	4	/* force 16-byte alignment */
+VARIABLE(grub_linux_trampoline_start)
+	cli
+	/* %rdi contains protected memory start and %rsi
+	contains real memory start. */
+
+	mov %rsi, %rbx
+	
+	call base
+base:	
+	pop %rsi
+	
+	lea (cont1-base)(%rsi, 1), %rax
+	mov %eax, (jump_vector-base)(%rsi,1)
+
+	lea (gdt-base)(%rsi, 1), %rax
+	mov %rax, (gdtaddr-base)(%rsi,1)
+	
+	/* Switch to compatibility mode. */
+
+	lidt (idtdesc-base)(%rsi,1)
+	lgdt (gdtdesc-base)(%rsi,1)
+	
+	/* Update %cs. Thanks to David Miller for pointing this mistake out. */
+	ljmp *(jump_vector-base)(%rsi,1)
+cont1:
+	.code32
+
+	/* Update other registers. */
+	mov $0x18, %eax
+	mov %eax, %ds 
+	mov %eax, %es
+	mov %eax, %fs
+	mov %eax, %gs
+	mov %eax, %ss
+
+	/* Disable paging. */
+	mov %cr0, %eax
+	and $0x7fffffff, %eax
+	mov %eax, %cr0
+
+	/* Disable amd64. */
+	mov $0xc0000080, %ecx
+	rdmsr
+	and $0xfffffeff, %eax
+	wrmsr
+
+	/* Turn off PAE. */
+	movl %cr4, %eax
+	and $0xffffffcf, %eax
+	mov %eax, %cr4
+
+	jmp cont2
+cont2:	
+	.code32
+	
+	mov %ebx, %esi
+
+	jmp *%edi
+
+	/* GDT. */
+	.p2align 4
+gdt:	
+	/* NULL.  */
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	
+	/* Reserved.  */
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	
+	/* Code segment.  */
+	.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
+	
+	/* Data segment.  */
+	.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
+
+gdtdesc:	
+	.word 31
+gdtaddr:	
+	.quad gdt
+
+idtdesc:	
+	.word 0
+idtaddr:	
+	.quad 0
+
+	.p2align 4
+jump_vector:
+	/* Jump location. Is filled by the code */
+	.long 0
+	.long 0x10	
+VARIABLE(grub_linux_trampoline_end)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.