본문 바로가기

project/Multicore 64bit OS Develop

[p.261] IA-32e 모드 4단계 페이징시 페이지 디렉토리 생성 코드 분석

64비트 페이지 디렉터리를 생성해야 하는데, 보호모드에서는 단일 레지스터로는 최대 32비트 값까지만 표현할 수 있기 때문에, 페이지 디렉터리가 맵핑하는 주소를 계산할 때, 상위 8바이트와 하위 8바이트를 나누어서 구조체로 주소를 표현하는 방법을 사용한다.


[예제코드 - 64GB까지 매핑하는 페이지 디렉터리를 생성하는 코드]

psdPDEntry = ( PDENTRY * ) 0x102000;

dwMappingAddress = 0;

for( i = 0 ; i < 512 * 64 ; i++ )

{

kSetPageEntryData( &( pstPDEntry[ i ] ), ( i * ( 0x200000 >> 20 ) ) >> 12,

dwMappingAddress, PAGE_FLAGS_DEFAULT | PAGE_FLAGS_PS, 0 );

dwMappingAddress += PAGE_DEFAULTSIZE;

}



빨간 줄이 그여있는 부분이 상위 8바이트 어드레스를 계산할때 쓰는 식인데, 

간단히 생각하자면 


i(현재 페이지 디렉터리 엔트리 번호) * 0x200000(PAGE_DEFAULTSIZE) / 2^32 이다.


페이지 크기를 2MB( 0x200000 ) 으로 설정 하였으므로, 페이지가 매핑하는 물리주소가 상위 8바이트를 사용할 경우는 0x100000000 / 0x200000 = 2048번째 entry 부터 상위 8바이트 주소를 사용하게 된다.


근데 지금 페이지 디렉토리를 생성하는 시점은 보호모드 이므로, 만약 파란색 줄처럼 상위주소를 계산한다면

 i * 0x200000  해당부분에서 2048번째 entry 부터 32비트를 넘어버리므로 오버플로가 발생한다. 이를 방지하기 위해

right shift 연산을 통해 먼저 값을 낮춘후 계산한다.  쉽게말해서 2^32으로 먼저 나누고 후에 곱한다고 생각하면 되는데, 처음부터 >> 32를 해버린다면 값이 0이 되어버리므로, >> 20  을 먼저 하고, 곱한 후에 나머지 >> 12를 하는 것이다.