2

xen のコードを読んで、以下のコードを見つけました。しかし、その意味がわかりません。idt初期化するコードgdtですか?リアル モードからプロテクト モードにジャンプするコードですか。gdtもしそうなら、との物理アドレスはidtどこですか? Hvmloader.c :

asm (
    "    .text                       \n"
    "    .globl _start               \n"
    "_start:                         \n"
    /* C runtime kickoff. */
    "    cld                         \n"
    "    cli                         \n"
    "    lgdt gdt_desr               \n"
    "    mov  $"STR(SEL_DATA32)",%ax \n"
    "    mov  %ax,%ds                \n"
    "    mov  %ax,%es                \n"
    "    mov  %ax,%fs                \n"
    "    mov  %ax,%gs                \n"
    "    mov  %ax,%ss                \n"
    "    ljmp $"STR(SEL_CODE32)",$1f \n"
    "1:  movl $stack_top,%esp        \n"
    "    movl %esp,%ebp              \n"
    "    call main                   \n"
    /* Relocate real-mode trampoline to 0x0. */
    "    mov  $trampoline_start,%esi \n"
    "    xor  %edi,%edi              \n"
    "    mov  $trampoline_end,%ecx   \n"
    "    sub  %esi,%ecx              \n"
    "    rep  movsb                  \n"
    /* Load real-mode compatible segment state (base 0x0000, limit 0xffff). */
    "    mov  $"STR(SEL_DATA16)",%ax \n"
    "    mov  %ax,%ds                \n"
    "    mov  %ax,%es                \n"
    "    mov  %ax,%fs                \n"
    "    mov  %ax,%gs                \n"
    "    mov  %ax,%ss                \n"
    /* Initialise all 32-bit GPRs to zero. */
    "    xor  %eax,%eax              \n"
    "    xor  %ebx,%ebx              \n"
    "    xor  %ecx,%ecx              \n"
    "    xor  %edx,%edx              \n"
    "    xor  %esp,%esp              \n"
    "    xor  %ebp,%ebp              \n"
    "    xor  %esi,%esi              \n"
    "    xor  %edi,%edi              \n"
    /* Enter real mode, reload all segment registers and IDT. */
    "    ljmp $"STR(SEL_CODE16)",$0x0\n"
    "trampoline_start: .code16       \n"
    "    mov  %eax,%cr0              \n"
    "    ljmp $0,$1f-trampoline_start\n"
    "1:  mov  %ax,%ds                \n"
    "    mov  %ax,%es                \n"
    "    mov  %ax,%fs                \n"
    "    mov  %ax,%gs                \n"
    "    mov  %ax,%ss                \n"
    "    lidt 1f-trampoline_start    \n"
    "    ljmp $0xf000,$0xfff0        \n"
    "1:  .word 0x3ff,0,0             \n"
    "trampoline_end:   .code32       \n"
    "                                \n"
    "gdt_desr:                       \n"
    "    .word gdt_end - gdt - 1     \n"
    "    .long gdt                   \n"
    "                                \n"
    "    .align 8                    \n"
    "gdt:                            \n"
    "    .quad 0x0000000000000000    \n"
    "    .quad 0x008f9a000000ffff    \n" /* Ring 0 16b code, base 0 limit 4G */
    "    .quad 0x008f92000000ffff    \n" /* Ring 0 16b data, base 0 limit 4G */
    "    .quad 0x00cf9a000000ffff    \n" /* Ring 0 32b code, base 0 limit 4G */
    "    .quad 0x00cf92000000ffff    \n" /* Ring 0 32b data, base 0 limit 4G */
    "    .quad 0x00af9a000000ffff    \n" /* Ring 0 64b code */
    "gdt_end:                        \n"
    "                                \n"
    "    .bss                        \n"
    "    .align    8                 \n"
    "stack:                          \n"
    "    .skip    0x4000             \n"
    "stack_top:                      \n"
    "    .text                       \n"
    );

ありがとう。

4

1 に答える 1

1

コードの最初から:

cld-方向フラグをクリアします。

cli-割り込みフラグをクリアして、割り込みをマスクします。

lgdt gdt_desr-の値をにロードしgdt_desrますgdtgdt_desrにロードされた値を見つけるためにソースコードを探してくださいgdt

"    mov  $"STR(SEL_DATA32)",%ax \n"
"    mov  %ax,%ds                \n"
"    mov  %ax,%es                \n"
"    mov  %ax,%fs                \n"
"    mov  %ax,%gs                \n"
"    mov  %ax,%ss                \n"

STR(SEL_DATA32)値をax、に格納してaxからdsesからfs、、、、gsおよびss(を除くすべてのセグメントレジスタにcs)を格納します。

"    ljmp $"STR(SEL_CODE32)",$1f \n"

にロングジャンプ/ファージャンプをSTR(SEL_CODE32):0x1f行い、実際にはとに設定csします。STR(SEL_CODE32)eip0x1f

これが32ビットコードセグメントの場合、プロセッサは32ビットプロテクトモードになります。Stackoverflowの質問:bootloader-プロセッサをプロテクトモードに切り替えるを参照してください。ただし、上記の例やプロテクトモードに関するウィキペディアの記事のように、レジスタのPEビットを設定するために使用されるコードはここには表示されません。cr0

その後、そのコード行は、このコードには示されていないcs:eipそのアドレス(STR(SEL_CODE32):0x1f)に移動するため、その場合に何が起こるかはわかりません。cs:eipそこを指している場合(それがジャンプアドレスの場合)、次の行にも続く可能性があります。とにかく、残りのコードとコメントは、プロテクトモードからリアルモードに切り替えるために使用されるコードのように見えます。

Intructionはのlidt 1f-trampoline_start値をにロードする1f-trampoline_startためidt、実際に使用されている値を知るには、ソースで。を検索しますif-trampoline_start

于 2013-01-08T10:42:16.207 に答える