[Linux内核驱动]内存动态申请

内核空间内存动态申请

更多详细内容可以查看我的github

kmalloc()

函数原型:

void *kmalloc(size_t size, gfp_t flags);

参数说明:

  • size:要分配的内存块的大小,以字节为单位。
  • flags:分配标志,用于指定内存分配的策略和属性。
    • GFP_KERNEL:在内核空间的进程中分配内存
    • GFP_ATOMIC:在原子上下文中分配内存

kmalloc()的底层依赖于__get_free_page()来实现,当使用 GFP_KERNEL 申请内存时,若暂时不能满足,则进程会睡眠等待页,引起阻塞,因此不能在 中断上下文 或持有 自选锁 的时候使用GFP_KERNEL申请内存。对于这些在非进程上下文中不能阻塞的情况,应当使用GFP_ATOMIC申请内存,若不存在空闲页,则不等待,直接返回。

kmalloc()类似,kzalloc() 函数也用于分配内存,区别在于kzalloc()函数会在分配的内存块中清零。

kmalloc()kzalloc()申请的内存都使用 kfree() 函数释放

__get_free_pages()

__get_free_pages()系列函数/宏本质上是Linux内核最底层用户获取空闲内存的方法。因为底层的buddy算法以2n页的方式管理内存,所以底层申请内存是以2n页为单位。n最大为10或11

  • __get_free_pages(gfp_mask, int order):分配2^order页的内存。
  • __get_free_page(gfp_mask):分配一个页(4KB)的内存。
    • 这个宏实际上就是调用__get_free_pages分配1页内存
  • get_zeroed_page(gfp_mask):分配并清零一个页的内存。

在可能阻塞的上下文中(如进程上下文),应使用允许阻塞的标志(GFP_KERNEL)。在不允许阻塞的上下文中(如中断上下文或持有自旋锁时),应使用不允许阻塞的标志(GFP_ATOMICGFP_NOWAIT)。

上面的申请的内存使用free_page(addr)free_pages(addr, order)释放。

vmalloc()

vmalloc()函数用于在内核中分配大的、连续的虚拟地址空间,但物理地址可能不连续。这通常用于需要连续虚拟地址但不需要物理连续性的情况,如大型数据结构或设备驱动程序的缓冲区。vmalloc()需要建立新的页表项,所以其开销很大。此外,vmalloc()不能应用在原子上下文中,因为其内部实现使用了GFP_KERNEL标志的kmalloc()

函数原型:

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

slab分配器

在Linux中,伙伴分配器(buddy allocator)是以页为单位管理和分配内存。但在内核中的需求,一方面,完全使用页为单位申请内存严重浪费内存;另一方面,Linux运行过程中经常会涉及到大量重复对象的重复生成、使用和释放内存问题(task_struct、inode等)。

为了解决这个问题,Linux内核引入了slab分配器。slab分配器以字节为单位,从 Buddy 分配器中申请内存,之后对申请来的内存细分管理。

struct kmem_cache

struct kmem_cache:这是Slab分配器的一部分,它提供了一种用于快速分配和释放固定大小内存块的机制。Slab分配器为每种大小的对象维护一个缓存池,从而提高了内存分配的效率。

kmem_cache_create()

创建一个新的kmem_cache实例。

函数原型:

struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align, unsigned long flags, void (*ctor)(void *));

参数说明:

  • name: 缓存的名称,用于调试和日志记录。
  • size: 缓存中每个对象的大小(以字节为单位)。
  • align: 每个对象的对齐要求(通常设置为0,让slab分配器选择最佳的对齐)。
  • flags: 标志位,用于控制缓存的行为
    • SLAB_HWCACHE_ALIGN:表示对象应该按硬件缓存行对齐,即对齐到一个缓存行
    • SLAB_RECLAIM_DMA:表示在DMA区域中分配
  • ctor: 构造函数(可选),当从缓存中分配对象时,此函数将被调用以初始化对象。

返回值:

  • 成功时返回一个指向新创建的 kmem_cache 结构体的指针。
  • 失败时返回 NULL。

kmem_cache_alloc()

从指定的kmem_cache中分配内存

函数原型:

c
void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags);

参数说明:

  • cachep: 之前通过 kmem_cache_create() 创建的 kmem_cache 结构体的指针。
  • flags: GFP(Get Free Pages)标志,用于控制内存分配的行为。

返回值:

  • 成功时返回一个指向新分配对象的指针。
  • 失败时(例如,由于内存不足)返回 NULL。

kmem_cache_free()

释放kmem_cache_alloc申请的内存

函数原型:

void kmem_cache_free(struct kmem_cache *cachep, void *objp);

参数说明:

  • cachep: 与对象关联的 kmem_cache 结构体的指针。
  • objp: 要释放的对象的指针。

kmem_cache_destroy()

销毁一个kmem_cache实例。

函数原型:

void kmem_cache_destroy(struct kmem_cache *cachep);

代码

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/gfp.h>
#include <linux/vmalloc.h>struct mem_dev
{char* test;struct kmem_cache* cache;
};struct mem_dev* mem_devp;static int __init mem_dev_init_module(void)
{printk(KERN_INFO "mem_init\n");mem_devp = kmalloc(sizeof(struct mem_dev), GFP_KERNEL);// kmallocmem_devp->test = kmalloc(1024, GFP_KERNEL);if (!mem_devp->test){return -ENOMEM;}printk(KERN_INFO "kmalloc get addr %p\n", mem_devp->test);kfree(mem_devp->test);// __get_free_pagemem_devp->test = (void*)__get_free_page(GFP_KERNEL);if (!mem_devp->test){return -ENOMEM;}printk(KERN_INFO "__get_free_page get addr %p\n", mem_devp->test);free_page((unsigned long)mem_devp->test);// vmallocmem_devp->test = vmalloc(PAGE_SIZE * 16);if (!mem_devp->test){return -ENOMEM;}printk(KERN_INFO "vmalloc get addr %p\n", mem_devp->test);vfree(mem_devp->test);// slabmem_devp->cache = kmem_cache_create("mem_cache", sizeof(struct mem_dev), 0, SLAB_HWCACHE_ALIGN, NULL);if (!mem_devp->cache){return -ENOMEM;}mem_devp->test = kmem_cache_alloc(mem_devp->cache, GFP_KERNEL);if (!mem_devp->test){return -ENOMEM;}printk(KERN_INFO "slab get addr %p\n", mem_devp->test);kmem_cache_free(mem_devp->cache, mem_devp->test);kmem_cache_destroy(mem_devp->cache);kfree(mem_devp);return 0;
}static void mem_dev_exit_module(void)
{printk(KERN_INFO "mem_dev exit\n");
}module_init(mem_dev_init_module);
module_exit(mem_dev_exit_module);MODULE_AUTHOR("lidonghang-02");
MODULE_LICENSE("GPL");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/31781.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

挑战与机遇的交织

AI与音乐创作&#xff1a;挑战与机遇的交织 引言 近年来&#xff0c;人工智能技术的迅猛发展使得其在各个领域都展现出了巨大的潜力和影响力&#xff0c;音乐创作领域也不例外。最近上线的音乐大模型&#xff0c;无疑是这一趋势的一个重要节点&#xff0c;它极大地降低了素人…

市场价格到底是因为什么而变动?

在外汇及广泛的金融市场中&#xff0c;影响金融工具价格起伏的因素纷繁复杂。然而&#xff0c;万变不离其宗&#xff0c;无论是哪个市场&#xff0c;价格的最终决定力量始终是供需之间的平衡法则。 对于外汇、大宗商品等金融市场而言&#xff0c;表面上似乎受宏观经济数据、央…

FastBoot刷机获取root权限(Magisk)

1.首先要下载ADB、Fastboot等工具。 1.ADB、Fastboot工具 https://developer.android.com/studio/releases/platform-tools 2.安装FastBoot的USB驱动 https://developer.android.com/studio/run/oem-usb 2.下载对应的镜像 https://developers.google.com/android/images?…

Ubuntu系统配置C/C++编译环境

在Ubuntu系统中安装和学习C语言非常的方便&#xff0c;与Windows复杂的环境配置不同&#xff0c;Ubuntu提供了多种C/C开发工具&#xff0c;如GCC&#xff08;GNU Compiler Collection&#xff09;、GDB&#xff08;GNU Debugger&#xff09;和Valgrind等。这些工具不仅功能强大…

24.1 部署-交叉编译、压缩二进制文件、Docker容器

1. 交叉编译 Go语言的优越性之一是可在众多环境下运行&#xff0c;其中包括&#xff1a; 操作系统 windows、darwin、plan9、solaris、linux、netbsd/openbsd/freebsd、android体系架构 386/amd64、arm/arm64、ppc64/ppc64le、mips/mipsle/mips64/mips64le 使用go env命令可…

穿越时空的金星奥秘:揭秘古代天文学的惊人成就

在浩瀚的历史长河中&#xff0c;人类对宇宙的探索从未停止。而在中国古代&#xff0c;一项惊人的天文发现&#xff0c;至今仍让世界为之惊叹。那就是西汉时期的《五星占》&#xff0c;一部揭示金星会合周期的珍贵文献&#xff0c;其精确度之高&#xff0c;足以令现代天文学家瞠…

【AI基础】大模型资源整理

开局一张图&#xff0c;全靠硬凑&#xff1a; 硬拼一个雷达图&#xff1a; AI大模型&#xff0c;这是核心智能助手&#xff0c;基于大模型搭建的拿来就用的成熟应用平台应用分享&#xff0c;基于大模型搭建的拿来就用的小应用AI开发&#xff0c;基于大模型开发小应用 学习资源…

基于gunicorn+flask+docker模型高并发部署

好的&#xff0c;今天我们将讨论如何使用 Gunicorn Flask Docker 来实现高并发部署。这个模型是一个流行的组合&#xff0c;用于部署Python编写的Web应用程序&#xff0c;特别是使用Flask框架的应用程序。Gunicorn是一个Python WSGI HTTP服务器&#xff0c;而Docker提供了一个…

容器之分栏窗体构件演示

代码; #include <gtk-2.0/gtk/gtk.h> #include <glib-2.0/glib.h> #include <gtk-2.0/gdk/gdkkeysyms.h> #include <stdio.h>int main(int argc, char *argv[]) {gtk_init(&argc, &argv);GtkWidget *window;window gtk_window_new(GTK_WINDO…

智慧园区解决方案PPT(53页)

## 1.1 智慧园区背景及需求分析 - 智慧园区的发展历程包括园区规划、经济、产业、企业、管理、理念的转变&#xff0c;强调管理模式创新&#xff0c;关注业务综合化、管理智慧化等发展。 ## 1.2 国家对智慧园区发展的政策 - 涉及多个国家部门&#xff0c;如工信部、住建部、…

抖音开放平台代开发小程序,上传模板代码

大家好&#xff0c;我是小悟 抖音小程序第三方平台开发着力于解决抖音生态体系内的小程序管理问题&#xff0c;一套模板&#xff0c;随处部署。能尽可能地减少服务商的开发成本&#xff0c;服务商只用开发一套小程序代码作为模板就可以快速批量的孵化出大量的商家小程序。 第…

Service方法增加@Asyn注解后导致bean无法找到 NoSuchBeanDefinitionException

Service方法增加Asyn注解后导致bean无法找到 NoSuchBeanDefinitionException 场景处理方法原因 场景 首先确认的是Service添加了Service或Component等注解&#xff0c;另外也增加了ComponentScan确定扫描的包路径是包含对应Service的&#xff0c;但就是无法找到这个bean。 通…

开放式耳机怎么选?五款劲爆机型强势PK!2024推荐版!

身为健身达人&#xff0c;我对耳机的要求可不低。开放式耳机让我在健身时既能享受音乐&#xff0c;又能清晰听到教练的指导。它佩戴舒适&#xff0c;不易掉落&#xff0c;而且音质出色&#xff0c;让我沉浸于运动的节奏中。市面上开放式耳机种类繁多&#xff0c;我为大家挑选了…

Omnivore:全能开源稍后阅读神器,让文字爱好者畅享阅读乐趣!

热门开源项目推荐 项目地址&#x1f517;&#x1f517;&#x1f517;&#x1f517; https://gitcode.com/omnivore-app/omnivore/overview Omnivore&#xff1a;全能开源稍后阅读神器 Omnivore App 介绍 Omnivore是一个完整的开源稍后阅读解决方案&#xff0c;专为喜欢文字…

【HarmonyOS NEXT】鸿蒙 如何在包含web组件的页面 让默认焦点有效

页面包含web组件Button组件等&#xff0c;把页面的默认焦点放到Button组件上&#xff0c;不起效果。 因为web组件默认会在组件加载完成后获取焦点&#xff1b; 可以在web的网页加载完成时onPageEnd回调中&#xff0c;将设置默认获焦的组件通过focusControl.requestFocus方法主…

自动备份SQL Server数据库,试试这4种方法!

各种规模的企业都使用 SQL 数据库来存储数据。因此&#xff0c;备份 SQL Server 数据库对于确保数据安全并在发生灾难时可恢复至关重要。对于 SQL 数据库备份&#xff0c;有多种可行的方法&#xff0c;对于特定组织来说&#xff0c;方法将取决于其具体需求。 SQL Server 备份的…

噪声-降噪引脚如何提高系统性能

由于LDO是电子器件&#xff0c;因此它们会自行产生一定量的噪声。选择低噪声LDO并采取措施来降低内部噪声对于生成不会影响系统性能的清洁电源轨而言不可或缺。 识别噪声 理想的 LDO 会生成没有交流元件的电压轨。遗憾的是&#xff0c;LDO 会像其他电子器件一样自行产生噪声。…

【乐吾乐2D可视化组态编辑器】数据通信

External Player - 哔哩哔哩嵌入式外链播放器 乐吾乐2D可视化组态编辑器地址&#xff1a;https://2d.le5le.com/ Meta2d.js支持 mqtt、websocket 和 http 轮询 3 种方式进行实时数据监听。 如果配置过 mqtt 或 websocket 或 http&#xff0c;下次打开时&#xff0c;会自动…

对于在pycharm中终端失去环境 报错-bash: conda: command not found 2024.6

背景介绍 我是在服务器上一个已经创建好conda环境&#xff0c;可以用vscode去执行conda命令 但是在pycharm上连接之后就一直不能使用conda命令 一直报错 -bash: conda: command not found 问题解读 加载环境变量文件.bashrc&#xff08;前提是你的服务器上已经给conda配置好了环…

解决linux下载github项目下载不下来,下载失败, 连接失败的问题

第一步&#xff1a;打开/etc/hosts文件 linux vim /etc/hosts 第二步&#xff1a;文件拉到最下面&#xff0c;输入以下内容 linux #GitHub Start 140.82.113.3 github.com 140.82.114.20 gist.github.com 151.101.184.133 assets-cdn.github.com 151.101.184.133 raw.githubus…