Linux io内存存在的意义~

今天是母亲节,首先祝各位读者的母亲节日快乐,祝你们的母亲年轻健康。母亲节是一个亘古的话题,我本来想写个文章,但是想起来这周就一个周末,要花点时间陪下家人,昨天我们老大开会,特别说了,有时间多陪陪家人,我脑子一转,今天就一直陪着楠哥各种玩。

晚上回来看看笔记,写了这个技术文章,ioremap是一个属于被遗忘的技术知识点,可能我做Android 驱动没用上,也就疏忽了,像内核通知链一些冷门的技术,还偶尔用一下。


内存管理是一个经久不衰的话题,从段式管理到页式管理已经过去很久了,页式管理也已经有了好长好长时间了,使用Linux内核的操作系统已经从更新了很多不同的版本。

不同的CPU体系对外设IO端口物理地址的编址方式也不同,分为I/O映射方式(I/O-mapped)和内存映射方式(Memory-mapped)。

以X86为例:X86为外设专门实现有单独的地址空间,可以称为「I/O地址空间」或「I/O端口空间」,这个是独立与CPU和RAM物理地址空间,所有外设的IO端口均在这一空间。CPU通过设立专门的IN和OUT指令来访问这一空间中的地址单元(即I/O端口),这就是所谓的“I/O映射方式”(I/O-mapped)。和RAM物理地址空间相比,I/O地址空间通常都比较小,如x86 CPU的I/O空间就只有64KB(0-0xffff)。这是「I/O映射方式」的一个主要缺点,你可以通过cat /proc/ioports去查看,IO port空间的地址资源分配情况是以树状结构显示。这个源于x86平台的设计思想,目前基本不用了,获取这些资源的函数接口如request_region和ioremap。

像用户空间一样,内核也是通过页表访问内存,很多人对页表理解不是很透彻,你要是说他复杂也是非常复杂,但是你说要是简单也很简单,可以理解成一个图书的目录,有了这个目录,就可以知道什么内存地址存放了什么东西,以后要是想存新的东西进去,就在原来的目录表里面进行更新。

但是我们使用的外设,比如是一个光感传感器,我们需要控制这个光感传感器,那就需要读写这个光感传感器的I2C寄存器,如果内核代码需要像访问内存一样来访问这个光感设备呢?我们这时候就需要首先设置一个适当的内核页表映射

这时候我们就需要使用 ioremap()这个函数,经过这个函数还衍生了其他很多变种函数,我不知道为什么要用变种这个词,如果有其他词语可以留言一起讨论下,毕竟一次好的词语可以加深我们的印象。

具体可以看代码arch/arm/mm/ioremap.c 里面有很多相近似的函数。函数参数含义

// 功能:将物理地址映射为虚拟地址
// 参数1:需要映射的物理地址
// 参数2:需要映射的地址长度
// 返回值:该函数返回映射后的内核虚拟地址(3G-4G). 接着便可以通过读写该返回的内核虚拟地址去访问之这段I/O内存资源。

简单的实例代码

void led_on(void)
{void *reg_base;unsigned int temp; reg_base = ioremap(0x1212, 4);temp = __raw_readl(reg_base); temp &= ~(0xff<<12);temp |= (0x11<<12);__raw_writel(temp, reg_base);
}

#但是内核没几个地方用这个函数

我在内核里面搜了下,这个函数在内核里面并没有几个地方用到的。特别是我们最近做MTK方案和RK方案,里面的触摸屏驱动下面没使用到。但是音频platform部分却还有使用的地方。

用了一个新的转换方式

 /* ioremap to BT HW register base address */BTSYS_PKV_BASE_ADDRESS = (void *)btsys_pkv_physical_base;BTSYS_SRAM_BANK2_BASE_ADDRESS = (void *)btsys_sram_bank2_physical_base;bt_hw_REG_PACKET_R = BTSYS_PKV_BASE_ADDRESS + cvsd_mcu_read_offset;bt_hw_REG_PACKET_W = BTSYS_PKV_BASE_ADDRESS + cvsd_mcu_write_offset;bt_hw_REG_CONTROL = BTSYS_PKV_BASE_ADDRESS + cvsd_packet_indicator;pr_debug("[BTCVSD probe] BTSYS_PKV_BASE_ADDRESS = %p BTSYS_SRAM_BANK2_BASE_ADDRESS = %p\n",BTSYS_PKV_BASE_ADDRESS, BTSYS_SRAM_BANK2_BASE_ADDRESS);return snd_soc_register_platform(&pdev->dev, &mtk_btcvsd_rx_soc_platform);/*使用*/kal_int32 i;kal_uint16 pv;kal_uint8 *pSrc;kal_uint8 *pPacketBuf;unsigned long flags;unsigned long connsys_addr_rx, ap_addr_rx;LOGBT("%s(+) btsco.pRX->iPacket_w=%d\n", __func__, btsco.pRX->iPacket_w);connsys_addr_rx = *bt_hw_REG_PACKET_R;ap_addr_rx = (unsigned long)BTSYS_SRAM_BANK2_BASE_ADDRESS + (connsys_addr_rx & 0xFFFF);LOGBT("%s connsys_addr_rx=0x%lx,ap_addr_rx=0x%lx\n",__func__, connsys_addr_rx, ap_addr_rx);pSrc = (kal_uint8 *)ap_addr_rx;LOGBT("%s uPacketLength=%d,uPacketNumber=%d, btsco.uRXState=%d\n",__func__, uPacketLength, uPacketNumber, btsco.uRXState);AudDrv_BTCVSD_DataTransfer(BT_SCO_DIRECT_BT2ARM, pSrc, btsco.pRX->TempPacketBuf,uPacketLength, uPacketNumber, btsco.uRXState);LOGBT("%s AudDrv_BTCVSD_DataTransfer DONE!!!,uControl=0x%x,uLen=%d\n", __func__, uControl, uLen);

#查看系统当前的内存映射

/proc/iomem这个文件记录的是物理地址的分配情况,记得要查看需要使用root权限。这些地址范围是通过 requset_mem_region 函数申请得到的。

weiqifa0@weiqifa-System-Product-Name:~$ sudo cat /proc/iomem
[sudo] password for weiqifa0:
00000000-00000fff : Reserved
00001000-00057fff : System RAM
00058000-00058fff : Reserved
00059000-0009efff : System RAM
0009f000-000fffff : Reserved000a0000-000bffff : PCI Bus 0000:00000c0000-000cffff : Video ROM000f0000-000fffff : System ROM
00100000-b77eefff : System RAM
b77ef000-b7828fff : ACPI Tables
b7829000-b7bc9fff : System RAM
b7bca000-b7bcafff : ACPI Non-volatile Storage
b7bcb000-b7bcbfff : Reserved
b7bcc000-c492efff : System RAM
c492f000-c61b9fff : Reserved
c61ba000-c61cefff : ACPI Tables
c61cf000-c62ccfff : System RAM
c62cd000-c65f4fff : ACPI Non-volatile Storage
c65f5000-c7795fff : Reserved
c7796000-c77fefff : Unknown E820 type
c77ff000-c77fffff : System RAM
c7800000-c7ffffff : Reserved
c8000000-f7ffffff : PCI Bus 0000:00c8000000-c81fffff : PCI Bus 0000:05c8200000-c83fffff : PCI Bus 0000:05e0000000-efffffff : PCI Bus 0000:01e0000000-efffffff : 0000:01:00.0

ioports主要显示IO端口的地址范围,使用request_region( )分配I/O端口地址范围会显示在这里。

weiqifa0@weiqifa-System-Product-Name:~$ sudo cat /proc/ioports
0000-0cf7 : PCI Bus 0000:000000-001f : dma10020-0021 : pic10040-0043 : timer00050-0053 : timer10060-0060 : keyboard0064-0064 : keyboard0070-0077 : rtc00080-008f : dma page reg00a0-00a1 : pic200c0-00df : dma200f0-00ff : fpu00f0-00f0 : PNP0C04:000290-029f : pnp 00:0003f8-03ff : serial0680-069f : pnp 00:020800-087f : pnp 00:03
0cf8-0cff : PCI conf1
0d00-ffff : PCI Bus 0000:00164e-164f : pnp 00:021800-18fe : pnp 00:021800-1803 : ACPI PM1a_EVT_BLK1804-1805 : ACPI PM1a_CNT_BLK1808-180b : ACPI PM_TMR1850-1850 : ACPI PM2_CNT_BLK1854-1857 : pnp 00:051880-189f : ACPI GPE0_BLK2000-2fff : PCI Bus 0000:05d000-dfff : PCI Bus 0000:04d000-d0ff : 0000:04:00.0e000-efff : PCI Bus 0000:01e000-e0ff : 0000:01:00.0f000-f01f : 0000:00:1f.4f020-f03f : 0000:00:17.0f020-f03f : ahcif040-f043 : 0000:00:17.0f040-f043 : ahcif050-f057 : 0000:00:17.0f050-f057 : ahcife00-fefe : pnp 00:08ffff-ffff : pnp 00:02ffff-ffff : pnp 00:02ffff-ffff : pnp 00:02
weiqifa0@weiqifa-System-Product-Name:~$

#总结

ioremap 这些曾经用起来很不错,或者说是设计者设计的时候,觉得很不错的东西,现在突然被遗忘,我认为很大程度是因为设计的时候允许的地址范围太小,也就是因为太小,要加新的东西总是畏首畏尾。

  回复「 篮球的大肚子」进入技术群聊

回复「1024」获取1000G学习资料

PS:想加入技术群的同学,加了我好友后,就给我发「篮球的大肚子」这句话,有可能机器人打瞌睡,可以多发几次,不要发与技术无关的消息或者推广。

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

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

相关文章

imx6 配置串口波特率_RS232串口多机通信

一、基本原理1、主从多机通信拓扑图2、主从多机通信的具体过程 1)使所有的从机的SM2位置1&#xff0c;以便接收主机发来的地址&#xff1b;2)主机发出一帧地址信息&#xff0c;其中包括8位需要与之通信的从机地址&#xff0c;第9位为1&#xff1b;3)所有从机接收到地址帧后&…

android设置访问internet权限

如果在app中访问网络&#xff0c;提示internet permission denied&#xff0c;即是没有设置访问网络的权限 在AndroidManifest.xml文件中添加如下一行即可 <uses-permission android:name"android.permission.INTERNET" />转载于:https://www.cnblogs.com/Awan…

一个故事讲完CPU的工作原理

上二年级的小明正坐在教室里。现在是数学课&#xff0c;下午第一节&#xff0c;窗外的蝉鸣、缓缓旋转的吊扇让同学们昏昏欲睡。此时&#xff0c;刘老师在黑板上写下一个问题&#xff1a;6324 244675 &#xff1f;小明抬头看了一眼&#xff0c;觉得这两个数字挺眼熟。他昨天翘…

axure弹窗关闭_干货来袭,Axure插入图标的几种办法

前言在日常绘制原型的时候&#xff0c;经常会需要插入相应的图标&#xff08;icon&#xff09;到Axure中&#xff0c;但是看似好像很简单的事情也给蛮多小伙伴造成了困扰。现在很多开发团队都会用一些比较常见的前端框架来搭建后台管理系统&#xff0c;例如常见的Element-UI&am…

用指针实现高低位倒序,疯了吧

昨晚在微信群看到一个读者发的面试题目&#xff0c;从网上截图出来的&#xff0c;我百思不得其解&#xff0c;题目如图。幸好&#xff0c;我学过栈栈&#xff0c;C语言实现然后我写了个小程序第一个方法比较笨&#xff0c;当我写完自己的代码后&#xff0c;看到有同学发了自己的…

部署nexus服务

一、安装和启动 官网下载nexus-2.12安装包&#xff0c;地址&#xff1a;https://sonatype-download.global.ssl.fastly.net/nexus/oss/nexus-2.12.0-01-bundle.tar.gz 此版本需要预先安装jdk1.7 解压后&#xff0c;用命令【./bin/nexus start】来启动 nexus有如下一些控制命令&…

天然气表怎么看多少方_上海考大学难度怎么样?看2019上海高考“成绩分布表”和“本科分数线”就知道了!...

参加高考的同学和家长们注意了~上海市教育考试院近日发布本市普通高等学校秋季招生本科各批次录取控制分数线和成绩分布表。艺术类、体育类本科文化控制分数线也同步公布。&#xff08;鲁申君注&#xff1a;上海2019年高考本科总分660&#xff0c;专科总分450&#xff0c;不分文…

关于Linux内核代码不使用typedef的讨论?

C语言关键字 -&#xff08;typedef关键字&#xff09;typedef有点像火隐忍者里面的万花筒写轮眼&#xff0c;用起来非常炫酷有型&#xff0c;使你的代码更加简短&#xff0c;让你穿上你亲妈都认不出你的马甲…比如这样一段代码typedef struct point{int x, y;} Points;Points f…

基于深度学习模型的花卉图像分类代码_华为不止有鸿蒙!教你快速入门华为免编程深度学习神器ModelArts...

引言&#xff1a;本文介绍利用华为ModelArts进行深度学习的图像分类任务&#xff0c;不用一行代码。今年8月9日&#xff0c;在华为史上规模最大的开发者大会上&#xff0c;华为正式发布全球首个基于微内核的全场景分布式OS——鸿蒙操作系统(HarmonyOS)。但你知道吗&#xff1f;…

洛谷P3405 [USACO16DEC]Cities and States省市

P3405 [USACO16DEC]Cities and States省市 题目描述 To keep his cows intellectually stimulated, Farmer John has placed a large map of the USA on the wall of his barn. Since the cows spend many hours in the barn staring at this map, they start to notice severa…

天线的原理

关注、星标公众号&#xff0c;不错过精彩内容来源&#xff1a;中兴文档小时候家里的收音机、电视机&#xff0c;都带着可以灵活转动拉伸的杆子&#xff0c;大家一定对这个可以转来转去的杆子记忆犹新&#xff0c;或许也好奇的发现这个杆子的长度与方向和收音机、电视的接收效果…

2d 蓝图_“蓝图”卷积--对深度可分离卷积的再思考

论文&#xff1a;Rethinking Depthwise Separable Convolutions: How Intra-Kernel Correlations Lead to Improved MobileNetshttps://arxiv.org/pdf/2003.13549.pdf​arxiv.org代码地址&#xff1a;zeiss-microscopy/BSConv​github.com一、背景一些轻量级的网络&#xff0c;…

Node.js 得到当前目录下文件修改文件名

博客园第一篇,平时都用 .net ,现在 node.js 比较火&#xff0c;就用它做一些小工具&#xff0c;比较方便 Node.js 得到当前目录下文件修改文件名,把 .txt 修改为.md var fs require(fs); var fileDirectory __dirname if (fs.existsSync(fileDirectory)) {fs.readdir(fileDir…

原来你也在写公众号

现在凌晨1点&#xff0c;我睡不着&#xff0c;因为今天打球了&#xff0c;每次打球回来我总是睡得很奇怪&#xff0c;奇怪有时候打球回来一躺下就睡着了&#xff0c;有时候打球回来就会习惯性失眠。脑海里总是浮现各种打球的进球动作&#xff0c;然后各种幻想&#xff0c;再加上…

中的数组怎么转成结构体_PLC知识,什么是数组和结构体?

今天给大家介绍一下什么是数组&#xff0c;什么是结构体&#xff0c;关于数组我们会介绍数组的定义、它的使用方法&#xff0c;关于结构体我们会介绍结构体的使用、怎么去建立一个结构体等知识&#xff0c;之前也是有部分学员有问过这些问题的&#xff0c;那么都一块儿给大家讲…

MMU那些事儿

最近在重新看这部分知识点&#xff0c;内存管理和进程调度应该是Linux下最核心的两个东西&#xff0c;不管你做得多牛逼了&#xff0c;这两点拿出来讨论&#xff0c;总是会让人眼前一亮&#xff0c;或者是可以讨论很久很久&#xff0c;这篇文章&#xff0c;读完后可能也可以让大…

51Nod 1530 稳定方块

瓦西亚和皮台亚摆放了m个方块。方块被编号为0到m-1(每个号码出现恰好一次)。现在建立一个座标系OX表示地面&#xff0c;OY的方向是竖直向上的。每一方块的左下角有一个座标而且是整点座标。 摆放好的方块一定要是稳定的。稳定的含意是每一个不在地面上的方块在他的下面至少有一…

C语言、嵌入式中几个非常实用的宏技巧

宏打印函数 在我们的嵌入式开发中&#xff0c;使用printf打印一些信息是一种常用的调试手段。但是&#xff0c;在打印的信息量比较多的时候&#xff0c;就比较难知道哪些信息在哪个函数里进行打印。特别是对于异常情况的打印&#xff0c;我们需要快速定位到异常情况的位置。这时…

canvas 多次画图效果_canvas练习之终极的奔跑小人

这次做一个终极的练习&#xff0c;先看一下最后的效果。一个不停奔跑的小人&#xff0c;点击鼠标后会让他跑到目的地&#xff0c;并且呈现不同的角度。下面来看一下如何一步步来实现它的。准备网上下载了一张图片&#xff0c;其中包含了小人面向不同角度奔跑的各个分解动作。新…

loadrunner11安装,提示少了Microsoft Visual c++2005 sp1运行时组件解决办法

解决方法&#xff1a;1、进入loadrunner-11\Additional Components\IDE Add-Ins\MS Visual Studio .NET2、安装&#xff1a;LRVS2005IDEAddInSetup.exe3、再安装loadrunner破解方法&#xff1a;1、把loadrunner相关程序全部退出&#xff1b;2、把lm70.dll、mlr5lprg.dll放到安装…