/* * Functions to support the virtual addressing method of relocation * that Etherboot uses. * */ FILE_LICENCE ( GPL2_OR_LATER ) #include "librm.h" .arch i386 .text .code32 /**************************************************************************** * _virt_to_phys (virtual addressing) * * Switch from virtual to flat physical addresses. %esp is adjusted * to a physical value. Segment registers are set to flat physical * selectors. All other registers are preserved. Flags are * preserved. * * Parameters: none * Returns: none **************************************************************************** */ .globl _virt_to_phys _virt_to_phys: /* Preserve registers and flags */ pushfl pushl %eax pushl %ebp /* Change return address to a physical address */ movl virt_offset, %ebp addl %ebp, 12(%esp) /* Switch to physical code segment */ pushl $PHYSICAL_CS leal 1f(%ebp), %eax pushl %eax lret 1: /* Reload other segment registers and adjust %esp */ movl $PHYSICAL_DS, %eax movl %eax, %ds movl %eax, %es movl %eax, %fs movl %eax, %gs movl %eax, %ss addl %ebp, %esp /* Restore registers and flags, and return */ popl %ebp popl %eax popfl ret /**************************************************************************** * _phys_to_virt (flat physical addressing) * * Switch from flat physical to virtual addresses. %esp is adjusted * to a virtual value. Segment registers are set to virtual * selectors. All other registers are preserved. Flags are * preserved. * * Note that this depends on the GDT already being correctly set up * (e.g. by a call to run_here()). * * Parameters: none * Returns: none **************************************************************************** */ .globl _phys_to_virt _phys_to_virt: /* Preserve registers and flags */ pushfl pushl %eax pushl %ebp /* Switch to virtual code segment */ ljmp $VIRTUAL_CS, $1f 1: /* Reload data segment registers */ movl $VIRTUAL_DS, %eax movl %eax, %ds movl %eax, %es movl %eax, %fs movl %eax, %gs /* Reload stack segment and adjust %esp */ movl virt_offset, %ebp movl %eax, %ss subl %ebp, %esp /* Change the return address to a virtual address */ subl %ebp, 12(%esp) /* Restore registers and flags, and return */ popl %ebp popl %eax popfl ret