⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 passage.c

📁 一个Windows下的Linux专用虚拟机
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * This source code is a part of coLinux source package. * * Dan Aloni <da-x@colinux.org>, 2003 (c) * * The code is licensed under the GPL. See the COPYING file at * the root directory. * */ /* * The passage page and code are responsible for switching between the  * two operating systems. */ #include <colinux/common/debug.h>#include <colinux/common/libc.h>#include <colinux/common/common.h>#include <colinux/kernel/monitor.h>#include <colinux/arch/passage.h>#include <colinux/os/kernel/alloc.h>#include <colinux/os/kernel/misc.h>#include "cpuid.h"#include "manager.h"#include "utils.h"#include "antinx.h"#include "defs.h"#ifdef __MINGW32__#define SYMBOL_PREFIX "_"#else#define SYMBOL_PREFIX ""#endif#ifdef CO_COLINUX_KERNEL#error "CO_COLINUX_KERNEL should never defined here"#endif#ifdef CONFIG_COOPERATIVE#error "CONFIG_COOPERATIVE should never defined here"#endif/* * These two pseudo variables mark the start and the end of the passage code. * The passage code is position indepedent, so we just copy it from the  * driver's text to the passage page which we allocate when we start running. */#define PASSAGE_CODE_WRAP_IBCS(_name_, inner)           \extern char _name_;                                     \extern char _name_##_end;                               \							\static inline unsigned long _name_##_size(void)		\{							\	return &_name_##_end - &_name_;			\}							\							\static inline void memcpy_##_name_(void *dest)		\{							\	co_memcpy(dest, &_name_, _name_##_size());	\}							\							\asm(""							\    ".globl " SYMBOL_PREFIX #_name_          "\n"	\    SYMBOL_PREFIX #_name_ ":"                "\n"	\    "    push %ebx"                          "\n"	\    "    push %esi"                          "\n"	\    "    push %edi"                          "\n"	\    "    push %ebp"                          "\n"	\    inner						\    "    popl %ebp"                          "\n"	\    "    popl %edi"                          "\n"	\    "    popl %esi"                          "\n"	\    "    popl %ebx"                          "\n"	\    "    ret"                                "\n"	\    ".globl " SYMBOL_PREFIX #_name_ "_end"   "\n"	\    SYMBOL_PREFIX #_name_ "_end:;"           "\n"	\    "");#define PASSAGE_CODE_NOWHERE_LAND_SHORT()               \    /* Turn off special processor features */           \    "    movl %cr4, %ebx"                    "\n"       \    "    andl $0xFFFFFF77, %ebx"             "\n"       \    "    movl %ebx, %cr4"                    "\n"       \/* *  Relocate to other map of the passage page. *  *  We do this by changing the current mapping to the passage temporary  *  address space, which contains the mapping of the passage page at the  *  two locations which are specific to the two operating systems. */							\                                                        \/* Put the virtual address of the source passage page in EBX */ \    "    movl %ecx, %ebx"                    "\n"       \    "    andl $0xFFFFF000, %ebx"             "\n"       \                                                        \/*  * Take the physical address of the temporary address space page directory  * pointer and put it in CR3. */ \    "    movl (%ebx), %eax"                  "\n"       \    "    movl %eax, %cr3"                    "\n"       \/* * Read the 'other_map' field, which is the difference between the two * mappings. */ \    "    movl "CO_ARCH_STATE_STACK_OTHERMAP"(%ebp), %eax"   "\n"  \   \/*   * First, we relocate EIP by putting it in 0x64(%ebp). That's why we load * ESP with 0x68(%esp). The call that follows puts the EIP where we want. * Afterwards the EIP is in %(esp) so we relocate it by adding the  * relocation offset. We also add the difference between 2 and 3 so that * the 'ret' that follows will put us in 3 intead of 2, but in the other  * mapping. */ \    "    leal "CO_ARCH_STATE_STACK_RELOCATE_EIP_AFTER"(%ebp), %esp"              "\n"       \    "    call 2f"                            "\n"       \    "2:  addl %eax, (%esp)"                  "\n"       \    "    addl $3f-2b, (%esp)"                "\n"       \    "    ret"                                "\n"       \    "3:  addl %eax, %ecx"                    "\n"       \    "    movl %ecx, %ebp"                    "\n"       \#define PASSAGE_CODE_NOWHERE_LAND()					\    "    movl %ecx, %ebx"                    "\n"			\    "    andl $0xFFFFF000, %ebx"             "\n"			\    "    movl (%ebx), %edx"                  "\n"			\    "    movl %edx, %eax"                    "\n"			\    "    leal "CO_ARCH_STATE_STACK_RELOCATE_EIP_AFTER"(%ebp), %esp"           "\n" \    "    call 2f"                            "\n"			\    "2:  pop %ebx"                           "\n"			\    "    andl $0x00000FFF, %ebx"             "\n"			\    "    orl %eax, %ebx"                     "\n"			\    "    addl $3f-2b, %ebx"                  "\n"			\    "    movl "CO_ARCH_STATE_STACK_TEMP_CR3"(%ebp), %eax"  "\n"		\    "    movl %eax, %cr3"                    "\n"			\    "    call *%ebx"                         "\n"			\    "    jmp 4f"                             "\n"			\    "3:     "                                "\n"			\    "    movl "CO_ARCH_STATE_STACK_VA"(%ebp), %eax" "\n"		\    "    subl %edx, %eax"                    "\n"			\    "    subl %eax, %ecx"                    "\n"			\    "    subl %eax, %ebp"                    "\n"			\    "    subl %eax, (%esp)"                  "\n"			\    "    subl %eax, %esp"                    "\n"			\									\    "    movl %cr0, %eax"                    "\n"			\    "    andl $0x7fffffff, %eax"             "\n"			\    "    movl %eax, %cr0"                    "\n"			\									\    "    movl "CO_ARCH_STATE_STACK_CR4"(%ecx), %eax"  "\n"		\    "    andl $0x00000020, %eax"  "\n"					\    "    movl %eax, %cr4" "\n"						\    "    movl "CO_ARCH_STATE_STACK_TEMP_CR3"(%ecx), %eax"  "\n"		\    "    movl %eax, %cr3" "\n"						\									\    "    movl %cr0, %eax"                    "\n"			\    "    orl $0x80000000, %eax"              "\n"			\    "    movl %eax, %cr0"                    "\n"			\									\    "    movl "CO_ARCH_STATE_STACK_VA"(%ecx), %eax" "\n"		\    "    subl %edx, %eax"                    "\n"			\    "    addl %eax, %esp"                    "\n"			\    "    addl %eax, (%esp)"                  "\n"			\    "    addl %eax, %ecx"                    "\n"			\    "    movl %ecx, %ebp"                    "\n"			\    "    ret"                                "\n"			\									\    "  4:\n"								\#define PASSAGE_CODE_WRAP_SWITCH(_inner_)				\/* read return address and state pointers  */				\    "    movl 16(%esp), %ebx" /* return addr */ "\n"			\    "    movl 24(%esp), %ebp" /* current */     "\n"			\    "    movl 28(%esp), %ecx" /* other */       "\n"			\									\/* save flags, disable interrupts */					\    "    pushfl"                             "\n"			\    "    cli"                                "\n"			\									\/* save and switch from old esp */					\    "    movl %esp, "CO_ARCH_STATE_STACK_ESP"(%ebp)"   "\n"		\    "    mov %ss, "CO_ARCH_STATE_STACK_SS"(%ebp)"      "\n"		\									\/* save flags */							\    "    movl (%esp), %eax"                  "\n"			\    "    movl %eax, "CO_ARCH_STATE_STACK_FLAGS"(%ebp)"    "\n"		\									\/* save return address */						\    "    movl %ebx, "CO_ARCH_STATE_STACK_RETURN_EIP"(%ebp)"   "\n"	\									\/* save %cs */							        \    "    movl %cs, %ebx"                     "\n"			\    "    movl %ebx, "CO_ARCH_STATE_STACK_CS"(%ebp)"      "\n"		\									\    _inner_								\									\/* get old ESP in EAX */						\    "    lss "CO_ARCH_STATE_STACK_ESP"(%ebp), %eax" "\n"		\									\/* get return address */						\    "    movl "CO_ARCH_STATE_STACK_RETURN_EIP"(%ebp), %ebx"  "\n"	\    "    movl %ebx, 20(%eax)"                "\n"			\									\/* get flags */								\    "    movl "CO_ARCH_STATE_STACK_FLAGS"(%ebp), %ebx"   "\n"		\    "    movl %ebx, (%eax)"                  "\n"			\									\/* switch to old ESP */							\    "    lss "CO_ARCH_STATE_STACK_ESP"(%ebp), %esp"   "\n"		\									\    "    call 1f"                            "\n"			\    "1:  popl %eax"                          "\n"			\    "    addl $2f-1b,%eax"                   "\n"			\    "    movl 0x04(%ebp), %ebx"              "\n"			\    "    movw %bx, -2(%eax)"                 "\n"			\    "    movl %eax, -6(%eax)"                "\n"			\    "    jmp 3f"                             "\n"			\    "3:  ljmp $0,$0"                         "\n"			\    "2:  popfl"                              "\n"#define PASSAGE_PAGE_PRESERVATION_FXSAVE(_inner_)		\    "    fxsave "CO_ARCH_STATE_STACK_FXSTATE"(%ebp)"  "\n"	\    "    fnclex"                             "\n"		\    _inner_							\    "    fxrstor "CO_ARCH_STATE_STACK_FXSTATE"(%ebp)"   "\n"#define PASSAGE_PAGE_PRESERVATION_FNSAVE(_inner_)		\    "    fnsave "CO_ARCH_STATE_STACK_FXSTATE"(%ebp)" "\n"	\    "    fwait"                              "\n"		\    _inner_							\    "    frstor "CO_ARCH_STATE_STACK_FXSTATE"(%ebp)" "\n"#define PASSAGE_PAGE_PRESERVATION_DEBUG(_inner_)			\/* Put the virtual address of the passage page in EBX */		\    "    movl %ebp, %ebx"                    "\n"			\    "    andl $0xFFFFF000, %ebx"             "\n"			\/*  "    incb 0x20f(%ebx)"                   "\n" */			\									\/* save DR0 */								\    "    movl %dr0, %eax"                    "\n"			\    "    movl %eax, "CO_ARCH_STATE_STACK_DR0"(%ebp)"              "\n"	\    "    movl %eax, 0x4(%ebx)"               "\n"			\									\/* save DR1 */								\    "    movl %dr1, %eax"                    "\n"			\    "    movl %eax, "CO_ARCH_STATE_STACK_DR1"(%ebp)"              "\n"	\    "    movl %eax, 0x8(%ebx)"               "\n"			\									\/* save DR2 */								\    "    movl %dr2, %eax"                    "\n"			\    "    movl %eax, "CO_ARCH_STATE_STACK_DR2"(%ebp)"              "\n"	\    "    movl %eax, 0xc(%ebx)"               "\n"			\									\/* save DR3 */								\    "    movl %dr3, %eax"                    "\n"			\    "    movl %eax, "CO_ARCH_STATE_STACK_DR3"(%ebp)"              "\n"	\    "    movl %eax, 0x10(%ebx)"              "\n"			\									\/* save DR6 */								\    "    movl %dr6, %eax"                    "\n"			\    "    movl %eax, "CO_ARCH_STATE_STACK_DR6"(%ebp)"              "\n"	\    "    movl %eax, 0x14(%ebx)"              "\n"			\									\/* save DR7 */								\    "    movl %dr7, %eax"                    "\n"			\    "    movl %eax, "CO_ARCH_STATE_STACK_DR7"(%ebp)"              "\n"	\    "    movl $0x00000700, %eax"             "\n"			\    "    movl %eax, 0x18(%ebx)"              "\n"			\    "    movl %eax, %dr7"                    "\n"			\									\    _inner_								\									\/* Put the virtual address of the passage page in EBX */		\    "    movl %ebp, %ebx"                    "\n"			\    "    andl $0xFFFFF000, %ebx"             "\n"			\									\/* load DR0 */								\    "    movl "CO_ARCH_STATE_STACK_DR0"(%ebp), %eax"    "\n"		\    "    movl 0x4(%ebx), %ecx"               "\n"			\    "    cmpl %eax, %ecx"                    "\n"			\    "    jz 1f"                              "\n"			\    "    movl %eax, %dr0"                    "\n"			\    "1:"                                     "\n"			\									\/* load DR1 */								\    "    movl "CO_ARCH_STATE_STACK_DR1"(%ebp), %eax"    "\n"		\    "    movl 0x8(%ebx), %ecx"               "\n"			\    "    cmpl %eax, %ecx"                    "\n"			\    "    jz 1f"                              "\n"			\    "    movl %eax, %dr1"                    "\n"			\    "1:"                                     "\n"			\									\/* load DR2 */								\    "    movl "CO_ARCH_STATE_STACK_DR2"(%ebp), %eax"    "\n"		\    "    movl 0xC(%ebx), %ecx"               "\n"			\    "    cmpl %eax, %ecx"                    "\n"			\    "    jz 1f"                              "\n"			\    "    movl %eax, %dr2"                    "\n"			\    "1:"                                     "\n"			\									\/* load DR3 */								\    "    movl "CO_ARCH_STATE_STACK_DR3"(%ebp), %eax"    "\n"		\    "    movl 0x10(%ebx), %ecx"              "\n"			\    "    cmpl %eax, %ecx"                    "\n"			\    "    jz 1f"                              "\n"			\    "    movl %eax, %dr3"                    "\n"			\    "1:"                                     "\n"			\									\/* load DR6 */								\    "    movl "CO_ARCH_STATE_STACK_DR6"(%ebp), %eax"    "\n"		\    "    movl 0x14(%ebx), %ecx"              "\n"			\    "    cmpl %eax, %ecx"                    "\n"			\    "    jz 1f"                              "\n"			\    "    movl %eax, %dr6"                    "\n"			\    "1:"                                     "\n"			\									\/* load DR7 */								\    "    movl "CO_ARCH_STATE_STACK_DR7"(%ebp), %eax"    "\n"		\    "    movl 0x18(%ebx), %ecx"              "\n"			\    "    cmpl %eax, %ecx"                    "\n"			\    "    jz 1f"                              "\n"			\    "    movl %eax, %dr7"                    "\n"			\    "1:"                                     "\n"			\#define PASSAGE_PAGE_PRESERVATION_COMMON(_inner_)			\/* save GDT */								\    "    leal "CO_ARCH_STATE_STACK_GDT"(%ebp), %ebx"        "\n"	\    "    sgdt (%ebx)"                        "\n"			\									\/* save TR */								\    "    xor %eax, %eax"                     "\n"			\    "    str %ax"                            "\n"			\    "    movw %ax, "CO_ARCH_STATE_STACK_TR"(%ebp)"          "\n"	\									\/*									\ * If TR is not 0, turn off our task's BUSY bit so we don't get a GPF	\ * on the way back.							\ */									\    "    cmpw $0, %ax"                       "\n"			\    "    jz 1f"                              "\n"			\    "    movl 2(%ebx), %edx"                 "\n"			\    "    shr $3, %eax      "                 "\n"			\    "    andl $0xfffffdff, 4(%edx,%eax,8)"   "\n"			\    "1:"                                     "\n"			\									\/* save LDT */								\    "    sldt "CO_ARCH_STATE_STACK_LDT"(%ebp)"                    "\n"	\									\/* save IDT */								\    "    sidt "CO_ARCH_STATE_STACK_IDT"(%ebp)"                    "\n"	\									\/* save segment registers */						\    "    movl %gs, %ebx"                     "\n"			\    "    movl %ebx, "CO_ARCH_STATE_STACK_GS"(%ebp)"              "\n"	\    "    movl %fs, %ebx"                     "\n"			\    "    movl %ebx, "CO_ARCH_STATE_STACK_FS"(%ebp)"              "\n"	\    "    movl %ds, %ebx"                     "\n"			\    "    movl %ebx, "CO_ARCH_STATE_STACK_DS"(%ebp)"              "\n"	\    "    movl %es, %ebx"                     "\n"			\    "    movl %ebx, "CO_ARCH_STATE_STACK_ES"(%ebp)"              "\n"	\									\/* be on the safe side and nullify the segment registers */		\    "    movl $0, %ebx"                      "\n"			\    "    movl %ebx, %fs"                     "\n"			\    "    movl %ebx, %gs"                     "\n"			\									\/* save CR4 */								\    "    movl %cr4, %eax"                    "\n"			\    "    movl %eax, "CO_ARCH_STATE_STACK_CR4"(%ebp)"              "\n"	\									\/* save CR2 */								\    "    movl %cr2, %eax"                    "\n"			\    "    movl %eax, "CO_ARCH_STATE_STACK_CR2"(%ebp)"              "\n"	\									\/* save CR0 */								\    "    movl %cr0, %eax"                    "\n"			\    "    movl %eax, "CO_ARCH_STATE_STACK_CR0"(%ebp)"              "\n"	\									\/* save CR3 */								\    "    movl %cr3, %eax"                    "\n"			\    "    movl %eax, "CO_ARCH_STATE_STACK_CR3"(%ebp)"      "\n"		\									\_inner_									\/* load other's CR4 */							\    "    movl "CO_ARCH_STATE_STACK_CR4"(%ebp), %eax"              "\n"	\    "    movl %eax, %cr4"                    "\n"			\									\

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -