Àðõèòåêòóðà x86-64 ïîä ñêàëüïåëåì àññåìáëåðùèêà

         

>>> Âðåçêà ïåðåõîä â 64-ðàçðäÿíûé ðåæèì


 èñõîäíèêàõ FreeBSD ìîæíî íàéòè ôàéë amd64_tramp.S, áûñòðî è ãðÿçíî ïåðåâîäÿùèé ïðîöåññîð â 64-ðåæèì. Îòêîìïèëèðîâàâ, åãî ìîæíî çàïèñàòü â boot-ñåêòîð, çàãðóæàþùèé íàøó ñîáñòâåííóþ îïåðàöèîííóþ ñèñòåìó (âû âåäü ïèøèòå åå, ïðàâäà?) èëè ñëèíêîâàòü com-ôàéë, çàïóñêàåìûé èç ðåàëüíîãî x86-ðåæèìà (äëÿ ýòîãî ïîòðåáóåòñÿ ÷èñòàÿ MS-DOS áåçî âñÿêèõ ýêñòåíäåðîâ).  îáùåì, âàðèàíòîâ ìíîãî…

//$FreeBSD: /repoman/r/ncvs/src/sys/boot/i386/libi386/amd64_tramp.S,v 1.4 2004/05/14

/*

 * Quick and dirty trampoline to get into 64 bit (long) mode and running

 * with paging enabled so that we enter the kernel at its linked address.

 */

#define MSR_EFER     0xc0000080

#define EFER_LME     0x00000100

#define CR4_PAE      0x00000020

#define CR4_PSE      0x00000010

#define CR0_PG             0x80000000

/* GRRR. Deal with BTX that links us for a non-zero location */

#define VPBASE       0xa000



#define VTOP(x)      ((x) + VPBASE)

       .data

       .p2align 12,0x40

       .globl PT4

PT4:

       .space 0x1000

       .globl PT3

PT3:

       .space 0x1000

       .globl PT2

PT2:

       .space 0x1000

gdtdesc:

       .word  gdtend - gdt

       .long  VTOP(gdt)            # low

       .long  0                    # high

gdt:

       .long  0                    # null descriptor

       .long  0

       .long  0x00000000           # %cs

       .long  0x00209800

       .long  0x00000000           # %ds

       .long  0x00008000

gdtend:

      

       .text

       .code32

      

       .globl amd64_tramp

amd64_tramp:

       /* Be sure that interrupts are disabled */

       cli

      

       /* Turn on EFER.LME */

       movl   $MSR_EFER, %ecx

       rdmsr

       orl    $EFER_LME, %eax

       wrmsr

      

       /* Turn on PAE */

       movl   %cr4, %eax

       orl    $(CR4_PAE | CR4_PSE), %eax

       movl   %eax, %cr4

      

       /* Set %cr3 for PT4 */

       movl   $VTOP(PT4), %eax

       movl   %eax, %cr3

      

       /* Turn on paging (implicitly sets EFER.LMA) */

       movl   %cr0, %eax

       orl    $CR0_PG, %eax

       movl   %eax, %cr0

      

       /* Now we're in compatability mode. set %cs for long mode */

       movl   $VTOP(gdtdesc), %eax

       movl   VTOP(entry_hi), %esi

       movl   VTOP(entry_lo), %edi

       lgdt   (%eax)

       ljmp   $0x8, $VTOP(longmode)

      

       .code64

longmode:

       /* We're still running V=P, jump to entry point */

       movl   %esi, %eax

       salq   $32, %rax

       orq    %rdi, %rax

       pushq  %rax

       ret



Ñîäåðæàíèå ðàçäåëà