IA32-e 페이징 전환 관련

시갈 2013.11.23 18:55 조회 수 : 1785

 /*
     * IA-32e 페이징 기능을 활성화하는 방법은 IA32_EFER LME,
     * CR0 레지스터의 PG bit, CR3 레지스터 설정, CR4 레지스터의 PAE bit만
     * 1로 설정하면된다.
     * PG bit는 CR0 레지스터의 최상위 비트에 위치하며 프로세서의
     * 페이징 기능을 제어하는 비트이다. PG bit를 설정하는 순간
     * 프로세서의 페이징 기능이 활성화 되므로 1로 설정하기전에
     * CR4, CR3 레지스터를 설정하여야 한다.
     */

    /* Enable PAE mode and PGE */
    movl    $(X86_CR4_PAE | X86_CR4_PGE), %ecx
    movq    %rcx, %cr4
    /*
     * IA-32e 모드에서 2MB 페이징을 활성화하기 위하여 설정
     * PAE: Physical Address Extensions의 약자로 36bit(64GB) 이상의
     *       물리 메모리를 사용할지 여부를 설정한다.
     * PGE: Page Global Enable의 약자로 Global Page Feature를 사용할지
     *      여부를 설정한다. 1로 설정하면 Global Page Feature를 사용함을
     *      나타내며 CR3 레지스터가 교체되어 페이지 테이블이 바뀌는 경우
     *      페이지 테이블 엔트리의 G bit가 1로 설정된 페이지는 TLB에서
     *      교체되지 않는다.
     */

 

    /* Check if nx is implemented */
    movl    $0x80000001, %eax
    cpuid
    movl    %edx,%edi
    /*
     * $0x00000001 cpuid: 기본 cpuid 정보 조회
     * $0x80000001 cpuid: 확장 기능 cpuid 정보 조회
     *                    ECX: 비트 0 - 64비트 모드에서 LAHF/SAHF 명령지원 여부
     *                         그외 나머지 비트는 제조사마다 차이가 있음
     *                    EDX: 비트 11 - 64비트 모드에서 SYSCALL/SYSRET
     *                                   명령지원 여부
     *                         비트 20 - Execute Disable 비트지원 여부
     *                         비트 29 - 64비트 모드 지원여부
     *                         그외 나머지 비트는 제조사마다 차이가 있음
     */

    /*
     * IA-32e 모드를 활성화하기 위해서는 먼저 IA32_EFER 레지스터의 LME비트를
     * 1로 설정하여야한다. LME를 활성화하지 않으면 IA-32e 모드용 세그먼트
     * 레지스터로 교체해도 32비트 보호모드로 동작한다.
     * IA32_EFER 레지스터는 범용 또는 컨트롤 레지스터가 아니며
     * MSR(Model-Specific Register)이라고 불리는 특수용도 레지스터이다.
     *
     * MSR 레지스터의 종류에는 크게 6가지가 있다.
     *   1. 디버깅 및 성능 측정
     *   2. 하드웨어 에러 검사
     *   3. 메모리 범위와 메모리 타입 설정
     *   4. 온도와 전력 관리
     *   5. 특수 명령어 지원
     *   6. 프로세서 특성과 모드 지원
     *
     * IA32_EFER 레지스터는 프로세서 특성과 모드 지원에 속하는 MSR 레지스터로
     * 프로세서의 확장 기능을 제어할 수 있다.
     * 제어할 수 있는 항목에는 SYSCALL/SYSRET 명령어 사용, IA-32e 모드사용,
     * Execute Disable(EXB) 사용 등이 있으며 현재 운영중인 모드가 IA-32e 모드
     * 인지 확인하는 기능도 있다.
     *
     * MSR 레지스터는 개별적으로 할당된 레지스터 어드레스가 있고 해당
     * 어드레스를 통해서만 접근할 수 있다. 또한 mov 명령으로 접근할 수 없으며
     * MSR 레지스터용 명령인 rdmsr과 wrmsr을 사용하여야 한다.
     * rdmsr 명령어는 MSR 레지스터에서 값을 읽어오는 역할을하며 ECX, EDX, EAX를
     * 사용한다. ECX에 읽을 MSR 레지스터 어드레스를 넘겨주면 MSR의 상위 32비트는
     * EDX에 하위 32비트는 EAX에 저장해준다. wrmsr도 rdmsr과 동일한 방법으로
     * MSR 레지스터에 값을 저장한다.
     * IA32_EREF 레지스터 어드레스는 0xc0000080이며 비트구성은 아래와 같다.
     *
     * 비트        필드        읽기/쓰기모드          설명
     * 63 ~ 12     -           -                  제조사마다 차이가 있음
     * 11          NXE         읽기/쓰기          No Excute Enable 약자로 Excute Disable 비트를 사용할지 여부를 표시하며 0으로 설정
     *                                                    하면 페이지 엔트리의 EXB 비트가 무시된다.
     * 10          LMA         읽기전용           Long Mode Active 약자로 프로세서가 IA-32e 모드로 동작중인지 표시한다.
     * 9           -              예약됨             예약된 영역
     * 8           LME         읽기/쓰기          Long Mode Enable 약자로 IA-32e 모드 활성화를 의미한다.
     * 7 ~ 1       -           예약됨             예약된 영역
     * 0           SCE         읽기/쓰기         System Call Enable 약자로 SYSCALL/SYSRET 명령어 사용 여부를 나타낸다.
     */

 

    /* Setup EFER (Extended Feature Enable Register) */
    movl    $MSR_EFER, %ecx         // MSR_EFER = 0xc0000080
    rdmsr
    /*
     * IA32_EREF 레지스터를 read
     */

    btsl    $_EFER_SCE, %eax
    /*
     * Enable System Call
     * _EFER_SCE = 0
     * bts: bit test and set
     */

    btl $20,%edi
    /*
     * 비트 20 - Execute Disable 비트지원 여부
     */
    jnc     1f

    btsl    $_EFER_NX, %eax
    /*
     * _EFER_NX = 11
     * NEX 사용 설정
     */

    btsq    $_PAGE_BIT_NX,early_pmd_flags(%rip)
    /*
     * early_pmd_flags의 EXB 설정
     * _PAGE_BIT_NX = 63
     *
     */
1:  wrmsr               /* Make changes effective */

 

    /* Setup cr0 */
#define CR0_STATE   (X86_CR0_PE | X86_CR0_MP | X86_CR0_ET |
             X86_CR0_NE | X86_CR0_WP | X86_CR0_AM |
             X86_CR0_PG)
    /* Make changes effective */
    movl    $CR0_STATE, %eax
    movq    %rax, %cr0
    /*
     * IA-32e 모드 페이징 활성화
     */

XE Login