Linux下内存空间分配、物理地址与虚拟地址映射
1.1 kmalloc函数Kmalloc分配的是连续的物理地址空间。如果需要连续的物理页可以使用此函数这是内核中内存分配的常用方式也是大多数情况下应该使用的内存分配方式。传递给函数的最常用的标志是GTP_ATOMIC和GTP_KERNEL。前面的标志表示进行不睡眠的高优先级分配。在中断处理程序和其他不能睡眠的代码段中需要。后面的标志可以睡眠在没有持自旋锁的进程上下文中使用。此函数返回内核逻辑地址。头文件#include linux/slab.h1.1.1 申请空间代码语言javascriptAI代码解释static void *kmalloc(size_t size, gfp_t flags) 参数 size_t size 申请的空间大小 gfp_t flags申请的标志(模式) 返回值申请的空间首地址。如果为NULL表示分配失败 一般填写的模式 GFP_ATOMIC用来从中断处理和进程上下文之外的其他代码中分配内存分配内存优先级高不会阻塞 GFP_KERNEL内核内存的正常分配方式可能会阻塞。1.1.2 释放内存空间代码语言javascriptAI代码解释void kfree(const void *block) 参数 void *block将要释放空间的首地址1.1.3 示例代码语言javascriptAI代码解释1.1.3 示例 #include linux/init.h #include linux/module.h #include linux/slab.h char *buff; static int __init interrupt_init(void) { printk(init ok\n); /*1.1 申请空间*/ buffkmalloc(1024, GFP_KERNEL); /*1.2 初始化空间*/ memset(buff,0x10,1024); /*1.3 打印出空间的数据*/ int i; for(i0;i1024;i) { printk(0x%X \n,buff[i]); } return 0; } static void __exit interrupt_exit(void) { /*1.4 释放申请的空间*/ kfree(buff); printk(exit ok\n); } module_init(interrupt_init); /*驱动入口*/ module_exit(interrupt_exit); /*驱动出口*/ MODULE_LICENSE(GPL);1.2 vmalloc 函数分配的空间是线性的在物理地址上不连续最多分配1GB的空间。定义文件\mm\vmalloc.c头文件#include linux/vmalloc.h1.2.1 申请空间代码语言javascriptAI代码解释void *vmalloc(unsigned long size)参数unsigned long size 分配空间的大小返回值申请的空间首地址1.2.2 释放空间代码语言javascriptAI代码解释void vfree(const void *addr)参数const void *addr释放的空间首地址1.2.3 示例代码语言javascriptAI代码解释#include linux/init.h #include linux/module.h #include linux/vmalloc.h #include linux/slab.h char *buffNULL; static int __init interrupt_init(void) { printk(init ok\n); /*1.1 申请空间*/ buffvmalloc(1024); if(buffNULL) { printk(内存空间分配失败!\n\n); } /*1.2 初始化空间*/ memset(buff,0x10,1024); /*1.3 打印出空间的数据*/ int i; for(i0;i1024;i) { printk(0x%X \n,buff[i]); } printk(buff0x%x\n,buff); //buff0xf0537000 return 0; } static void __exit interrupt_exit(void) { /*释放申请的空间*/ vfree(buff); printk(exit ok\n); } module_init(interrupt_init); /*驱动入口*/ module_exit(interrupt_exit); /*驱动出口*/ MODULE_LICENSE(GPL);1.3 区别总结代码语言javascriptAI代码解释1.​ kmalloc和vmalloc是分配的是内核的内存,malloc分配的是用户的内存 2.​ kmalloc保证分配的内存在物理上是连续的,vmalloc保证的是在虚拟地址空间上的连续 3.​ kmalloc能分配的大小有限,vmalloc能分配的大小相对较大 4.​ 内存只有在要被DMA访问的时候才需要物理上连续 5.​ vmalloc比kmalloc要慢二、​ MMAP驱动实现2.1 应用层mmap函数介绍mmap函数用于将一个文件或者其它对象映射进内存通过对这段内存的读取和修改来实现对文件的读取和修改而不需要再调用read,write等操作。头文件sys/mman.h函数原型代码语言javascriptAI代码解释void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset); int munmap(void* start,size_t length);映射函数代码语言javascriptAI代码解释void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);1​ addr: 指定映射的起始地址通常设为NULL由系统指定。2​ length:映射到内存的文件长度。3​ prot:映射的保护方式可以是PROT_EXEC映射区可被执行PROT_READ映射区可被读取PROT_WRITE映射区可被写入PROT_NONE映射区不能存取4​ Flags:映射区的特性可以是MAP_SHARED写入映射区的数据会复制回文件且允许其他映射该文件的进程共享。MAP_PRIVATE对映射区的写入操作会产生一个映射区的复制(copy_on_write)对此区域所做的修改不会写回原文件。5​ fd:由open返回的文件描述符代表要映射的文件。6​ offset:以文件开始处的偏移量必须是分页大小的整数倍通常为0表示从文件头开始映射。解除映射代码语言javascriptAI代码解释int munmap(void *start, size_t length);功能取消参数start所指向的映射内存参数length表示欲取消的内存大小。返回值解除成功返回0否则返回-12.2 Linux内核的mmap接口2.2.1 内核描述虚拟内存的结构体Linux内核中使用结构体vm_area_struct来描述虚拟内存的区域其中几个主要成员如下代码语言javascriptAI代码解释unsigned long vm_start 虚拟内存区域起始地址 unsigned long vm_end 虚拟内存区域结束地址 unsigned long vm_flags 该区域的标志该结构体定义在linux/mm_types.h头文件中。该结构体的vm_flags成员赋值的标志为VM_IO和VM_RESERVED。其中VM_IO表示对设备IO空间的映射M_RESERVED表示该内存区不能被换出在设备驱动中虚拟页和物理页的关系应该是长期的应该保留起来不能随便被别的虚拟页换出取消。2.2.2 mmap操作接口在字符设备的文件操作集合struct file_operations中有mmap函数的接口。原型如下代码语言javascriptAI代码解释int (*mmap) (struct file *, struct vm_area_struct *);其中第二个参数struct vm_area_struct *相当于内核找到的可以拿来用的虚拟内存区间。mmap内部可以完成页表的建立。2.2.3 实现mmap映射映射一个设备是指把用户空间的一段地址关联到设备内存上当程序读写这段用户空间的地址时它实际上是在访问设备。这里需要做的两个操作代码语言javascriptAI代码解释1.找到可以用来关联的虚拟地址区间。 2.实现关联操作。mmap设备操作实例如下代码语言javascriptAI代码解释static int tiny4412_mmap(struct file *myfile, struct vm_area_struct *vma) { vma-vm_flags | VM_IO;//表示对设备IO空间的映射 vma-vm_flags | VM_RESERVED;//标志该内存区不能被换出在设备驱动中虚拟页和物理页的关系应该是长期的应该保留起来不能随便被别的虚拟页换出 if(remap_pfn_range(vma,//虚拟内存区域即设备地址将要映射到这里 vma-vm_start,//虚拟空间的起始地址 virt_to_phys(buf)PAGE_SHIFT,//与物理内存对应的页帧号物理地址右移12位 //说明: 向后面移动12位相当于除4096 为了得到页编号 vma-vm_end - vma-vm_start,//映射区域大小一般是页大小的整数倍 vma-vm_page_prot))//保护属性 { return -EAGAIN; } printk(tiny4412_mmap\n); return 0; }其中的buf就是在内核中申请的一段空间。使用kmalloc函数实现。代码如下代码语言javascriptAI代码解释buf (char *)kmalloc(MM_SIZE, GFP_KERNEL); //内核申请内存只能按页申请申请该内存以便后面把它当作虚拟设备2.2.4 remap_pfn_range函数remap_pfn_range函数用于一次建立所有页表。函数原型如下代码语言javascriptAI代码解释int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, unsigned long size, pgprot_t prot);其中vma是内核为我们找到的虚拟地址空间addr要关联的是虚拟地址pfn是要关联的物理地址size是关联的长度是多少。ioremap与phys_to_virt、virt_to_phys的区别ioremap是用来为IO内存建立映射的 它为IO内存分配了虚拟地址这样驱动程序才可以访问这块内存。phys_to_virt只是计算出某个已知物理地址所对应的虚拟地址。将内核物理地址转化为虚拟地址。virt_to_phys 将内核虚拟地址转化为物理地址。

相关新闻

【OpenClaw -09】OpenClaw 自动化编排:Cron 精准调度与 Heartbeat 批处理

【OpenClaw -09】OpenClaw 自动化编排:Cron 精准调度与 Heartbeat 批处理

OpenClaw 自动化编排:Cron 精准调度与 Heartbeat 批处理 在724小时运行的AI Agent生产环境中,"定时触发"与"健康巡检"是自动化运维的双支柱。OpenClaw通过六字段Cron引擎(支持秒级精度)与可编排的Heartbeat机…

2026/7/6 8:01:44 阅读更多 →
黑丝空姐-造相Z-Turbo对比传统CG:在AE视频制作中的辅助角色

黑丝空姐-造相Z-Turbo对比传统CG:在AE视频制作中的辅助角色

黑丝空姐-造相Z-Turbo对比传统CG:在AE视频制作中的辅助角色 最近在尝试用After Effects做几个短视频片段,从片头动画到一些转场特效,整个过程让我再次体会到传统CG流程的“重量感”。从构思、建模、贴图、绑定到最终渲染,每一步都…

2026/5/17 11:59:55 阅读更多 →
简单的Python调用C++程序

简单的Python调用C++程序

一般来说在python调用C/C程序主要可以分为3步:1、编写C/C实现程序。- 2、将C/C程序编译成动态库。- 3、在Python中调用编译生成的库。Python在调用C/C程序时有一些不同,需要注意。1、Python调用C函数Python调用C语言程序比较简单,将C语言程序…

2026/7/6 12:09:15 阅读更多 →

最新新闻

@Async异步线程:Spring 自带的异步解决方案

@Async异步线程:Spring 自带的异步解决方案

前言 在项目应用中,使用MQ异步调用来实现系统性能优化,完成服务间数据同步是常用的技术手段。如果是在同一台服务器内部,不涉及到分布式系统,单纯的想实现部分业务的异步执行,这里介绍一个更简单的异步方法调…

2026/7/6 21:30:26 阅读更多 →
揭秘HQTrack核心架构:InternT-MSDeAOTL-V2模型如何实现高精度实时追踪?

揭秘HQTrack核心架构:InternT-MSDeAOTL-V2模型如何实现高精度实时追踪?

揭秘HQTrack核心架构:InternT-MSDeAOTL-V2模型如何实现高精度实时追踪? 【免费下载链接】HQTrack Tracking Anything in High Quality 项目地址: https://gitcode.com/gh_mirrors/hq/HQTrack 你是否曾想过,如何让计算机像人类一样精准…

2026/7/6 21:28:26 阅读更多 →
从 0 新增一个 has.echo:我如何理解小程序容器里的 API 调用链路

从 0 新增一个 has.echo:我如何理解小程序容器里的 API 调用链路

从 0 新增一个 has.echo:我如何理解小程序容器里的 API 调用链路说明:本文是一次脱敏后的学习复盘。文中的 has.echo、EchoModule、system.demo 都是为了讲清楚调用链路而设计的最小示例,不包含公司内部源码、真实业务接口、真实模块路径和敏…

2026/7/6 21:28:26 阅读更多 →
151、RAG 检索增强生成(五):评估体系——RAGAS 指标、人工评测与线上监控

151、RAG 检索增强生成(五):评估体系——RAGAS 指标、人工评测与线上监控

151、RAG 检索增强生成(五):评估体系——RAGAS 指标、人工评测与线上监控 上周五凌晨两点,我被生产环境告警电话吵醒。用户反馈一个法律咨询机器人回答“根据《民法典》第X条,您需要承担全部责任”,但实际法条引用完全错误。我查了日志,发现RAG检索到的文档片段是某篇自…

2026/7/6 21:26:25 阅读更多 →
MySQL 联表查询性能对比:INNER JOIN vs 子查询 vs 临时表,3方案效率实测

MySQL 联表查询性能对比:INNER JOIN vs 子查询 vs 临时表,3方案效率实测

MySQL 联表查询性能优化实战:INNER JOIN vs 子查询 vs 临时表在数据库应用开发中,联表查询是最常见也最容易出现性能问题的操作之一。面对复杂的业务场景,开发者往往需要在多种实现方案中做出选择。本文将针对学生-课程-教师这一经典场景&…

2026/7/6 21:26:25 阅读更多 →
SDF在游戏开发中的创新应用:Dreams与Claybook技术案例分析

SDF在游戏开发中的创新应用:Dreams与Claybook技术案例分析

SDF在游戏开发中的创新应用:Dreams与Claybook技术案例分析 【免费下载链接】SDF Collection of resources (papers, links, discussions, shadertoys,...) related to Signed Distance Field 项目地址: https://gitcode.com/gh_mirrors/sdf/SDF 有符号距离场…

2026/7/6 21:22:23 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻