From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1MIT5q-0004qQ-Sq for mharc-grub-devel@gnu.org; Sun, 21 Jun 2009 15:52:46 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MIT5q-0004qL-4e for grub-devel@gnu.org; Sun, 21 Jun 2009 15:52:46 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MIT5l-0004kq-9E for grub-devel@gnu.org; Sun, 21 Jun 2009 15:52:45 -0400 Received: from [199.232.76.173] (port=40239 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MIT5l-0004kn-4p for grub-devel@gnu.org; Sun, 21 Jun 2009 15:52:41 -0400 Received: from aybabtu.com ([69.60.117.155]:36335) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MIT5k-0001yx-LP for grub-devel@gnu.org; Sun, 21 Jun 2009 15:52:40 -0400 Received: from [192.168.10.10] (helo=thorin) by aybabtu.com with esmtp (Exim 4.69) (envelope-from ) id 1MIS2p-0004ds-BC for grub-devel@gnu.org; Sun, 21 Jun 2009 20:45:36 +0200 Received: from rmh by thorin with local (Exim 4.69) (envelope-from ) id 1MIT5h-00069M-Eb for grub-devel@gnu.org; Sun, 21 Jun 2009 21:52:37 +0200 Date: Sun, 21 Jun 2009 21:52:37 +0200 From: Robert Millan To: grub-devel@gnu.org Message-ID: <20090621195237.GA23624@thorin> References: <20090621181748.GA21152@thorin> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="3V7upXqbjpZ4EhLz" Content-Disposition: inline In-Reply-To: <20090621181748.GA21152@thorin> Organization: free as in freedom X-Message-Flag: Worried about Outlook viruses? Switch to Thunderbird! www.mozilla.com/thunderbird X-Debbugs-No-Ack: true User-Agent: Mutt/1.5.18 (2008-05-17) X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 1) Subject: [PATCH] swap real_to_prot() and prot_to_real() (Re: [PATCH] i386-qemu port) X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 19:52:46 -0000 --3V7upXqbjpZ4EhLz Content-Type: text/plain; charset=us-ascii Content-Disposition: inline When doing the i386-coreboot port I made this choice completely backwards. I thought real_to_prot() was only useful on i386-pc, because we needed it for returning from BIOS, and prot_to_real() was useful elsewhere, because the Linux loader would use it. Turns out we need real_to_prot() on i386-qemu for the initial transition to i386 mode, AND we don't need prot_to_real() anywhere other than i386-pc, because OSes that expect to be loaded in i8086 mode are going to rely on BIOS calls. So this patch swaps them. real_to_prot() goes to realmode.S and prot_to_real() back to startup.S. -- Robert Millan The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and how) you may access your data; but nobody's threatening your freedom: we still allow you to remove your data and not access it at all." --3V7upXqbjpZ4EhLz Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="real_prot.diff" 2009-06-21 Robert Millan * kern/i386/pc/startup.S (real_to_prot): Move from here ... * kern/i386/realmode.S (real_to_prot): ... to here. * kern/i386/realmode.S (prot_to_real): Move from here ... * kern/i386/pc/startup.S (prot_to_real): ... to here. Index: kern/i386/pc/startup.S =================================================================== --- kern/i386/pc/startup.S (revision 2353) +++ kern/i386/pc/startup.S (working copy) @@ -302,62 +302,73 @@ .p2align 2 /* force 4-byte alignment */ /* - * These next two routines, "real_to_prot" and "prot_to_real" are structured - * in a very specific way. Be very careful when changing them. + * This next routine, "prot_to_real" is structured in a very + * specific way. Be very careful when changing it. * - * NOTE: Use of either one messes up %eax and %ebp. + * NOTE: Use of it messes up %eax and %ebp. */ -real_to_prot: - .code16 - cli +prot_to_real: + /* just in case, set GDT */ + lgdt gdtdesc - /* load the GDT register */ -#ifdef APPLE_CC - mov %cs, %ax - mov %ax, %ds - DATA32 ADDR32 lgdt gdtdesc -#else - DATA32 ADDR32 lgdt %cs:gdtdesc -#endif + /* save the protected mode stack */ + movl %esp, %eax + movl %eax, protstack - /* turn on protected mode */ - movl %cr0, %eax - orl $GRUB_MEMORY_MACHINE_CR0_PE_ON, %eax - movl %eax, %cr0 + /* get the return address */ + movl (%esp), %eax + movl %eax, GRUB_MEMORY_MACHINE_REAL_STACK - /* jump to relocation, flush prefetch queue, and reload %cs */ - DATA32 ljmp $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg + /* set up new stack */ + movl $GRUB_MEMORY_MACHINE_REAL_STACK, %eax + movl %eax, %esp + movl %eax, %ebp - .code32 -protcseg: - /* reload other segment registers */ - movw $GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %ax + /* set up segment limits */ + movw $GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG, %ax movw %ax, %ds movw %ax, %es movw %ax, %fs movw %ax, %gs movw %ax, %ss - /* put the return address in a known safe location */ - movl (%esp), %eax - movl %eax, GRUB_MEMORY_MACHINE_REAL_STACK + /* this might be an extra step */ + /* jump to a 16 bit segment */ + ljmp $GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG, $tmpcseg - /* get protected mode stack */ - movl protstack, %eax - movl %eax, %esp - movl %eax, %ebp +tmpcseg: + .code16 - /* get return address onto the right stack */ - movl GRUB_MEMORY_MACHINE_REAL_STACK, %eax - movl %eax, (%esp) + /* clear the PE bit of CR0 */ + movl %cr0, %eax + andl $(~GRUB_MEMORY_MACHINE_CR0_PE_ON), %eax + movl %eax, %cr0 + /* flush prefetch queue, reload %cs */ + DATA32 ljmp $0, $realcseg + +realcseg: + /* we are in real mode now + * set up the real mode segment registers : DS, SS, ES + */ /* zero %eax */ xorl %eax, %eax - /* return on the old (or initialized) stack! */ - ret + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + /* restore interrupts */ + sti + + /* return on new stack! */ + DATA32 ret + + .code32 + /* * grub_gate_a20(int on) * Index: kern/i386/realmode.S =================================================================== --- kern/i386/realmode.S (revision 2353) +++ kern/i386/realmode.S (working copy) @@ -110,69 +110,59 @@ .long gdt /* addr */ /* - * These next routine, "prot_to_real" is structured in a very + * This next routine, "real_to_prot" is structured in a very * specific way. Be very careful when changing it. * * NOTE: Use of it messes up %eax and %ebp. */ -prot_to_real: - /* just in case, set GDT */ - lgdt gdtdesc +real_to_prot: + .code16 + cli - /* save the protected mode stack */ - movl %esp, %eax - movl %eax, protstack + /* load the GDT register */ +#ifdef APPLE_CC + mov %cs, %ax + mov %ax, %ds + DATA32 ADDR32 lgdt gdtdesc +#else + DATA32 ADDR32 lgdt %cs:gdtdesc +#endif - /* get the return address */ - movl (%esp), %eax - movl %eax, GRUB_MEMORY_MACHINE_REAL_STACK + /* turn on protected mode */ + movl %cr0, %eax + orl $GRUB_MEMORY_MACHINE_CR0_PE_ON, %eax + movl %eax, %cr0 - /* set up new stack */ - movl $GRUB_MEMORY_MACHINE_REAL_STACK, %eax - movl %eax, %esp - movl %eax, %ebp + /* jump to relocation, flush prefetch queue, and reload %cs */ + DATA32 ljmp $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg - /* set up segment limits */ - movw $GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG, %ax + .code32 +protcseg: + /* reload other segment registers */ + movw $GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %ax movw %ax, %ds movw %ax, %es movw %ax, %fs movw %ax, %gs movw %ax, %ss - /* this might be an extra step */ - /* jump to a 16 bit segment */ - ljmp $GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG, $tmpcseg + /* put the return address in a known safe location */ + movl (%esp), %eax + movl %eax, GRUB_MEMORY_MACHINE_REAL_STACK -tmpcseg: - .code16 + /* get protected mode stack */ + movl protstack, %eax + movl %eax, %esp + movl %eax, %ebp - /* clear the PE bit of CR0 */ - movl %cr0, %eax - andl $(~GRUB_MEMORY_MACHINE_CR0_PE_ON), %eax - movl %eax, %cr0 + /* get return address onto the right stack */ + movl GRUB_MEMORY_MACHINE_REAL_STACK, %eax + movl %eax, (%esp) - /* flush prefetch queue, reload %cs */ - DATA32 ljmp $0, $realcseg - -realcseg: - /* we are in real mode now - * set up the real mode segment registers : DS, SS, ES - */ /* zero %eax */ xorl %eax, %eax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - movw %ax, %ss - - /* restore interrupts */ - sti - - /* return on new stack! */ - DATA32 ret - + /* return on the old (or initialized) stack! */ + ret .code32 --3V7upXqbjpZ4EhLz--