저는 리눅스 커널 아키텍처를 전문적으로 배우고 있고, 3장 메모리 관리를 공부하고 있습니다. 제가 연구할 당시에는 커널 주소 공간 자체가 직접 매핑 영역, vmalloc 영역, kmap 영역, 고정 매핑 영역으로 나누어져 있었습니다.
제가 알고 싶은 내용은 아래와 같습니다.
__va, __pa 및 기타 기능을 통해 MMU 없이 32비트 머신 커널 주소 공간의 직접 매핑 영역(896MB)에 액세스할 수 있습니까?
1.이 true이면 기본 커널 페이지 테이블(swapper_pg_dir)은 128MB만 관리합니까?
커널 코드를 살펴보니 32비트와 64비트의 paging_init 함수에 차이가 있는 것을 발견했습니다. 32비트에서는 pagetable_init 함수가 커널 페이지 테이블을 초기화하고 마스터하는 것으로 나타났습니다.페이징 초기화기능.
32비트 paging_init 함수
void __init pageit_init(void){
pagetable_init();
__flush_tlb_all();
kmap_init();
olpc_dt_build_devicetree();
sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init();
zone_sizes_init();
}
그런데 64비트에서는 커널 페이지 테이블 관련 함수를 찾을 수 없습니다.페이징 초기화기능.
void __init paging_init(void)
{
sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init();
node_clear_state(0, N_MEMORY);
if (N_MEMORY != N_NORMAL_MEMORY)
node_clear_state(0, N_NORMAL_MEMORY);
zone_sizes_init();
}
64비트 커널에는 기본 커널 페이지 테이블이 없나요? 사실이라면 직접 매핑을 통해 커널 메모리에 액세스합니까?
답변1
질문 1과 2에 대한 답변: 아니요. 페이징이 활성화되면 CPU 명령은 가상 주소만 사용하며, RAM을 읽거나 쓰기 전에 MMU를 사용하여 가상 주소를 실제 주소로 변환합니다. __va
매크로는 __pa
메모리에 액세스하지 않고 주소 공간 간의 주소를 변환할 뿐입니다. 32비트 시스템에서는 물리적 주소가 가상 주소에 있도록 매핑이 이미 설정되어 있으므로 인수로 제공된 물리적 주소를 __va
추가하기만 하면 됩니다 .0xc0000000
N
N+0xc0000000
CPU가 액세스하려는 주소는 매핑되어야 하며 MMU를 우회할 수 없습니다. 따라서 128MB 지도를 관리하는 것만으로는 충분하지 않습니다.