- 论坛徽章:
- 0
|
回复 20# embeddedlwp
对于/dev/mem设备文件来说,这个offset的意义就是物理地址的偏移吧
drivers/char/mem.c, mem设备文件的fops:- static const struct file_operations mem_fops = {
- .llseek = memory_lseek,
- .read = read_mem,
- .write = write_mem,
- .mmap = mmap_mem,
- .open = open_mem,
- .get_unmapped_area = get_unmapped_area_mem,
- };
复制代码 其中mmap和read接口来完成的内存的访问:
- /*
- * This funcion reads the *physical* memory. The f_pos points directly to the
- * memory location.
- */
- static ssize_t read_mem(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
- {
- unsigned long p = *ppos;
- ssize_t read, sz;
- char *ptr;
- if (!valid_phys_addr_range(p, count))
- return -EFAULT;
- read = 0;
- #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
- /* we don't have page 0 mapped on sparc and m68k.. */
- if (p < PAGE_SIZE) {
- sz = size_inside_page(p, count);
- if (sz > 0) {
- if (clear_user(buf, sz))
- return -EFAULT;
- buf += sz;
- p += sz;
- count -= sz;
- read += sz;
- }
- }
- #endif
- while (count > 0) {
- unsigned long remaining;
- sz = size_inside_page(p, count);
- if (!range_is_allowed(p >> PAGE_SHIFT, count))
- return -EPERM;
- /*
- * On ia64 if a page has been mapped somewhere as uncached, then
- * it must also be accessed uncached by the kernel or data
- * corruption may occur.
- */
- ptr = xlate_dev_mem_ptr(p);
- if (!ptr)
- return -EFAULT;
- remaining = copy_to_user(buf, ptr, sz);
- unxlate_dev_mem_ptr(p, ptr);
- if (remaining)
- return -EFAULT;
- buf += sz;
- p += sz;
- count -= sz;
- read += sz;
- }
- *ppos += read;
- return read;
- }
复制代码 mmap实现:
- static int mmap_mem(struct file *file, struct vm_area_struct *vma)
- {
- size_t size = vma->vm_end - vma->vm_start;
- if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
- return -EINVAL;
- if (!private_mapping_ok(vma))
- return -ENOSYS;
- if (!range_is_allowed(vma->vm_pgoff, size))
- return -EPERM;
- if (!phys_mem_access_prot_allowed(file, vma->vm_pgoff, size,
- &vma->vm_page_prot))
- return -EINVAL;
- vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
- size,
- vma->vm_page_prot);
- vma->vm_ops = &mmap_mem_ops;
- /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
- if (remap_pfn_range(vma,
- vma->vm_start,
- vma->vm_pgoff,
- size,
- vma->vm_page_prot)) {
- return -EAGAIN;
- }
- return 0;
- }
复制代码 |
|