linux 64bit 에서 page address 변환에 대해서
한눈에 보기 쉽게 그려보았습니다.
사용할때는 꼭 출처를 명시해 주기 바랍니다.
pde64_table = (pde64_t *)__va(BASE_TO_PAGE_ADDR(pdpe64_table->pd_base_addr) + (PDE64_INDEX(fault_addr)*sizeof(pde64_t))); if(!pde64_table->present) { uintptr_t tmp_pte64_table; tmp_pte64_table = (uintptr_t)petmem_smart_alloc_pages(map, (uintptr_t)NULL, (pte64_t *)NULL); memset((void *)__va(tmp_pte64_table), 0, PAGE_SIZE_4KB); pde64_table->present = 1; pde64_table->writable = 1; pde64_table->user_page = 1; pde64_table->pt_base_addr = PAGE_TO_BASE_ADDR(tmp_pte64_table); } pte64_table = (pte64_t *)__va(BASE_TO_PAGE_ADDR(pde64_table->pt_base_addr) + (PTE64_INDEX(fault_addr)*sizeof(pte64_t))); uintptr_t alloc_physical_memory; alloc_physical_memory = (uintptr_t)(petmem_smart_alloc_pages(map, fault_addr, pte64_table)); memset((void *)__va(alloc_physical_memory), 0, PAGE_SIZE_4KB); pte64_table->present = 1; pte64_table->writable = 1; pte64_table->user_page = 1; pte64_table->page_base_addr = PAGE_TO_BASE_ADDR_4KB(alloc_physical_memory); printk_debug("alloc physical addr : 0x%lx\n", (uintptr_t)(BASE_TO_PAGE_ADDR_4KB(pte64_table->page_base_addr) + PAGE_OFFSET_4KB(fault_addr)) ); // fault_addr == virtuall address
/* Gets the base address needed for a Page Table entry */ #define PAGE_TO_BASE_ADDR(x) ((x) >> 12) #define PAGE_TO_BASE_ADDR_4KB(x) ((x) >> 12) #define PAGE_TO_BASE_ADDR_2MB(x) ((x) >> 21) #define PAGE_TO_BASE_ADDR_4MB(x) ((x) >> 22) #define PAGE_TO_BASE_ADDR_1GB(x) ((x) >> 30) #define BASE_TO_PAGE_ADDR(x) (((uintptr_t)x) << 12) #define BASE_TO_PAGE_ADDR_4KB(x) (((uintptr_t)x) << 12) #define BASE_TO_PAGE_ADDR_2MB(x) (((uintptr_t)x) << 21) #define BASE_TO_PAGE_ADDR_4MB(x) (((uintptr_t)x) << 22) #define BASE_TO_PAGE_ADDR_1GB(x) (((uintptr_t)x) << 30) /* *** */ //#define PAGE_OFFSET(x) ((x) & 0xfff) #define PAGE_OFFSET_4KB(x) ((x) & 0xfff) #define PAGE_OFFSET_2MB(x) ((x) & 0x1fffff) #define PAGE_OFFSET_4MB(x) ((x) & 0x3fffff) #define PAGE_OFFSET_1GB(x) ((x) & 0x3fffffff) #define PAGE_POWER 12 #define PAGE_POWER_4KB 12 #define PAGE_POWER_2MB 21 #define PAGE_POWER_4MB 22 #define PAGE_POWER_1GB 30 // We shift instead of mask because we don't know the address size #define PAGE_ADDR(x) (((x) >> PAGE_POWER) << PAGE_POWER) #define PAGE_ADDR_4KB(x) (((x) >> PAGE_POWER_4KB) << PAGE_POWER_4KB) #define PAGE_ADDR_2MB(x) (((x) >> PAGE_POWER_2MB) << PAGE_POWER_2MB) #define PAGE_ADDR_4MB(x) (((x) >> PAGE_POWER_4MB) << PAGE_POWER_4MB) #define PAGE_ADDR_1GB(x) (((x) >> PAGE_POWER_1GB) << PAGE_POWER_1GB)
virtual-memory-example-source-code.tar.bz2
'Programming > Linux_Kernel' 카테고리의 다른 글
sleep and delay in linux kernel (0) | 2015.03.22 |
---|---|
uevent 사용하기 (0) | 2015.03.21 |
File System의 개요 (0) | 2014.05.12 |
mmap 을 이용한 process memory mapping (0) | 2014.04.25 |
linux 에서 page cache(페이지 캐쉬)란? (0) | 2014.04.24 |