📄 kvmem.h
字号:
/* * Copyright (C) 1999 Tomasz Motylewski <motyl@stan.chemie.unibas.ch> * * The general driver layout borrowed from BIOS FLASH driver: * Copyright (C) 1998 Stefan Reinauer <stepan@freiburg.linux.de> * * routines for vmalloc'ed area remapping from bttv.c linux 2.1 driver. * * (EDITED IN MY SO CALLED "TYPING STYLE", + A FEW CHANGES (Paolo Mantegazza)) *//* convert virtual user memory address to physical address *//* (virt_to_phys only works for kmalloced kernel memory) */static inline unsigned long uvirt_to_phys(unsigned long adr){ pgd_t *pgd; pmd_t *pmd; pte_t pte; if (!pgd_none(*(pgd = pgd_offset(current->mm, adr)))) { if (!pmd_none(*(pmd = pmd_offset(pgd, adr)))) { if (pte_present((pte = *pte_offset(pmd, adr)))) { return virt_to_phys((void *)(pte_page(pte) | (adr & (PAGE_SIZE-1)))); } } } return 0;}static inline unsigned long uvirt_to_bus(unsigned long adr) { return virt_to_bus(phys_to_virt(uvirt_to_phys(adr)));}/* convert virtual kernel memory address to physical address *//* (virt_to_phys only works for kmalloced kernel memory) */static inline unsigned long kvirt_to_phys(unsigned long adr) { return uvirt_to_phys(VMALLOC_VMADDR(adr));}static inline unsigned long kvirt_to_bus(unsigned long adr) { return uvirt_to_bus(VMALLOC_VMADDR(adr));}/* allocate user space mmapable block of memory in the kernel space */static void *rvmalloc(unsigned long size){ void *vadr; unsigned long adr; if ((vadr = vmalloc(size))) { adr = (unsigned long)vadr; while (size > 0) { mem_map_reserve(MAP_NR(phys_to_virt(kvirt_to_phys(adr)))); adr += PAGE_SIZE; size -= PAGE_SIZE; } } return vadr;}/* freee user space mmapable block of memory in the kernel space */static void rvfree(void *vadr, unsigned long size){ unsigned long adr; if (vadr) { adr = (unsigned long)vadr; while (size > 0) { mem_map_unreserve(MAP_NR(phys_to_virt(kvirt_to_phys(adr)))); adr += PAGE_SIZE; size -= PAGE_SIZE; } vfree(vadr); }}/* this function will map rvmalloc'ed memory area to user space *//* it is not time critical code, so we check the arguments *//* vma->vm_offset HAS to be checked (and is checked) */static int rvmmap(void *vadr, unsigned size, struct vm_area_struct *vma) { unsigned long adr, start; adr = (unsigned long)vadr + vma->vm_offset; start = vma->vm_start; if (vma->vm_offset < 0 || (vma->vm_end - vma->vm_start) > size || adr%PAGE_SIZE || start%PAGE_SIZE || size%PAGE_SIZE) { return -EFAULT; } while (size > 0) { if (remap_page_range(start, kvirt_to_phys(adr), PAGE_SIZE, vma->vm_page_prot)) { return -EFAULT; } adr += PAGE_SIZE; start += PAGE_SIZE; size -= PAGE_SIZE; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -