精华内容
下载资源
问答
  • vmalloc =>__vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);//丫的竟然用高端内存???? =>__vmalloc_node(size, gfp_mask, prot, -1); =>area = get_vm_area_node(size, VM_...

    vmalloc的两个数据结构也就是vm_struct和pages依赖于slab系统,pages指向的page依赖于buddy系统,另外修改页表重新映射依赖于maping

    vmalloc
        =>__vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);//丫的竟然用高端内存????,是的,在最高的128M
            =>__vmalloc_node(size, gfp_mask, prot, -1);
    	        =>size = PAGE_ALIGN(size); //size大小页对齐
                =>area = get_vm_area_node(size, VM_ALLOC, node, gfp_mask);//struct vm_struct *area;
                    =>return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, node, gfp_mask);//VMALLOC_START和VMALLOC_END分别是vmalloc的起始和终止区域
                        =>area = kmalloc_node(sizeof(*area), gfp_mask & GFP_LEVEL_MASK, node);//vm_struct依赖于kmalloc,也就是slab系统
    	                    =>return kmalloc(size, flags);
    		                    =>return kmem_cache_alloc(malloc_sizes[i].cs_cachep, flags);//进入slab领域
    		            =>size += PAGE_SIZE; //We always allocate a guard page. 申请的时候加个栅栏
                        =>for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) { //在vmlist链表里面找到area合适的位置,把新分配的area插入到里面
                            if ((unsigned long)tmp->addr < addr) {
                                if((unsigned long)tmp->addr + tmp->size >= addr)
                                    addr = ALIGN(tmp->size + 
                                             (unsigned long)tmp->addr, align);
                                continue;
                            }
                            if ((size + addr) < addr)
                                goto out;
                            if (size + addr <= (unsigned long)tmp->addr)
                                goto found;
                            addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
                            if (addr > end - size)
                                goto out;
                        }
                        =>
                      found: //一旦找到合适的地方就初始化
                        area->next = *p;  //这两句话是将area加入到vm_struct链表中
                        *p = area;
    
                        area->flags = flags;
                        area->addr = (void *)addr;//addr作为内容,area作为载体
                        area->size = size;
                        area->pages = NULL;
                        area->nr_pages = 0;
                        area->phys_addr = 0;
                =>return __vmalloc_area_node(area, gfp_mask, prot, node);
    	            =>nr_pages = (area->size - PAGE_SIZE) >> PAGE_SHIFT; //真正申请的时候取消栅栏,递归的时候也做递减的作用
    				array_size = (nr_pages * sizeof(struct page *));
    				area->nr_pages = nr_pages;
    				=>if (array_size > PAGE_SIZE) {//为pages分配空间,如果pages正常占用的字节有限,但是如果超过一个页框大小,也就是4KB,需要递归调用,关于pages的详细描述详见“参考”里面的第一章节最后一张图片,很形象
    					pages = __vmalloc_node(array_size, gfp_mask | __GFP_ZERO,
    								PAGE_KERNEL, node);//页面大小超过1个页
    					area->flags |= VM_VPAGES;
    				} else {//
    					pages = kmalloc_node(array_size,
    							(gfp_mask & GFP_LEVEL_MASK) | __GFP_ZERO,
    							node);//页面大小没有超过1个页,递归递减1个页框,最终会调用的这个地方
    				}
    				area->pages = pages;
    				=>for (i = 0; i < area->nr_pages; i++) { 好多页面物理不连续,但是虚拟地址连续
    					if (node < 0)
    						area->pages[i] = alloc_page(gfp_mask);
    					else
    						area->pages[i] = alloc_pages_node(node, gfp_mask, 0);
    					if (unlikely(!area->pages[i])) {
    						/* Successfully allocated i pages, free them in __vunmap() */
    						area->nr_pages = i;
    						goto fail;
    					}
    				}
    				=>if (map_vm_area(area, prot, &pages))//页表映射修改
    				=>return area->addr;
    
    void vfree(const void *addr)
    	__vunmap(addr, 1);
    		=>void __vunmap(const void *addr, int deallocate_pages)
    			area = remove_vm_area(addr);
    				=>struct vm_struct *remove_vm_area(const void *addr)
    					va = find_vmap_area((unsigned long)addr);
    					free_unmap_vmap_area(va);
    			for (i = 0; i < area->nr_pages; i++) {
    				struct page *page = area->pages[i];
    				__free_page(page);
    			}
    			kfree(area);
    

    参考
    高端内存映射之vmalloc分配内存中不连续的页–Linux内存管理(十九)
    http://blog.csdn.net/gatieme/article/details/52705111

    启动过程内存check和vmalloc大小设置
    https://blog.csdn.net/sunlei0625/article/details/50465713

    内核中的内存申请:kmalloc、vmalloc、kzalloc、kcalloc、get_free_pages
    https://www.cnblogs.com/eleclsc/p/11531589.html

    展开全文
  • linux vmalloc 和 其友

    2019-07-06 11:26:00
    我们展示给你的下一个内存分配函数是 vmlloc, 它在虚拟内存空间分配一块连续的... vmalloc 返回 0 ( NULL 地址 ) 如果发 生一个错误, 否则, 它返回一个指向一个大小至少为 size 的连续内存区. 我们这里描述 vma...

    我们展示给你的下一个内存分配函数是 vmlloc, 它在虚拟内存空间分配一块连续的内存 区. 尽管这些页在物理内存中不连续 (使用一个单独的对 alloc_page 的调用来获得每个 页), 内核看它们作为一个一个连续的地址范围. vmalloc 返回 0 ( NULL 地址 ) 如果发 生一个错误, 否则, 它返回一个指向一个大小至少为 size 的连续内存区.

     

    我们这里描述 vmalloc 因为它是一个基本的 Linux 内存分配机制. 我们应当注意, 但是, vmalloc 的使用在大部分情况下不鼓励. 从 vmalloc 获得的内存用起来稍微低效些, 并 且, 在某些体系上, 留给 vmalloc 的地址空间的数量相对小. 使用 vmalloc 的代码如果 被提交来包含到内核中可能会受到冷遇. 如果可能, 你应当直接使用单个页而不是试图使 用 vmalloc 来掩饰事情.

     

    让我们看看 vmalloc 如何工作的. 这个函数的原型和它相关的东西(ioremap, 严格地不 是一个分配函数, 在本节后面讨论)是下列:

     

    #include <linux/vmalloc.h>

    void *vmalloc(unsigned long size); void vfree(void * addr);

    void *ioremap(unsigned long offset, unsigned long size);

    void iounmap(void * addr);

     

    NUMA (非统一内存存取) 计算机是多处理器系统, 这里内存对于特定的处理器组("节点")是"局部的". 对局部内

    存的存取比存取非局部内存更快. 在这样的系统, 在当前节点分配内存是重要的. 驱动作者通常不必担心 NUMA 问题, 但是.

     

     

    值得强调的是 kmalloc 和 _get_free_pages 返回的内存地址也是虚拟地址. 它们的实际 值在它用在寻址物理地址前仍然由 MMU (内存管理单元, 常常是 CPU 的一部分)管理.[31]31 vmalloc 在它如何使用硬件上没有不同, 不同是在内核如何进行分配任务上.

     

    kmalloc 和 get_free_pages 使用的(虚拟)地址范围特有一个一对一映射到物理内存, 可能移位一个常量 PAGE_OFFSET 值; 这些函数不需要给这个地址范围修改页表. vmalloc 和 ioremap 使用的地址范围, 另一方面, 是完全地合成的, 并且每个分配建立(虚拟)内 存区域, 通过适当地设置页表.

     

    这个区别可以通过比较分配函数返回的指针来获知. 在一些平台(例如, x86), vmalloc 返回的地址只是远离 kmalloc 使用的地址. 在其他平台上(例如, MIPS, IA-64, 以及 x86_64 ), 它们属于一个完全不同的地址范围. 对 vmalloc 可用的地址在从 VMALLOC_START 到 VAMLLOC_END 的范围中. 2 个符号都定义在 <asm/patable.h> 中.

     

    vmalloc 分配的地址不能用于微处理器之外, 因为它们只在处理器的 MMU 之上才有意义. 当一个驱动需要一个真正的物理地址(例如一个 DMA 地址, 被外设硬件用来驱动系统的总 线), 你无法轻易使用 vmalloc. 调用 vmalloc 的正确时机是当你在为一个大的只存在于 软件中的顺序缓冲分配内存时. 重要的是注意 vamlloc 比  get_free_pages 有更多开 销, 因为它必须获取内存并且建立页表. 因此, 调用 vmalloc 来分配仅仅一页是无意义 的.

     

    在内核中使用 vmalloc 的一个例子函数是 create_module 系统调用, 它使用 vmalloc 为在创建的模块获得空间. 模块的代码和数据之后被拷贝到分配的空间中, 使用 copy_from_user. 在这个方式中, 模块看来是加载到连续的内存. 你可以验证, 同过看

    /proc/kallsyms, 模块输出的内核符号位于一个不同于内核自身输出的符号的内存范围.

     

    使用 vmalloc 分配的内存由 vfree 释放, 采用和 kfree 释放由 kmalloc 分配的内存的 相同方式.

     

    如同 vmalloc, ioremap 建立新页表; 不同于 vmalloc, 但是, 它实际上不分配任何内存. ioremap 的返回值是一个特殊的虚拟地址可用来存取特定的物理地址范围; 获得的虚拟地 址应当最终通过调用 iounmap 来释放.

     

    ioremap 对于映射一个 PCI 缓冲的(物理)地址到(虚拟)内核空间是非常有用的. 例如, 它可用来存取一个 PCI 视频设备的帧缓冲; 这样的缓冲常常被映射在高端物理地址, 在 内核启动时建立的页表的地址范围之外. PCI 问题在 12 章有详细解释.

     

    由于可移植性, 值得注意的是你不应当直接存取由 ioremap 返回的地址好像是内存指针. 你应当一直使用 readb 和 其他的在第 9 章介绍的 I/O 函数. 这个要求适用因为一些平 台, 例如 Alpha, 无法直接映射 PCI 内存区到处理器地址空间, 由于在 PCI 规格和 Alpha 处理器之间的在数据如何传送方面的不同.

     

    实际上, 一些体系结构定义"虚拟"地址为保留给寻址物理内存. 当这个发生了, Linux 内核利用这个特性, 并且

    kernel 和 get_free_pages 地址都位于这些地址范围中的一个. 这个区别对设备驱动和其他的不直接包含到内存管理 内核子系统中的代码是透明的.

     

    ioremap 和 vmalloc 是面向页的(它通过修改页表来工作); 结果, 重分配的或者分配的 大小被调整到最近的页边界. ioremap 模拟一个非对齐的映射通过"向下调整"被重映射的 地址以及通过返回第一个被重映射页内的偏移.

     

    vmalloc 的一个小的缺点在于它无法在原子上下文中使用, 因为, 内部地, 它使用 kmalloc(GFP_KERNEL) 来获取页表的存储, 并且因此可能睡眠. 这不应当是一个问题 -- 如果   get_free_page 的使用对于一个中断处理不足够好, 软件设计需要一些清理.

    转载于:https://www.cnblogs.com/fanweisheng/p/11142129.html

    展开全文
  • Linux内核空间内存申请函数kmalloc、kzalloc、vmalloc的区别》 《内核中的内存申请:kmalloc、vmalloc、kzalloc、kcalloc、get_free_pages》 kmalloc()申请的内存位于物理内存映射区域,而且在物理上也是连续的,...

    vmalloc原理与实现

    Linux内核空间内存申请函数kmalloc、kzalloc、vmalloc的区别

    内核中的内存申请:kmalloc、vmalloc、kzalloc、kcalloc、get_free_pages

    • kmalloc() 申请的内存位于物理内存映射区域,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因为存在较简单的转换关系,所以对申请的内存大小有限制,不能超过128KB。 
    • vmalloc() 函数则会在虚拟内存空间给出一块连续的内存区,但这片连续的虚拟内存在物理内存中并不一定连续。由于 vmalloc() 没有保证申请到的是连续的物理内存,因此对申请的内存大小没有限制,如果需要申请较大的内存空间就需要用此函数了。由于直接内存映射区(3GB ~ 3GB+896MB)是直接映射到物理地址(0 ~ 896MB)的,所以内核不能通过直接内存映射区使用到超过 896MB 之外的物理内存。这时候就需要提供一个机制能够让内核使用 896MB 之外的物理内存,所以 Linux 就实现了一个 vmalloc 机制。

    Table of Contents

    为什么需要vmalloc区

    vmalloc实现


     

    在 Linux 系统中的每个进程都有独立 4GB 内存空间,而 Linux 把这 4GB 内存空间划分为用户内存空间(0 ~ 3GB)和内核内存空间(3GB ~ 4GB),而内核内存空间由划分为直接内存映射区和动态内存映射区(vmalloc区)。

    直接内存映射区从 3GB 开始到 3GB+896MB 处结束,直接内存映射区的特点就是物理地址与虚拟地址的关系为:

    虚拟地址 = 物理地址 + 3GB

    而动态内存映射区不能通过这种简单的关系关联,而是需要访问动态内存映射区时,由内核动态申请物理内存并且映射到动态内存映射区中。下图是动态内存映射区在内存空间的位置:

    为什么需要vmalloc区

    由于直接内存映射区(3GB ~ 3GB+896MB)是直接映射到物理地址(0 ~ 896MB)的,所以内核不能通过直接内存映射区使用到超过 896MB 之外的物理内存。这时候就需要提供一个机制能够让内核使用 896MB 之外的物理内存,所以 Linux 就实现了一个 vmalloc 机制。vmalloc 机制的目的是在内核内存空间提供一个内存区,能够让这个内存区映射到 896MB 之外的物理内存。如下图:

    那么什么时候使用 vmalloc 呢?一般来说,如果要申请大块的内存就可以用vmalloc。

    vmalloc实现

    可以通过 vmalloc() 函数向内核申请一块内存,其原型如下:

    void * vmalloc(unsigned long size);

    参数 size 表示要申请的内存块大小。

    我们看看看 vmalloc() 函数的实现,代码如下:

    static inline void * vmalloc(unsigned long size)
    {
        return __vmalloc(size, GFP_KERNEL|__GFP_HIGHMEM, PAGE_KERNEL);
    }

    从上面代码可以看出,vmalloc() 函数直接调用了 __vmalloc() 函数,而 __vmalloc() 函数的实现如下:

    void * __vmalloc(unsigned long size, int gfp_mask, pgprot_t prot)
    {
        void * addr;
        struct vm_struct *area;
    
        size = PAGE_ALIGN(size); // 内存对齐
        if (!size || (size >> PAGE_SHIFT) > num_physpages) {
            BUG();
            return NULL;
        }
    
        area = get_vm_area(size, VM_ALLOC); // 申请一个合法的虚拟地址
        if (!area)
            return NULL;
    
        addr = area->addr;
        // 映射物理内存地址
        if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size, gfp_mask, prot)) {
            vfree(addr);
            return NULL;
        }
    
        return addr;
    }

    __vmalloc() 函数主要工作有两点:

    • 调用 get_vm_area() 函数申请一个合法的虚拟内存地址。
    • 调用 vmalloc_area_pages() 函数把虚拟内存地址映射到物理内存地址。

    接下来,我们看看 get_vm_area() 函数的实现,代码如下:

    struct vm_struct * get_vm_area(unsigned long size, unsigned long flags)
    {
        unsigned long addr;
        struct vm_struct **p, *tmp, *area;
    
        area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
        if (!area)
            return NULL;
        size += PAGE_SIZE;
        addr = VMALLOC_START;
        write_lock(&vmlist_lock);
        for (p = &vmlist; (tmp = *p) ; p = &tmp->next) {
            if ((size + addr) < addr)
                goto out;
            if (size + addr <= (unsigned long) tmp->addr)
                break;
            addr = tmp->size + (unsigned long) tmp->addr;
            if (addr > VMALLOC_END-size)
                goto out;
        }
        area->flags = flags;
        area->addr = (void *)addr;
        area->size = size;
        area->next = *p;
        *p = area;
        write_unlock(&vmlist_lock);
        return area;
    
    out:
        write_unlock(&vmlist_lock);
        kfree(area);
        return NULL;
    }

    get_vm_area() 函数比较简单,首先申请一个类型为 vm_struct 的结构 area 用于保存申请到的虚拟内存地址。然后查找可用的虚拟内存地址,如果找到,就把虚拟内存到虚拟内存地址保存到 area 变量中。最后把 area 连接到 vmalloc 虚拟内存地址管理链表 vmlist 中。vmlist 链表最终结果如下图:

    申请到虚拟内存地址后,__vmalloc() 函数会调用 vmalloc_area_pages() 函数来对虚拟内存地址与物理内存地址进行映射。

    我们知道,映射过程就是对进程的 页表 进行映射。但每个进程都有一个独立 页表(内核线程除外),并且我们知道内核空间是所有进程共享的,那么就有个问题:如果只映射当前进程 页表 的内核空间,那么怎么同步到其他进程的内核空间呢?

    为了解决内核空间同步问题,Linux 并不是直接对当前进程的内核空间映射的,而是对 init 进程的内核空间(init_mm)进行映射,我们来看看 vmalloc_area_pages() 函数的实现:

    inline int vmalloc_area_pages (unsigned long address, unsigned long size,
                                   int gfp_mask, pgprot_t prot)
    {
        pgd_t * dir;
        unsigned long end = address + size;
        int ret;
    
        dir = pgd_offset_k(address);         // 获取 address 地址在 init 进程对应的页目录项
        spin_lock(&init_mm.page_table_lock); // 对 init_mm 上锁
        do {
            pmd_t *pmd;
    
            pmd = pmd_alloc(&init_mm, dir, address);
            ret = -ENOMEM;
            if (!pmd)
                break;
    
            ret = -ENOMEM;
            if (alloc_area_pmd(pmd, address, end - address, gfp_mask, prot)) // 对页目录项进行映射
                break;
    
            address = (address + PGDIR_SIZE) & PGDIR_MASK;
            dir++;
    
            ret = 0;
        } while (address && (address < end));
        spin_unlock(&init_mm.page_table_lock);
        return ret;
    }

    从上面代码可以看出,vmalloc_area_pages() 函数映射的主体是 init 进程的内存空间。因为映射的 init 进程的内存空间,所以当前进程访问 vmalloc() 函数申请的内存时,由于没有对虚拟内存进行映射,所以会发生 缺页异常 而触发内核调用 do_page_fault() 函数来修复。我们看看 do_page_fault() 函数对 vmalloc() 申请的内存异常处理:

    void do_page_fault(struct pt_regs *regs, unsigned long error_code)
    {
        ...
        __asm__("movl %%cr2,%0":"=r" (address));  // 获取出错的虚拟地址
        ...
    
        if (address >= TASK_SIZE && !(error_code & 5))
            goto vmalloc_fault;
    
        ...
    
    vmalloc_fault:
        {
            int offset = __pgd_offset(address);
            pgd_t *pgd, *pgd_k;
            pmd_t *pmd, *pmd_k;
            pte_t *pte_k;
    
            asm("movl %%cr3,%0":"=r" (pgd));
            pgd = offset + (pgd_t *)__va(pgd);
            pgd_k = init_mm.pgd + offset;
    
            if (!pgd_present(*pgd_k))
                goto no_context;
            set_pgd(pgd, *pgd_k);
    
            pmd = pmd_offset(pgd, address);
            pmd_k = pmd_offset(pgd_k, address);
            if (!pmd_present(*pmd_k))
                goto no_context;
            set_pmd(pmd, *pmd_k);
    
            pte_k = pte_offset(pmd_k, address);
            if (!pte_present(*pte_k))
                goto no_context;
            return;
        }
    }

    上面的代码就是当进程访问 vmalloc() 函数申请到的内存时,发生 缺页异常 而进行的异常修复,主要的修复过程就是把 init 进程的 页表项 复制到当前进程的 页表项 中,这样就可以实现所有进程的内核内存地址空间同步。

     

    Linux内核空间内存申请函数kmalloc、kzalloc、vmalloc的区别

    展开全文
  • Linux 内存管理之vmalloc

    2021-05-14 00:10:24
    走进vmalloc 根据前面的系列文章,我们知道了buddy system是基于页框分配器,kmalloc是基于slab分配器,而且这些分配的地址都是物理内存连续的。但是随着碎片化的积累,...

    走进vmalloc

    根据前面的系列文章,我们知道了buddy system是基于页框分配器,kmalloc是基于slab分配器,而且这些分配的地址都是物理内存连续的。但是随着碎片化的积累,连续物理内存的分配就会变得困难,对于那些非DMA访问,不一定非要连续物理内存的话完全可以像malloc那样,将不连续的物理内存页框映射到连续的虚拟地址空间中,这就是vmap的来源)(提供把离散的page映射到连续的虚拟地址空间),vmalloc的分配就是基于这个机制来实现的。

    vmalloc最小分配一个page,并且分配到的页面不保证是连续的,因为vmalloc内部调用alloc_page多次分配单个页面。

    vmalloc的区域就是在上图中VMALLOC_START - VMALLOC_END之间,可通过/proc/vmallocinfo查看。

    数据结构

    • vmap_area 描述一段虚拟地址的区域,可以将struct vm_struct构成一个链表,维护多段映射。

    struct vmap_area {
     unsigned long va_start; //vmalloc申请虚拟地址返回的起始地址
     unsigned long va_end; //vmalloc申请申请虚拟地址返回的结束地址
     unsigned long flags;
      //挂接到vmap_area_root红黑树
     struct rb_node rb_node;         /* address sorted rbtree */
      //挂接到vmap_area_list链表
     struct list_head list;          /* address sorted list */
     struct llist_node purge_list;    /* "lazy purge" list */
     //如果当前VA处于使用状态(即在vmap_area_root为根的红黑树中和vmap_area_list链表中),vm有效,指向用于管理虚拟地址和物理页之间的映射关系的描述符
     struct vm_struct *vm;
     struct rcu_head rcu_head;
    };
    
    • vm_struct 管理虚拟地址和物理页之间的映射关系

    struct vm_struct {
     struct vm_struct *next; //指向下一个vm结构体
     void   *addr; //当前vmalloc区域的虚拟地址的起始地址
     unsigned long  size; //当前vmalloc区域的虚拟地址的大小
     unsigned long  flags;
     //vamlloc分配获取的各个物理页面并是不连续的,每个物理页面用struct page描述,一个vm_struct对用到的管理所有物理页面的struct page构成一个数组,而pages就是指向这个数组的指针。
     struct page  **pages;
     unsigned int  nr_pages; //vmalloc映射的page数目
     phys_addr_t  phys_addr; //用来映射硬件设备的IO共享内存,其他情况下为0
     const void  *caller; //调用vmalloc函数的函数的地址
    };
    

    vmalloc

    主要分以下三步:

    1. 从VMALLOC_START到VMALLOC_END查找空闲的虚拟地址空间(hole)

    2. 根据分配的size,调用alloc_page依次分配单个页面.

    3. 把分配的单个页面,映射到第一步中找到的连续的虚拟地址。把分配的单个页面,映射到第一步中找到的连续的虚拟地址。


    推荐阅读:

    专辑|Linux文章汇总

    专辑|程序人生

    专辑|C语言

    我的知识小密圈

    关注公众号,后台回复「1024」获取学习资料网盘链接。

    欢迎点赞,关注,转发,在看,您的每一次鼓励,我都将铭记于心~

    展开全文
  • linux内存管理之vmalloc

    2015-10-02 01:04:09
    linux内存管理之vmalloc  http://blog.chinaunix.net/uid-20786208-id-4888173.html  在前面我们讲解了kmalloc申请连续物理内存的操作,以及原理和基础cache . 在内核中还有另外一个接口函数那...
  • Linux内存管理 (6)vmalloc

    2019-03-21 11:07:11
    专题:Linux内存管理专题 关键词:vmalloc、页对齐、虚拟地址连续、物理不连续 至此,已经介绍了集中内核中内存分配函数,在开始简单做个对比总结Linux中常用内存分配...vmalloc的核心是在vmalloc区域中找到合适...
  • Linux内存管理:Vmalloc

    千次阅读 2015-09-24 11:18:29
    原文出处: linuxDOS 欢迎分享原创到伯乐头条 在前面我们讲解了kmalloc申请连续物理内存的操作,以及原理和基础cache . 在内核中还有另外一个接口函数那就是vmalloc,申请一片连续的虚拟地址空间,但不保证...
  • vmalloc最小分配一个page.并且分配到的页面不保证是连续的.因为vmalloc内部调用alloc_page多次分配单个页面. vmalloc主要内容: 1. 从VMALLOC_START到VMALLOC_END查找空闲的虚拟地址空间(hole) 2.根据分配的size...
  • 一:vmalloc http://www.360doc.com/content/14/0614/13/18127083_386524093.shtml 1,vmalloc()的内核入口函数是kernel/mm/Vmalloc.c里的void *vmalloc(unsigned long size),size表示的是请求内核分配的字节数目。...
  • linux内存管理--vmalloc

    千次阅读 2016-04-27 22:29:10
    * vmalloc - allocate virtually contiguous memory * @size: allocation size * Allocate enough pages to cover @size from the page level * allocator and map them into contiguous kernel
  • 三个内存区域zone,分别为ZONE_DMA,ZONE_NORMAL和ZONE_HIGHMEM,在e500上ZONE_NORMAL实际划分的内存为空,所以所有低端内存(low_memory)都划分到ZONE_DMA中; 内存区域的划分信息保存在max_zone_pfns中,其定义...
  • 位置:vmalloc区位是一段虚拟地址空间,位于内核地址空间,介于低端内存映射区和持久映射区之间,虚拟地址范围从VMALLOC_START至VMALLOC_END,如下图土黄色部分:   功能:调用vmalloc函数时,会从该VMALLOC区申请...
  • Linux内存管理之vmalloc和kmalloc

    千次阅读 2017-04-10 21:30:24
    了解linux操作系统的,我们都知道内存管理对于linux操作系统的重要性,当然其他操作系统内存管理也占有举足轻重的角色。 在内核里分配内存可不像在其他地方分配内存那么容易。造成这种局面的因素有很多,从根本上讲...
  • 动态内存映射区:该区域由内核函数vmalloc来分配,特点是:线性空间连续,但是对应的物理空间不一定连续。vmalloc分配的线性地址所对应的物理页可能处于低端内存,也可能处于高端内存。 永久内存映射区:该区域可...
  • Vmalloc可以获得的地址在VMALLOC_START到VMALLOC_END的范围中。这两个符号在中定义: /* include/asm/pgtable.h */ #define VMALLOC_OFFSET (8*1024*1024) #define VMALLOC_START (((unsigned long)high_me
  • 我们都知道在用户空间动态申请内存用的函数是 malloc(),这个函数在各种操作系统上的使用是一致的,对应的用户空间内存释放函数是...一般我们会用到 kmalloc()、kzalloc()、vmalloc() 等,下面我们介绍一下这些函数的使
  • linux中kmalloc和vmalloc的使用

    千次阅读 2013-09-29 16:10:18
    kmalloc和get_free_page申请的内存位于物理内存映射区域,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因此存在较简单的转换关系,virt_to_phys()可以实现内核虚拟地址转化为物理地址: ...
  • Linux提供了复杂的存储管理系统,使得进程所能访问的内存达到4GB ...内核空间中,从3G到vmalloc_start这段地址是物理内存映射区域(该区域中包含了内核镜像、物理页框表mem_map等等),比如我们使用 ...
  • 进程空间地址分布从0到3G(其实是到PAGE_OFFSET, 在0x86中它等于0xC0000000),从3G到vmalloc_start这段地址是物理内存映射区域(该区域中包含了内核镜像、物理页面表mem_map等等)比如我使用的系统内存是64M(可以...
  • 本文目的在于分析Linux内核中的vmalloc函数。内核版本为2.6.31。 我们知道物理上连续的映射对内核是最好的,但不是总能成功。在分配一大块内存时,可能无法找到连续的内存块。在用户空间这不是问题,因为普通进程...
  • 一、内核中不连续页的分配 我们知道物理上连续的映射对内核是最好的,但并不总能成功地使用。在分配一大块内存时,可能竭尽全力也无法找到连续的内存块。... 每个vmalloc分配的子区域都是自包含的,与其...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,031
精华内容 1,612
关键字:

linuxvmalloc区域

linux 订阅