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

mmap底层驱动实现(remap_pfn_range函数)

mmap底层驱动实现

myfb.c(申请了128K空间)
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/device.h>
#include <linux/export.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/export.h>
#include <linux/mm_types.h>
#include <linux/mm.h>
#include <linux/slab.h>#define 	BUFF_SIZE 		(32 * 4 * 1024)static char *buff;
static int major;
static struct class * myfb_class;static int myfb_mmap (struct file *fp, struct vm_area_struct *vm)
{int res;//表示该vma在虚拟地址空间中的偏移地址,单位是页(4K)//unsigned long offset = vm->vm_pgoff << PAGE_SHIFT;   //计算被映射的物理内存的物理页帧号(物理地址+偏移),以页为单位, virt_to_phys将虚拟地址转成物理地址//vm->pgoff表示的是用户空间映射时在VMA中的偏移(即mmap最后一个参数,单位是字节,但vm->pgoff自动转成页单位)unsigned long pfn_start = (virt_to_phys(buff) >> PAGE_SHIFT);   res = remap_pfn_range(vm, vm->vm_start, pfn_start + vm->vm_pgoff,   //在物理页帧号上加上偏移vm->vm_end - vm->vm_start, vm->vm_page_prot);if(res){printk("remap_pfn_range failed\n");return -1;}printk("[kernel] pfn_start = 0x%lx, vm->vm_pgoff = 0x%lx, \\n[kernel] vm->vm_start = 0x%lx, vm->vm_end = 0x%lx, vir_ker_start = 0x%lx\n",  \pfn_start, vm->vm_pgoff, vm->vm_start, vm->vm_end, (unsigned long)buff);return 0;
}static struct file_operations myfb_fops = {.owner = THIS_MODULE,.mmap  = myfb_mmap,
};static int myfb_init(void)
{buff = kzalloc(BUFF_SIZE, GFP_KERNEL);if (!buff){printk("kzalloc failed!\n");return -ENOMEM;}printk("kzalloc success!\n");major = register_chrdev(0, "myfb", &myfb_fops);myfb_class = class_create(THIS_MODULE, "myfb_class");device_create(myfb_class, NULL, MKDEV(major, 0), NULL, "myfb");return 0;
}static void myfb_exit(void)
{device_destroy(myfb_class, MKDEV(major, 0));class_destroy(myfb_class);unregister_chrdev(major, "myfb");kfree(buff);
}module_init(myfb_init);
module_exit(myfb_exit);
MODULE_LICENSE("GPL");
mmap_read.c
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>#define   PAGE_SIZE    (4*1024)
#define   BUFF_SIZE    (1 * PAGE_SIZE)
#define   OFFSET       (2 * PAGE_SIZE)char *p;
int fd;void ctrlc(int signum)
{munmap(p, BUFF_SIZE);close(fd);
}int main(void)
{signal(SIGINT, ctrlc);fd = open("/dev/myfb", O_RDWR);p = (char *)mmap(NULL, BUFF_SIZE, PROT_READ | PROT_WRITE , MAP_SHARED, fd, OFFSET);if(p){printf("mmap addr = 0x%x\n", p);printf("data = %s\n", p);}else{printf("mmap failed\n");}while(1){sleep(1);}return 0;
}
mmap_write.c
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>#define   PAGE_SIZE    (4*1024)
#define   BUFF_SIZE    (1 * PAGE_SIZE)
#define   OFFSET       (0 * PAGE_SIZE)char *p;
int fd;void ctrlc(int signum)
{munmap(p, BUFF_SIZE);close(fd);
}int main(void)
{signal(SIGINT, ctrlc);fd = open("/dev/myfb", O_RDWR);p = (char *)mmap(NULL, BUFF_SIZE, PROT_READ | PROT_WRITE , MAP_SHARED, fd, OFFSET);if(p){printf("mmap addr = 0x%x\n", p);memcpy(p, "hello world", 20);}else{printf("mmap failed\n");}while(1){sleep(1);}return 0;
}

Makefile

KERNEL_DIR = /home/me/Kernel_Uboot/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientekall:make -C $(KERNEL_DIR) M=`pwd` modules$(CROSS_COMPILE)gcc mmap_read.c -o mmap_read$(CROSS_COMPILE)gcc mmap_write.c -o mmap_writeclean:make -C $(KERNEL_DIR) M=`pwd` modules cleanobj-m += myfb.o

当读和写的进程内存映射地址的偏移都为0时,读进程能把写进程写入的数据读出
在这里插入图片描述
当写进程内存映射地址偏移为0,读进程内存映射地址**偏移为2(单位页)**时,读进程读出数据为空
在这里插入图片描述

PS:注意到读写进程的pfn_start相同,这个值是映射的物理内存地址,vm->vm_pgoff 是偏移(单位页,一页=4K(4096))

但是两个进程映射的虚拟地址结果不一定相同,虚拟地址是进程自己独有的,这点很容易理解。


1. 查看虚拟内存分布

查看读写进程的pid
在这里插入图片描述
写进程的虚拟内存分布
在这里插入图片描述

读进程的虚拟内存分布
在这里插入图片描述

1.1 分析虚拟内存映射部分

以读进程为例,/dev/myfb所在行即是内存映射的部分

76ffa000: vm->vm_start 的值

76ffb000: vm->vm_end 的值

rw-s: 表示的是 vm->vm_flags,"rw"表示可读可写,"s"表示 share共享,"p"表示 private 私有

00000000: 表示偏移量,即 vm->vm_pgoff(单位页,此处的偏移量单位是字节,需要做一下换算)

00:06 : 表示主次设备号

2564: 表示 inode 值

/dev/myfb: 表示设备节点名

1.2 关于偏移量

将读进程中mmap函数最后一个参数改为2*4096(2页)后,进程的虚拟内存映射部分的地址分布如下。

可以看到偏移量为 00002000,即 2*4096字节 = 2页 = 8K

偏移量指的是mmap最后一个参数、同样也是vm->vm_pgoff(单位页),指的是映射时在文件的物理内存上的偏移,只映射了文件的部分内容,单位是页4K
在这里插入图片描述


2. remap_pfn_range函数
2.1 remap_pfn_range函数原型
/*** remap_pfn_range - remap kernel memory to userspace* @vma: user vma to map to* @addr: target user address to start at* @pfn: physical address of kernel memory* @size: size of map area* @prot: page protection flags for this mapping**  Note: this is only safe if the mm semaphore is held when called.*/
int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,unsigned long pfn, unsigned long size, pgprot_t prot)
参数含义
vm虚拟内存区域描述符,用于表示映射的虚拟内存区域
addr映射的虚拟内存区域的首地址
pfn物理页帧号
size映射区域的大小
prot物理页面的操作属性,例如读/写/执行权限
2.2 remap_pfn_range函数使用

这里主要搞懂 myfb.c 驱动代码中的 remap_pfn_range 中的如下代码

unsigned long pfn_start = (virt_to_phys(buff) >> PAGE_SHIFT);   res = remap_pfn_range(vm, vm->vm_start, pfn_start + vm->vm_pgoff,   //在物理页帧号上加上偏移vm->vm_end - vm->vm_start, vm->vm_page_prot);
  • vm: 调用mmap时内核自动生成的VMA(虚拟内存描述符)
  • vm->vm_start: 该VMA的起始地址
  • vm->_end: 该VMA的结束地址
  • virt_to_phys: 将虚拟地址转成物理地址
  • PAGE_SHIFT: 宏,值为12,1<<PAGE_SHIFT表示4096,即4K,一页的大小
  • vm->vm_pgoff: 指的是映射时在文件的物理内存上的偏移,只映射了文件的部分内容,单位是页(4K)
  • vm->vm_page_prot: 该虚拟内存的访问权限,由mmap的参数决定,例如可读可写,共享等

相关文章:

mmap底层驱动实现(remap_pfn_range函数)

mmap底层驱动实现 myfb.c&#xff08;申请了128K空间&#xff09; #include <linux/init.h> #include <linux/tty.h> #include <linux/device.h> #include <linux/export.h> #include <linux/types.h> #include <linux/module.h> #inclu…...

品牌如何查窜货

当渠道中的产品出现不按规定区域销售时&#xff0c;这种行为就叫做窜货&#xff0c;窜货不仅会扰乱渠道的健康发展&#xff0c;损害经销商的利益&#xff0c;同时会滋生低价、假货的发生&#xff0c;有效的管控窜货&#xff0c;需要品牌先将窜货链店铺找出来&#xff0c;才能进…...

Java基于SpringBoot的车辆充电桩

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,Csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 文章目录 1、效果演示效果图 技术栈2、 前言介绍&#xff08;完整源码请私聊&#xff09;3、主要技术3.4.1…...

【ARM】(1)架构简介

前言 ARM既可以认为是一个公司的名字&#xff0c;也可以认为是对一类微处理器的通称&#xff0c;还可以认为是一种技术的名字。 ARM公司是专门从事基于RISC技术芯片设计开发的公司&#xff0c;作为知识产权&#xff08;IP&#xff09;供应商&#xff0c;本身不直接从事芯片生产…...

企业完善质量、环境、健康安全三体系认证的作用及其意义!

一、ISO三体系标准作用 ISO9001&#xff1a;质量管理体系&#xff0c;专门针对企业的质量管理&#xff0c;投标首选&#xff0c;很多大客户要求企业必备这项。 ISO14001&#xff1a;环境管理体系&#xff0c;针对企业的生产环境&#xff0c;排污&#xff0c;节能环保&#xf…...

<HarmonyOS第一课>运行Hello World——闯关习题及答案

判断题 1.DevEco Studio是开发HarmonyOS应用的一站式集成开发环境。&#xff08; 对 &#xff09; 2.main_pages.json存放页面page路径配置信息。&#xff08; 对 &#xff09; 单选题 1.在stage模型中&#xff0c;下列配置文件属于AppScope文件夹的是&#xff1f;&#xff…...

NLP 02 RNN

一、RNN RNN(Recurrent Neural Network),中文称作循环神经网络它一般以序列数据为输入通过网络内部的结构设计有效捕捉序列之间的关系特征,一般也是以序列形式进行输出。 传统神经网络(包括CNN)&#xff0c;输入和输出都是互相独立的。但有些任务&#xff0c;后续的输出和之前…...

@PostConstruct注解

PostConstruct注解 PostConstruct注解是javax.annotation包下的一个注解&#xff0c;用于标记一个方法&#xff0c;在构造函数执行之后&#xff0c;依赖注入(如Autowired&#xff0c;意味着在方法内部可以安全地使用依赖注入的成员变量&#xff0c;而不会出现空指针异常&#…...

拓世AI|中秋节营销攻略,创意文案和海报一键生成

秋风意境多诗情&#xff0c;中秋月圆思最浓。又是一年中秋节&#xff0c;作为中国传统的重要节日之一&#xff0c;中秋节的意义早已不再仅仅是一家团圆的节日&#xff0c;更是一场商业盛宴。品牌方们纷纷加入其中&#xff0c;希望能够借助这一节日为自己的产品赢得更多的关注和…...

基于知识蒸馏的两阶段去雨去雪去雾模型学习记录(三)之知识测试阶段与评估模块

去雨去雾去雪算法分为两个阶段&#xff0c;分别是知识收集阶段与知识测试阶段&#xff0c;前面我们已经学习了知识收集阶段&#xff0c;了解到知识阶段的特征迁移模块&#xff08;CKT)与软损失&#xff08;SCRLoss&#xff09;,那么在知识收集阶段的主要重点便是HCRLoss(硬损失…...

代码随想录二刷day46

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣139. 单词拆分二、力扣动态规划&#xff1a;关于多重背包&#xff0c;你该了解这些&#xff01; 前言 提示&#xff1a;以下是本篇文章正文内容&#x…...

计算机竞赛 行人重识别(person reid) - 机器视觉 深度学习 opencv python

文章目录 0 前言1 技术背景2 技术介绍3 重识别技术实现3.1 数据集3.2 Person REID3.2.1 算法原理3.2.2 算法流程图 4 实现效果5 部分代码6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习行人重识别(person reid)系统 该项目…...

在线图片转BASE64、在线BASE64转图片

图片转BASE64、BASE64转图片...

什么是RPA?一文了解RPA发展与进程!

RPA&#xff08;Robotic Process Automation&#xff0c;机器人流程自动化&#xff09;是一种通过软件机器人模拟人类在计算机上执行重复性任务的技术。RPA的核心理念是将规则、过程和数据“机器人化”&#xff0c;从而实现对业务流程的自动化。RPA技术可以显著提高企业的工作效…...

【云备份项目】【Linux】:环境搭建(g++、json库、bundle库、httplib库)

文章目录 1. g 升级到 7.3 版本2. 安装 jsoncpp 库3. 下载 bundle 数据压缩库4. 下载 httplib 库从 Win 传输文件到 Linux解压缩 1. g 升级到 7.3 版本 &#x1f517;链接跳转 2. 安装 jsoncpp 库 &#x1f517;链接跳转 3. 下载 bundle 数据压缩库 安装 git 工具 sudo yum…...

工信部教考中心:什么是《研发效能(DevOps)工程师》认证,拿到证书之后有什么作用!(下篇)丨IDCF

拿到证书有什么用&#xff1f; 提高职业竞争力&#xff1a;通过学习认证培训课程可以提升专业技能&#xff0c;了解项目或产品研发全生命周期的核心原则&#xff0c;掌握端到端的研发效能提升方法与实践&#xff0c;包括组织与协作、产品设计与运营、开发与交付、测试与安全、…...

Linux进程相关管理(ps、top、kill)

目录 一、概念 二、查看进程 1、ps命令查看进程 1&#xff09;ps显示某个时间点的程序运行情况 2&#xff09;查看指定的进程信息 2、top命令查看进程 1&#xff09;信息统计区&#xff1a; 2&#xff09;进程信息区 3&#xff09;交互式命令 三、信号控制进程 四、…...

微服务技术栈-Ribbon负载均衡和Nacos注册中心

文章目录 前言一、Ribbon负载均衡1.LoadBalancerInterceptor&#xff08;负载均衡拦截器&#xff09;2.负载均衡策略IRule 二、Nacos注册中心1.Nacos简介2.搭建Nacos注册中心3.服务分级存储模型4.环境隔离5.Nacos与Eureka的区别 总结 前言 在上面那个文章中介绍了微服务架构的…...

知识图谱和大语言模型的共存之道

源自&#xff1a;开放知识图谱 “人工智能技术与咨询” 发布 导 读 01 知识图谱和大语言模型的历史 图1 图2 图3 图4 图5 02 知识图谱和大语言模型作为知识库的优缺点 图6 图7 表1 表2 图8 图9 03 知识图谱和大语言模型双知识平台融合 图10 图11 04 总结与展望 声明:公众号转…...

enum, sizeof, typedef

枚举类型enum enum 是 C 语言中的一种自定义类型enum 值是可以根据需要自定义的整型值第一个定义的 enum 值默认为 0默认情况下的 enum 值在前一个定义值得基础上加 1enum 类型的变量只能取定义时得离散值 void code() {enum Color{GREEN, // 0RED 2, // 2BLUE, …...

(二)激光线扫描-相机标定

1. 何为相机标定? 当相机拍摄照片时,我们看到的图像通常与我们实际看到的不完全相同。这是由相机镜头引起的,而且发生的频率比我们想象的要高。 这种图像的改变就是我们所说的畸变。一般来说,畸变是指直线在图像中出现弯曲或弯曲。 这种畸变我们可以通过相机标定来进行解…...

pytorch 数据载入

在PyTorch中&#xff0c;数据载入是训练深度学习模型的重要一环。 本文将介绍三种常用的数据载入方式&#xff1a;Dataset、DataLoader、以及自定义的数据加载器。 使用 Dataset 载入数据 方法&#xff1a; from torch.utils.data import Datasetclass CustomDataset(Dataset…...

angular 在vscode 下的hello world

Angulai 是google 公司开发的前端开发框架。Angular 使用 typescript 作为编程语言。typescript 是Javascript 的一个超集&#xff0c;提升了某些功能。本文介绍运行我的第一个angular 程序。 前面部分参考&#xff1a; Angular TypeScript Tutorial in Visual Studio Code 一…...

Django、Nginx、uWSGI详解及配置示例

一、Django、Nginx、uWSGI的概念、联系与区别 Django、Nginx 和 uWSGI 都是用于构建和运行 Web 应用程序的软件&#xff0c;这三个软件的概念如下&#xff1a; Django&#xff1a;Django 是一个基于 Python 的开源 Web 框架&#xff0c;它提供了一套完整的工具和组件&#xf…...

王道考研计算机组成原理——计算机硬件的基础知识

计算机组成原理的基本概念 计算机硬件的针脚都是用来传递信息&#xff0c;传递数据用的&#xff1a; 服务程序包含一些调试程序&#xff1a; 计算机硬件的基本组成 控制器通过电信号来协调其他部件的工作&#xff0c;同时负责解析存储器里存放的程序指令&#xff0c;然后指挥…...

[晕事]今天做了件晕事21;设置代理访问网站的时候需注意的问题

今天在家上班&#xff0c;设置好VPN&#xff0c;通过代理来访问公司内部的一个系统浏览器的反应如下&#xff1a; Hmmm… can’t reach this page ***.com refused to connect. 这个返回的错误&#xff0c;非常的具有迷惑性&#xff0c;提示的意思&#xff1a;拒绝链接&#xf…...

Go通过reflect.Value修改值

到目前为止&#xff0c;反射还只是程序中变量的另一种读取方式。然而&#xff0c;在本节中我们将重点讨论如何通过反射机制来修改变量。 回想一下&#xff0c;Go语言中类似x、x.f[1]和*p形式的表达式都可以表示变量&#xff0c;但是其它如x 1和f(2)则不是变量。一个变量就是一…...

【MySql】4- 实践篇(二)

文章目录 1. SQL 语句为什么变“慢”了1.1 什么情况会引发数据库的 flush 过程呢&#xff1f;1.2 四种情况性能分析1.3 InnoDB 刷脏页的控制策略 2. 数据库表的空间回收2.1 innodb_file_per_table参数2.2 数据删除流程2.3 重建表2.4 Online 和 inplace 3. count(*) 语句怎样实现…...

获取多个接口的数据并进行处理,使用Promise.all来等待所有接口请求完成

Promise.all (等待机制) 方法 它调用了多个函数&#xff0c;这些函数返回了Promise对象&#xff0c;每个Promise对象代表了一个异步操作。 然后&#xff0c;使用Promise.all将这多个Promise对象包装成一个新的Promise对象&#xff0c;它会等待所有的Promise都完成&#xff08;或…...

利用C++开发一个迷你的英文单词录入和测试小程序-升级版本

我们现在有了一个本地sqlite3的迷你英文单词小测试工具&#xff0c;需求就跟工作当中一样是不断变更的。这里虚构两个场景&#xff0c;并且一步一步的完成最终升级后的小demo。 场景&#xff1a;数据不依赖本地sqlite3&#xff0c;需要支持远程访问&#xff0c;用目前的restfu…...

求推荐软件毕设代做靠谱网站/网络营销所学课程

说在前面&#xff1a;Gradle中project是非常重要的&#xff0c;所以也会有非常多的API及其可配置的属性&#xff0c;笔者也有许多不了解的&#xff0c;在这只是讲一些开发中比较常用的一些API和属性。但是了解了这些&#xff0c;其它的自己去看&#xff0c;去查资料相信也是可以…...

湛江公司做网站/泰州网站优化公司

基本操作 <1> all(): 查询所有结果<2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象<3> get(**kwargs): 返回与所给筛选条件相匹配的对象&#xff0c;返回结果有且只有一个&#xff0c;如果符合筛选条件的对象超过一…...

安徽省建设厅证件查询/北京知名seo公司精准互联

环境&#xff1a;SQLServer 2008 R2 MyEclipse 6.5 JDK 1.6.24 问题&#xff1a;当使用JPasswordField类接收用户的密码&#xff0c;单击注册按钮无反应&#xff0c;向数据库插入数据时出现不可预期的结果。 如下图红色标识处&#xff08;数据库数据&#xff09;&#xff1…...

网站有多少个/网站需要怎么优化比较好

软件之间沟通的大喇叭&#xff1a;Android四大组件之广播机制前言五、软件之间沟通的大喇叭&#xff1a;Android四大组件之广播机制5.1 广播机制简介5.2 接收系统广播&#xff0c;通过大喇叭听听其它软件的消息5.2.1 基于动态注册广播方式接收系统广播的示例5.2.2 基于静态注册…...

中山网站优化营销/著名营销策划公司

1.背景与大纲 在我们了解了java虚拟机的运行时数据区后&#xff0c;我们大概知道了虚拟机内存的概况&#xff0c;但是我们还是不清楚具体怎么存放的访问的&#xff1b; 接下来&#xff0c;我们将深入探讨HotSport虚拟机在java堆中对象的分配、布局、访问的全过程。 2.对象创建 …...

b2b网站建设优化哪家好/seo北京优化

装饰器系列&#xff1a; [1]. Python装饰器(decorator)系列 — 面向对象以及装饰器 [2]. Python装饰器(decorator)系列 — 编写无参数的装饰器 [3]. Python装饰器(decorator)系列 — 编写带参数的装饰器 功能&#xff1a;使用装饰器可以对已有的函数增加新的功能&#xff0c;避…...