/*
* 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 모드 페이징 활성화
*/
댓글 0
.