인자로 넘어온 struct map_desc *md 에 해당하는 영역에 대한 페이지 테이블 맵핑 작업을 한다.
while (length >= (PGDIR_SIZE / 2)) {
alloc_init_section(virt, virt + off, prot_sect);
virt += (PGDIR_SIZE / 2); // + 0x100000
length -= (PGDIR_SIZE / 2);
}
while (length >= PAGE_SIZE) {
alloc_init_page(virt, virt + off, prot_l1,prot_pte);
virt += PAGE_SIZE;
length -= PAGE_SIZE;
}
length 를 0x100000 감소 시키고, virt 는 0x100000 를 증가 시키며, alloc_init_section 를 호출해서 section 에 대한 맵핑을 한다.
length 가 0x100000 보다 작게 남는 경우엔, alloc_init_page 를 호출해서 1차 페이지 디스크립터 와 2차 페이지 디스크립터를 생성한다.
[ alloc_init_section ] arch/arm/mm/mmu.c
pmd_off_k 는 주어진 virtual address 의 page directory index ( 2048 엔트리중에서 )
그리고, virtual address가 C01*4, C03*4 와 같이 홀수 이면, pmdp두번째 맴버에 값을 저장하도록 한다.
flush_pmd_entry 를 호출한다.
clear_pmd_entry, flush_pmd_entry 의 차이
[ alloc_init_page ] arch/arm/mm/mmu.c
pmd_off_k 는 주어진 virtual address 의 page directory index ( 2048 엔트리중에서 )
*pmdp값이 비어 있는지 확인한다. 비어 있으면, 아직 pte 를 만들지 않았다
만들지 않았다면, alloc_bootmem_low_pages 로 부터 4K 를 할당 받는다.
할당 받은 address 는 ptep 에 저장되고, 이 주소는 pmdp[0], 1024 만큼 더한 주소는 pmdp[1]에 각각 저장된다.
pgd pte
| |
+--------+ +0
| |--------> +------------+ +0
+--------+ +4 | h/w pt 0 |
| |--------> +------------+ +1024
+--------+ +8 | h/w pt 1 |
| | +------------+ +2048
+--------+ | Linux pt 0 |
| | +------------+ +3072
+--------+ | Linux pt 1 |
| | +------------+ +4096
pmd_page_vaddr 는 *pmdp 로 주어진 address 를 2048 만큼 더한다. 속성은 mask 로 다 날린다.
__pte_index 는 512 앤트리에 대한 인덱스이다.
pte_offset_kernel 은 커널 pte의 주소를 반환하고, set_pte_ext 를 호출하여, 커널 pte 를 저장하고, 2048만큼 뺀 곳에 h.w pte 를 저장한다.
'리눅스커널' 카테고리의 다른 글
[ devicemaps_init ] arch/arm/mm/mmu.c (0) | 2009.10.02 |
---|---|
[ bootmem_bootmap_pages ] mm/bootmem.c (0) | 2009.10.02 |
[ bootmem_init_node ] arch/arm/mm/init.c (0) | 2009.10.02 |
[ 부트 메모리 allocator ] (0) | 2009.10.02 |
[ prepare_page_table ] arch/arm/mm/mmu.c (0) | 2009.10.02 |