vmalloc最小分配一个page,并且分配到的页面不保证是连续的,因为vmalloc内部调用alloc_page多次分配单个页面。 ?...vmalloc的区域就是在上图中VMALLOC_START - VMALLOC_END之间,可通过/proc/vmallocinfo查看。...struct vmap_area { unsigned long va_start; //vmalloc申请虚拟地址返回的起始地址 unsigned long va_end; //vmalloc申请申请虚拟地址返回的结束地址...IO共享内存,其他情况下为0 const void *caller; //调用vmalloc函数的函数的地址 }; ?...vmalloc 主要分以下三步: 从VMALLOC_START到VMALLOC_END查找空闲的虚拟地址空间(hole) 根据分配的size,调用alloc_page依次分配单个页面.
VMALLOC_END, gfp_mask, prot, 0, node, caller); } 这里的VMALLOC_START和VMALLOC_END是vmalloc中最重要的宏,这两个宏定义在...VMALLOC_START是vmalloc区域的开始地址,它是在High_memory指定的高端内存开始地址再加上8MB大小的安全区域(VMALLOC_OFFSET)。...long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) #define VMALLOC_END 0xff000000UL [vmalloc...如果不能再已有vmalloc区块的缝隙中找到合适的hole,那么从最后一块vmalloc区块的结束地址开始一个新的vmalloc区域,见第71~83行代码。...[vmalloc()->__vmalloc_node_range()->__vmalloc_area_node()] static void *__vmalloc_area_node(struct vm_struct
没办法,只好重新调整驱动中分配内存的方式,改用vmalloc获取地址空间。 在kernel里,通常有3种申请内存的方式:vmalloc, kmalloc, alloc_pages。...而vmalloc则可以申请一段不连续的物理地址空间,并将其映射到连续的线性地址上。每次vmalloc之后,内核会创建一个vm_struct,用以映射分配到的不连续的内存区域。...另一种方法是直接使用remap_vmalloc_range()函数。...是mmap使用调用传下来的,addr即为vmalloc()所分配内存的起始地址。...需要注意的是,需要映射到用户空间的内存段,不能直接利用vmalloc()分配,而应该使用vmalloc_user()函数。
在 Linux 系统中的每个进程都有独立 4GB 内存空间,而 Linux 把这 4GB 内存空间划分为用户内存空间(0 ~ 3GB)和内核内存空间(3GB ~ 4GB),而内核内存空间由划分为直接内存映射区和动态内存映射区...(vmalloc区)。...这时候就需要提供一个机制能够让内核使用 896MB 之外的物理内存,所以 Linux 就实现了一个 vmalloc 机制。...vmalloc实现 可以通过 vmalloc() 函数向内核申请一块内存,其原型如下: void * vmalloc(unsigned long size); 参数 size 表示要申请的内存块大小。...为了解决内核空间同步问题,Linux 并不是直接对当前进程的内核空间映射的,而是对 init 进程的内核空间(init_mm)进行映射,我们来看看 vmalloc_area_pages() 函数的实现:
)和__get_free_pages()函数申请的内存位于物理内存的映射区域,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因此存在简单的线性关系;(3G+896M)(低端内存); vmalloc...3、vmalloc() vmalloc()一般用在只存在于软件中的较大顺序缓冲区分配内存,vmalloc()远大于__get_free_pages()的开销,为了完成vmalloc(),新的页表需要被建立...以字节为单位进行分配,在中 2. void *kmalloc(size_t size, int flags) 分配的内存物理地址上连续,虚拟地址上自然连续 3. gfp_mask
文章目录 一、Linux 内核 动态分配内存 系统接口函数 二、统计输出 vmalloc 分配的内存 一、Linux 内核 动态分配内存 系统接口函数 ---- Linux 内核 " 动态分配内存 "...---- 执行 grep vmalloc /proc/vmallocinfo 命令 , 可以统计输出 通过 vmalloc 函数分配的 " 虚拟地址连续的内存块 " ; 参考输出内容 : root@ubuntu...=4 vmalloc N0=4 0xffffa769c0018000-0xffffa769c001d000 20480 _do_fork+0x76/0x3e0 pages=4 vmalloc N0=...=1 vmalloc N0=1 0xffffa769c0074000-0xffffa769c0079000 20480 _do_fork+0x76/0x3e0 pages=4 vmalloc N0=...=1 vmalloc N0=1 0xffffa769c00a4000-0xffffa769c00a9000 20480 fork_idle+0x5d/0xf0 pages=4 vmalloc N0=
/include/linux/vmalloc.h?...所有有关vmalloc的数据结构和API结构声明在include/linux/vmalloc.h 声明头文件 NON-MMU实现 MMU实现 include/linux/vmalloc.h mm/nommu.c...该结构提的定义在include/linux/vmalloc.h?...v=4.7, line 32 // http://lxr.free-electrons.com/source/include/linux/vmalloc.h?...函数声明如下, include/linux/vmalloc.h?
变更履历 内核版本4.5.0支持arm64undefinedhttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit.../kernel/git/torvalds/linux.git/commit/?.../linux.git/commit/?.../linux.git/commit/?...IS_ENABLED(CONFIG_ARM_MODULE_PLTS) || p) return p; return __vmalloc_node_range(size, 1, VMALLOC_START
内核启动源码 start_kernel ---- 在 Linux 内核初始化完成后 , 会在 " 初始化内存 " 时 , 输出 内存布局 ; Linux 内核启动源码是定义在 linux-5.6.18..., VMALLOC_END, (VMALLOC_END - VMALLOC_START) >> 20, (unsigned long)__va(0), (unsigned long)high_memory...> PKMAP_BASE); #endif #define high_memory (-128UL << 20) BUILD_BUG_ON(VMALLOC_START >= VMALLOC_END...> PKMAP_BASE); #endif BUG_ON(VMALLOC_START >= VMALLOC_END); BUG_ON((unsigned long)high_memory...> VMALLOC_START); test_wp_bit(); }
(4)通过vmalloc获得内存 vmalloc()分配的内存虚拟地址是连续的,但物理地址不需要连续。这也是malloc()的分配方式。...vmalloc分配非连续的内存块,再修改页表,把内存映射到逻辑空间连续的区域内。 大多数情况下,只有硬件设备需要得到物理地址连续的内存,内核可以使用通过vmalloc获得的内存。...但内核中多采用kmalloc,这主要是考虑性能,因为vmalloc会引起较大的TLB抖动,除非映射大块内存时采用vmalloc。例如模块动态加载时,就是加载到通过vmalloc分配的内存。...vmalloc在声明,在定义,用法和malloc()相同。...void* vmalloc(unsigned long size); void vfree(void *addr); vmalloc会引起睡眠 (5)通过slab机制获得内存 分配和释放数据结构是内核最普遍的操作之一
前面已经分析了linux内存管理算法(伙伴管理算法)的准备工作。...()则是用于vmalloc的初始化。..., VMALLOC_END, (VMALLOC_END - VMALLOC_START) >> 20, (unsigned long)__va(0), (unsigned...managed_pages则是记录管理区的管理页面数,totalhigh_pages则是记录高端内存的页面总数; 具体看一下__free_reserved_page(): 【file:/include/linux...ClearPageReserved(page); init_page_count(page); __free_page(page); } 其中ClearPageReserved定义在/include/linux
调用 " 内核与用户层接口 “ 中的 brk sbrk mmap munmap 等函数 , 这些函数就是 ” 系统调用 " 函数 ; 系统调用接口 是 用户层的 malloc 函数 与 内核层的 vmalloc...函数之间的 桥梁 ; ③ 内核层调用 : 内核与用户层接口 的 内存管理函数 调用 " Linux 内核 " 中的 kmalloc vmalloc 函数 ; C 语言中使用 malloc free 等函数分配堆内存...内核 内存管理】Linux 内核堆内存管理 ② ( 动态分配堆内存方式 | brk 系统调用 | mmap 系统调用 | brk 系统调用源码介绍 ) 博客 , 了解 brk 和 mmap 系统调用...; brk 系统调用 : 该方式本质是 设置 " 进程数据段 “ 的 结束地址 , 将该 ” 结束地址 " 向 高或低 移动 , 实现堆内存的 扩张或收缩 ; mmap 系统调用 : 向 Linux...内核中 , 通过 kmalloc vmalloc __get_free_pages 函数管理内存 ;
Linux内核在启动时会打印出内核内存空间的布局图,下面是ARM Vexpress平台打印出来的内存空间布局图: ? 这部分信息打印是在mem_init()函数中实现的。...static void * __initdata vmalloc_min = (void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET); void __...内核许多驱动使用vmalloc来分配连续的虚拟地址的内存,因为有的驱动不需要连续的物理地址的内存;除此之外,vmalloc还可以用于高端内存的临时映射。...) */ #define VMALLOC_OFFSET (8*1024*1024) #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET...) & ~(VMALLOC_OFFSET-1)) #define VMALLOC_END 0xff000000UL vmalloc区域在ARM32内核中,从VMALLOC_START开始到VMALLOC_END
前面已经分析过了Intel的内存映射和linux的基本使用情况,已知head_32.S仅是建立临时页表,内核还是要建立内核页表,做到全面映射的。...- PAGE_OFFSET - __VMALLOC_RESERVE) 那么VMALLOC_END的定义则为: (file:arch/x86/include/asm/pgtable_32_types.h...动态内存映射区,又称之为vmalloc映射区或非连续映射区,是指VMALLOC_START到VMALLOC_END的地址空间,申请释放操作接口是vmalloc()/vfree(),通常用于将非连续的物理内存映射为连续的线性地址内存空间...已知PAGE_OFFSET默认的为0xC0000000,而__VMALLOC_RESERVE为: unsigned int __VMALLOC_RESERVE = 128 << 20; 最后在个人的实验环境上...由此管中窥豹,看到了Linux内存分页映射模型的存在和相关设计,暂且也就先了解这么多。 分析宏是一件很乏味的事情,不过以小见大却是一件很有意思的事情。
调用 " 内核与用户层接口 “ 中的 brk sbrk mmap munmap 等函数 , 这些函数就是 ” 系统调用 " 函数 ; 系统调用接口 是 用户层的 malloc 函数 与 内核层的 vmalloc...函数之间的 桥梁 ; ③ 内核层调用 : 内核与用户层接口 的 内存管理函数 调用 " Linux 内核 " 中的 kmalloc vmalloc 函数 ; 参考 【Linux 内核 内存管理】内存管理架构...free | 系统调用层 brk mmap | 内核层 kmalloc | 内存管理流程 ) 博客 ; 3、malloc 使用的系统调用判定 ( brk | mmap ) 内核层 使用 kmalloc vmalloc...是 128 KB ; 使用 brk 系统调用 : 如果 应用程序 申请的内存大小 小于 划分阈值 , glibc 库 的 ptmalloc " 内存分配器 " 会使用 brk 系统调用 , 向 Linux...内核申请内存 ; 4、mmap 创建内存映射 mmap 可以直接向 Linux 内核申请 " 虚拟内存 " , 不需要经过 " 用户态 “ 与 ” 内核态 " 之间的转换 ; 二、mmap 创建内存映射
Linux:/proc/meminfo参数详细解释 一、Linux内存总览图 二、meminfo参数的详细介绍 /proc/meminfo是了解Linux系统内存使用状况的主要接口,我们最常用的”free...因为Linux kernel并没有滴水不漏地统计所有的内存分配,kernel动态分配的内存中就有一部分没有计入/proc/meminfo中。...注:/proc/vmallocinfo中能看到vmalloc来自哪个调用者(caller),那是vmalloc()记录下来的,相应的源代码可见: mm/vmalloc.c: vmalloc > __vmalloc_node_flags...> __vmalloc_node > __vmalloc_node_range > __get_vm_area_node > setup_vmalloc_vm 通过vmalloc分配了多少内存,可以统计...在x86系统上Linux的内核栈大小是固定的8K或16K(可参阅我以前的文章:内核栈溢出)。
上面搜索是新功能,大家可以体验看看 今天来带大家研究一下Linux内存管理。...动态内存映射区 vmalloc Region 该区域由内核函数vmalloc来分配,特点是:线性空间连续,但是对应的物理地址空间不一定连续。...vmalloc 分配的线性地址所对应的物理页可能处于低端内存,也可能处于高端内存。 vmalloc 分配的地址则限于vmalloc_start与vmalloc_end之间。...每一块vmalloc分配的内核虚拟内存都对应一个vm_struct结构体,不同的内核空间虚拟地址之间有4k大小的防越界空闲区间隔区。...Reference 《Linux内核设计与实现(原书第3版)》 Linux内存管理 https://cloud.tencent.com/developer/article/1515762 linux 内存管理初探
内核将高端内存划分为3部分: VMALLOC_START~VMALLOC_END KMAP_BASE~FIXADDR_START FIXADDR_START~4G 对 于高端内存,可以通过 alloc_page...在X86上为8M,主要用来防止越界错误;在内存比较小的系统上,余下的线性地址空间(还要再减去空白区即VMALLOC_OFFSET)被vmalloc()函数用来把不连续的物理地址空间映射到连续的线性地址空间上...,在内存比较大的系统上,vmalloc()使用从VMALLOC_START到VMALLOC_END(也即PKMAP_BASE减去2页的空白页大小PAGE_SIZE(解释VMALLOC_END))的线性地址空间...VMALLOC_RESERVE大小的空间。...VMALLOC_RESERVE的大小与体系结构相关,在X86上,VMALLOC_RESERVE定义为128M,这就是为什么ZONE_NORMAL大小通常是16M到896M的原因。
领取专属 10元无门槛券
手把手带您无忧上云