페이지폴트 핸들러 코드 작성
1. 코드
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/rmap.h>
#include <linux/dev_printk.h>
#include <linux/list.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
#define MAX_NR_PAGES 10
static struct page* pages[MAX_NR_PAGES];
static vm_fault_t pfn_ctrl_fault(struct vm_fault *vmf)
{
struct page* page = NULL;
if(pages[vmf->pgoff] == NULL){
page = alloc_pages(GFP_KERNEL, 0);
pages[vmf->pgoff]=page;
}
vmf->page=pages[vmf->pgoff];
get_page(vmf->page);
pr_info("%lx %lx\n", vmf->address, page_to_pfn(vmf->page));
return 0;
}
static const struct vm_operations_struct pfn_ctrl_vm_ops = {
.fault = pfn_ctrl_fault,
};
static int pfn_ctrl_mmap(struct file *file, struct vm_area_struct *vma)
{
vma->vm_ops = &pfn_ctrl_vm_ops;
return 0;
}
static const struct file_operations pfn_ctrl_fops = {
.owner = THIS_MODULE,
.mmap = pfn_ctrl_mmap,
};
static struct miscdevice pfn_ctrl_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "pfn_ctrl",
.fops = &pfn_ctrl_fops,
};
static int __init pfn_ctrl_dev_init(void)
{
int err = 0;
err = misc_register(&pfn_ctrl_dev);
pr_info("Hello!\n");
return err;
}
static void __exit pfn_ctrl_dev_exit(void)
{
int i;
for(i=0;i<MAX_NR_PAGES; i++){
if(pages[i]!=NULL)
__free_pages(pages[i],0);
}
misc_deregister(&pfn_ctrl_dev);
pr_info("Good bye!\n");
}
module_init(pfn_ctrl_dev_init);
module_exit(pfn_ctrl_dev_exit);
MODULE_DESCRIPTION("Simple Page Fault Handling Device");
MODULE_LICENSE("GPL");
2. 실습 과정
1. 스켈레톤 코드 다운
다운로드
2. 빌드 및 실행
tar zxvf pfnctl.tgz && cd pfnctl
make
sudo insmod module/pfn_ctrl_dev.ko – $ sudo ./test_pfn
sudo rmmod pfn_ctrl_dev.ko
sudo dmesg
실패
