Pick a Free OS

User login

Navigation

For Kernel_Newbies By a Kernel_Newbie

page_present is not set.(pte_present) do_swap_page looks up a swap_cache and

gets in a page.It removes the page from the swap cache (swap_free),and does a

set_pte. A page contains some hints regarding its location in the swap. A swap

cache entry contains 6 bits to indicate Swap Type, (64 swap devices

supported),and 24 bits are retained for SWAP_OFFSET within the swap device.

Given a swap entry,you can lookup a swap cache by doing lookup_swap_cache, and

get the page.If its not present, there is a swapin_readahead which tries to

readahead aligned 1 << clusters,(I didnt get that.) before doing a

read_swapcache,to get a page. Some of the routines call handle_mm_fault to fault

in the page to tasks virtual address space. One such routine is map_user_kiobuf

which uses a kiobuf to force in the pages to user space. Try reading it,because

sometimes you might have to use kiobuf,for mapping vmalloced pages to

user_space,supposing you define your own page_fault_handler,do_no_page. If you

want to define your own page_fault_handler,for mapping kernel_memory allocated

using kmalloc or vmalloc to user_space,then you should be prepared to look up

the page tables.For kmalloc cases you can use remap_page_range,but be aware of

the fact that remap_page_range only works with page_reserved cases. It doesn

work if the page is not reserved.(check out remap_pte_range in memory.c). So you

are better off,faulting in 1 page at a time,in case of a page_fault exception. I

have some sample codes,but they are there in kernelnewbies.org, mapping a device

section. vmalloc case is not covered over there. For vmalloc cases,you have to

look up kernel Page tables for tracking the page. The reason being-Vmalloc

virtual_addresses are contiguous in space,but they are not physically

contiguous.vmalloc addresses lie after the end of Physical Memory.(8 MEM HOLE

before vmalloc starts). Hence you should go about tracing the pte_entry for

those virtual_addresses in the Kernels Page tables. You can do for example :

get_page : {

pgd_t *pgd; pmd_t *pmd; pte_t *pte;

struct page *page = NOPAGE_SIGBUS;

pgd = pgd_offset_k(address) ; //pgd_offset_k takes care of passing init_mm.

if(! pgd_none(*pgd) ) {

pmd = pmd_offset(pgd,address);

if(! pmd_none(*pmd) ) {

pte = pte_offset(pmd,address);

if(pte_present(*pte) ) {

page = pte_page(*pte); //get the page

}

}

}

return page;

}