当前位置: 首页 > news >正文

[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");

相关文章:

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

内核空间内存动态申请 更多详细内容可以查看我的github kmalloc() 函数原型&#xff1a; void *kmalloc(size_t size, gfp_t flags);参数说明&#xff1a; size&#xff1a;要分配的内存块的大小&#xff0c;以字节为单位。flags&#xff1a;分配标志&#xff0c;用于指定内…...

在Worpress增加网站的二级目录,并转向到站外网站

在WordPress中&#xff0c;你可以通过添加自定义重定向来实现将某个二级目录&#xff08;例如 www.example.com/subdir&#xff09;重定向到站外网站。可以通过以下几种方法来实现&#xff1a; 方法一&#xff1a;使用 .htaccess 文件 如果你的服务器使用Apache&#xff0c;你…...

torch.max函数

torch.max函数的用法 第一种第二种 官方介绍&#xff1a;Link 有两种使用场景&#xff0c;输入的参数不同以及返回值不同&#xff1a; 第一种 没有参数dim&#xff0c;但这种只适合一维张量。 torch.max(input) → Tensor Returns the maximum value of all elements in the…...

“打造智能售货机系统,基于ruoyi微服务版本开源项目“

目录 # 开篇 售货机术语 1. 表设计说明 2. 页面展示 2.1 区域管理页面 2.2 合作商管理页面 2.3 点位管理页面 3. 建表资源 3.1 创建表的 SQL 语句&#xff08;包含字段备注&#xff09; 1. Region 表 2. Node 表 3. Partner 表 4. 创建 tb_vending_machine 表的 S…...

LeetCode347:前K个高频元素

题目描述 给你一个整数数组 nums 和一个整数 k &#xff0c;请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 解题思想 使用优先队列 priority_queue<Type, Container, Functional> Type 就是数据类型&#xff0c;Container 就是容器类型&#xff08;C…...

2.线上论坛项目

一、项目介绍 线上论坛 相关技术&#xff1a;SpringBootSpringMvcMybatisMysqlSwagger项目简介&#xff1a;本项目是一个功能丰富的线上论坛&#xff0c;用户可编辑、发布、删除帖子&#xff0c;并评论、点赞。帖子按版块分类&#xff0c;方便查找。同时&#xff0c;用户可以…...

Java面试题:讨论synchronized关键字和java.util.concurrent包中的同步工具,如Lock和Semaphore

在 Java 中&#xff0c;synchronized 关键字和 java.util.concurrent 包中的同步工具都是用来控制多线程环境下的并发访问&#xff0c;以防止数据竞争和确保线程安全。下面是对 synchronized 关键字和 java.util.concurrent 包中的一些同步工具的讨论&#xff0c;包括它们的特点…...

酱香型白酒派系介绍

酱香型白酒作为中国传统白酒的重要流派&#xff0c;以其独特的酱香和复杂的酿造工艺而著称。在酱香型白酒中&#xff0c;形成了多个派系&#xff0c;各具特色。 以下是关于北派、茅派、川派和黔派等各个派系的详细介绍。 一、北派 地理位置&#xff1a;主要产于秦岭和淮河以…...

编译chamfer3D报错

python setup.py install编译chamfer3D报错 出现nvcc fatal : Unsupported gpu architecture ‘compute_86‘的问题&#xff0c;是因为显卡与cuda版本支持的算力不匹配。 nvcc fatal : Unsupported gpu architecture ‘compute_86’ ninja: build stopped: subcommand failed. …...

BuildConfig类找不到,BuildConfig.java类不在编译加载路径问题解决

今天用buildConfigField设置编译时常量遇到了问题&#xff0c;访问不到BuildConfig类&#xff0c;import导包也找不到类&#xff0c;具体设置如下&#xff1a; defaultConfig {applicationId com.sample.abcminSdk 28targetSdk 33versionCode getVerInt()//1versionName getVer…...

海外版coze前端代码助手

定位 解决前端同事的开发问题 参数配置 测试 支持 最屌的大模型及语音播报。 体验地址 海外版前端代码助手 需要魔法才能体验油...

python pyautogui实现图片识别点击失败后重试

安装库 pip install Pillow pip install opencv-python confidence作用 confidence 参数是用于指定图像匹配的信度&#xff08;或置信度&#xff09;的&#xff0c;它表示图像匹配的准确程度。这个参数的值在 0 到 1 之间&#xff0c;数值越高表示匹配的要求越严格。 具体来…...

怎么看电脑实时充电功率

因为我想测试不同的充电器给电脑充电的速度&#xff0c;所以就想找一款软件可以看电脑当前充电功率的软件&#xff0c;我给一个图 直接搜索就可以下载了&#xff0c;charge rate就是功率&#xff0c;这里是毫瓦&#xff0c;换算单位是 1000mw1w 所以我这里充电功率是65w&…...

Qt 实战(4)信号与槽 | 4.2、自定义信号与槽

文章目录 一、自定义信号与槽1、自定义信号2、自定义槽3、连接信号与槽4、总结 前言&#xff1a; 在Qt框架中&#xff0c;信号&#xff08;signals&#xff09;和槽&#xff08;slots&#xff09;机制是对象间通信的核心。这种机制允许对象在特定事件发生时发出信号&#xff0c…...

Android开发系列(六)Jetpack Compose之Box

Box是一个用来组合和控制子元素布局的组件。它可以在一个矩形区域内排列一个或多个子元素&#xff0c;并根据所提供的参数来控制它们的位置、大小和样式。 Box的功能类似传统的FrameLayout。 下面通过示例了解Box的使用方法&#xff0c;首先看一个最简单的示例&#xff0c;如下…...

51单片机STC89C52RC——4.1 独立按键(数码管显示按键值)

目录 目录 目的 一&#xff0c;STC单片机模块 二&#xff0c;矩阵按键模块 2.1 针脚定义 ​编辑 2.2 矩阵按键位置 2.3 如何理解按键按下后针脚的高低电平 2.3.1 错误理解1 2.3.2 错误理解2 2.3.3 正确判定按下的是那个按键的逻辑 2.3.4 判定按键按下的依次扫描程…...

解决双击bootstrap.bat没有生成b2.exe文件

双击bootstrap.bat但是并没有没有生成b2.exe文件&#xff0c;会报如下错误&#xff1a; "cl" 不是内部或外部命令&#xff0c;也不是可运行的程序 或批处理文件。D:\cppsoft\boost_1_85_0\tools\build\src\engine>dir *.exe 驱动器 D 中的卷是 Data 卷的序列号是…...

AI穿戴设备是未来手机的终结者?中国AI商业化的未来预测

AI技术的发展正处于商业化应用的关键阶段&#xff0c;而中国在互联网时代已凭借商业化应用逆袭。AI算法大模型虽强大&#xff0c;但真正普惠民众需与设备深度结合。穿戴式智能设备就成为了新战场&#xff0c;AI算法与穿戴设备结合能释放更大工作效率。私人助理AI将成趋势&#…...

FPGA+Nvidia Orin NX+AI 异构视频图像处理开发平台在高端医疗和工业检测的应用,支持定制,支持国产化

FPGAGPU 异构架构视频图像处理开发平台&#xff0c;它结合了 AMD Zynq UltraScale MPSoC&#xff08;FPGA&#xff09;与 NVIDIA Jetson Orin NX&#xff08;GPU&#xff09;的强大功能&#xff0c;能够应用于对图像精准度和实时性有着严苛要求的行业领域。 Zynq UltraScale MP…...

2000-2023年各省名义GDP、实际GDP、GDP平减指数数据(含原始数据+计算过程+计算结果)(以2000年为基期)

2000-2023年各省名义GDP、实际GDP、GDP平减指数数据&#xff08;含原始数据计算过程计算结果&#xff09;&#xff08;以2000年为基期&#xff09; 1、时间&#xff1a;2000-2023年 2、范围&#xff1a;31省 3、指标&#xff1a;名义GDP、国内生产总值指数、实际GDP、GDP平减…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...