- 论坛徽章:
- 0
|
/*内核模块加载函数*/
int __init kmalloc_map_init(void)
{
//申请设备号,添加cdev结构体
buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
for (page = virt_to_page(buffer); page < virt_to_page(buffer + BUFFER_SIZE); page++)
{
mem_map_reserve(page);//置页为保留,virt_to_page()将内核虚拟地址转化为页
}
}
/*mmap()函数*/
static int kmalloc_map_mmap(struct file *filp, struct vm_area_struct *vma)
{
unsigned long page, pos;
unsigned long start = (unsigned long)vma->vm_start;
unsigned long size = (unsigned long)(vma->vm_end - vma->vm_start);
if (size > BUFFER_SIZE)
{
return - EINVAL;
}
pos = (unsigned long)buffer;
/*映射buffer中的所有页*/
while (size > 0)
{
page = virt_to_phys((void *)pos);
if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
return - EAGAIN;
start += PAGE_SIZE;
pos += PAGE_SIZE;
size -= PAGE_SIZE;
}
/*
**可否用io_remap_pfn_range(vma, vma->vm_start, virt_to_phys((void *)buffer) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, PAGE_SHARED)来替代remap_page_range?
**在Linux kernel 2.6.27中,已经找不到remap_page_range的实现,见Linux kernel change log: Changes remap_page_range to remap_pfn_range for 2.6.10 and above kernels
*/
return 0;
} |
|