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