内核函数 __get_vm_area和free_vm_area

struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
                                unsigned long start, unsigned long end)

功能: 从start到end之间获得size字节大小的内核虚拟空间
size:分配字节的大小
flags:地址空间映射方式,会用来设置vm_struct->flags
返回值: vm结构体 用来描述内核的一个连续的虚拟空间
头文件:#include <linux/vmalloc.h>

void free_vm_area(struct vm_struct *area)
功能:释放一段vm_struct描述的虚拟地址
area:vm指针
头文件:#include <linux/vmalloc.h>

struct vm_struct {
    struct vm_struct    *next;        
//用于连接成链表
    void            *addr;                        //虚拟地址
    unsigned long        size;           //虚拟地址的大小
    unsigned long        flags;          //vm的标志 VM_IOREMAP VM_ALLOC VM_MAP
    
    struct page        **pages;          
//指向映射的页描述符数组
    unsigned int        nr_pages;      //映射的页的个数
    unsigned long        phys_addr;//用来映射硬件设备的IO共享内存,其他情况下为0
    void            *caller;                        //一般设置为__builtin_return_address(0)表示当前函数的返回地址                           
};

vm_struct用来描述内核的一个连续的虚拟空间,注意与struct vm_area_struct的区别
struct vm_area_struct也是一个连续的虚拟内存空间,不过是描述用户空间的
struct vm_struct表示的地址空间范围是(3G + 896M + 8M) ~ 4G
struct vm_area_struct表示的地址空间范围是0~3G    


#define VM_IOREMAP    0x00000001    /* 通过ioremap分配的页,将一个IO地址空间映射到内核的虚拟地址空间上去*/
#define VM_ALLOC    0x00000002        /* 通过vmalloc()分配的页在非直接映射区域分配的物理地址不是连续的*/
#define VM_MAP        0x00000004        /* 通过vmap()它将已经映射了的物理地址,
                                                                          又映射到了一些线性地址,所以对于这部分物理地址,
                                                                           现在有两个或两个以上的线性地址与其对应*/
#define VM_USERMAP    0x00000008    /*在用vmalloc_user(类似vmalloc)分配内核内存设置此标志,然后通过 
                                                                            remap_vmalloc_range将vmalloc_user分配的内存映射到用户空间*/
#define VM_VPAGES    0x00000010         /* 标志通过__vmalloc_node在非连续物理内存进行分配*/

例子如下:

猜你喜欢

转载自blog.csdn.net/yldfree/article/details/81143369