가상 메모리에서는 1G/3G이다.
물리메모리에서는 아키텍처 상, 1G까지는 직접 접근이 가능하다. 하지만 그 이후 메모리에서는 직접 접근이 불가능하다. 따라서 896 ~ 1024MB까지를 HighMem와 매핑시켜서 접근이 가능하도록 한다.
당연히, 직접접근이 가능한 쪽은 커널이 사용하겟지
kmap은 HighMem에 접근하기 위해 필요한 함수이다.
물리메모리에서는 아키텍처 상, 1G까지는 직접 접근이 가능하다. 하지만 그 이후 메모리에서는 직접 접근이 불가능하다. 따라서 896 ~ 1024MB까지를 HighMem와 매핑시켜서 접근이 가능하도록 한다.
당연히, 직접접근이 가능한 쪽은 커널이 사용하겟지
kmap은 HighMem에 접근하기 위해 필요한 함수이다.
21void *kmap(struct page *page) 22{ 23 might_sleep(); 24 if (!PageHighMem(page)) 25 return page_address(page); 26 return kmap_high(page); 27} 28EXPORT_SYMBOL(kmap); 29
void *page_address(const struct page *page) 341{ 342 unsigned long flags; 343 void *ret; 344 struct page_address_slot *pas; 345 346 if (!PageHighMem(page)) 347 return lowmem_page_address(page); 348 349 pas = page_slot(page); 350 ret = NULL; 351 spin_lock_irqsave(&pas->lock, flags); 352 if (!list_empty(&pas->lh)) { 353 struct page_address_map *pam; 354 355 list_for_each_entry(pam, &pas->lh, list) { 356 if (pam->page == page) { 357 ret = pam->virtual; 358 goto done; 359 } 360 } 361 } 362done: 363 spin_unlock_irqrestore(&pas->lock, flags); 364 return ret; 365} 366 367EXPORT_SYMBOL(page_address);
735static __always_inline void *lowmem_page_address(const struct page *page) 736{ 737 return __va(PFN_PHYS(page_to_pfn(page))); 738} 739
void *kmap_high(struct page *page) 207{ 208 unsigned long vaddr; 209 210 /* 211 * For highmem pages, we can't trust "virtual" until 212 * after we have the lock. 213 */ 214 lock_kmap(); 215 vaddr = (unsigned long)page_address(page); 216 if (!vaddr) 217 vaddr = map_new_virtual(page); 218 pkmap_count[PKMAP_NR(vaddr)]++; 219 BUG_ON(pkmap_count[PKMAP_NR(vaddr)] < 2); 220 unlock_kmap(); 221 return (void*) vaddr; 222} 223 224EXPORT_SYMBOL(kmap_high);
http://osinside.net/linuxMM/kmap_k.html
정리하면, kmap()은 struct page *를 인자로 받는데, 그것이 NORMAL 일수도 있고, High일수도 있다.
NORMAL이면 바로 해당 페이지가 있는지만 검사한 후 , 리턴받을 수 있다.
HIGHMEM 페이지의 경우, 부팅시간에 할당되었던 kmap 페이지 테이블에 쓰지 않은 entry가
있는지 검사한다. 이 검색은 간단하게 차례로 pkmap_count의 엔트리를 조사하며 0을
찾는다. 만약 없다면, 다른 프로세스가 페이지를 unmap할 때까지 sleep한다.
사용되지 않은 엔트리를 찾았다면, 매핑하고자 하는 그 페이지의 물리 주소를 삽입하고, pkmap_count
참조계수를 증가시킨다. 그리고 호출자에게 가상주소르르 반환한다.
또한 그 page 구조체가 매핑된 주소를 의미하도록 page->virtual를 갱신
'OS이야기' 카테고리의 다른 글
LRU/k (0) | 2012.01.03 |
---|---|
mm_struct, vm_area_struct (0) | 2012.01.03 |
bio (0) | 2012.01.03 |
프로세스의 .text, .data, .lib 구하기 (0) | 2012.01.02 |
proc (0) | 2011.12.31 |