리눅스데브코스 [11주차 - 2]<리눅스 메모리 관리 기술(3) 실습>

심우열·2023년 6월 13일
0

페이지폴트 핸들러 코드 작성

1. 코드

/*
 * pfn_ctrl_dev.cpfn_ctrl_dev.c
 */

#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;
	/* Steps
	 * 1) identify the pgoff of this page fault 
	 * 2) allocate a new page if that pgoff has no allocated page
	 * 3) return the page through the vm_fault structure
	 * 4) return 0; // do NOT return VM_FAULT_SIGBUS
	 */
}

static const struct vm_operations_struct pfn_ctrl_vm_ops = {
	.fault = pfn_ctrl_fault,
};

/* mmap can map up to 10 pages */ 
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);
	}
	/* free pages that are used by this device */
	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

실패

profile
Dev Ops, "Git, Linux, Docker, Kubernetes, ansible, " .

0개의 댓글