linux内核 - vmalloc 介绍
一:概述
vmalloc 是内核中的一个分配器。它返回的内存 在虚拟地址空间中是连续的,但底层的物理页帧是分散的。
vmalloc分配的内存在物理上并不连续。此外, vmalloc 返回的内存总是来自 HIGH_MEM 区域。返回的地址是 纯虚拟地址(而非逻辑地址),无法直接转换为物理地址或总线地址,因为无法保证其对应的物理内存是连续的。
这意味着,vmalloc() 返回的内存 不能在微处理器之外使用(例如,不能直接用于 DMA 操作)。vmalloc() 适合用于分配 存在于软件中的大块连续页序列(例如网络缓冲区),而不是仅仅分配一页内存。
需要注意的是,vmalloc() 比 kmalloc() 和页分配器函数慢,因为它不仅要获取内存,还需要建立页表,甚至可能重新映射为虚拟连续区域,而 kmalloc() 则无需执行这些操作。
vmalloc() 会分配 非连续的物理页,并将它们映射到 连续的虚拟地址区域。这些 vmalloc 的虚拟地址位于 内核空间的一定区域内,由 VMALLOC_START 和 VMALLOC_END 限定,这两个值依赖于具体的体系结构。
内核提供了 /proc/vmallocinfo 文件,用于显示系统中 所有通过 vmalloc 分配的内存。
二:相关函数和示例
#include <linux/vmalloc.h>void *vmalloc(unsigned long size);
void *vzalloc(unsigned long size);
void vfree(void *addr);
#include <linux/init.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/kernel.h>
#include <linux/string.h> // for memsetstatic void *ptr; // 静态指针用于保存 vmalloc 地址
#define ALLOC_SIZE 8192 // 分配 2 x 4KB 内存static int __init my_vmalloc_init(void)
{pr_info("Initializing vmalloc example module\n");// 分配内存ptr = vmalloc(ALLOC_SIZE);if (!ptr) {pr_err("Memory allocation failed\n");return -ENOMEM;}// 初始化内存memset(ptr, 0, ALLOC_SIZE);pr_info("Memory allocated successfully at virtual address %p\n", ptr);return 0;
}static void __exit my_vmalloc_exit(void)
{if (ptr) {vfree(ptr);pr_info("Memory freed\n");}
}module_init(my_vmalloc_init);
module_exit(my_vmalloc_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("your_email@example.com");
MODULE_DESCRIPTION("A simple vmalloc() example kernel module");