三种地址介绍
写驱动是为了操作IO口,实现自己的wiringpi库,跟硬件打交道。
首先要理解以下3个地址的概念:
4.1 总线地址
通俗来说:cpu能够访问的内存范围
现象:电脑装了32位(bit)的系统,明明内存条有8G,却只能识别3.8G左右,这是因为32位仅能表示/访问232=4,294,967,296bit=4,194,304Kb=4096Mb=4G左右。只有装了64位的,才能够识别到8G。32位、64位是计算机CPU一次处理数据能力的大小。
树莓派装载32位操作系统,寻址自然是4G。
树莓派的内存
cat /proc/meminfo
大概是927M
4.2 物理地址
硬件实际地址或绝对地址,就是硬盘上的排列地址
4.3 虚拟地址
又叫逻辑地址(基于算法的地址,软件层面的地址,是假地址)便称为虚拟地址
虚拟地址的作用:
以树莓派为例,总线可以访问4G,物理地址只有1G,但需要运行的程序大于1G,如果把程序全部都加载到内存是不可取的。物理地址数据的运行真正是拿虚拟地址来操作的,虚拟地址可以比1G大,总线地址(CPU能访问的地址范围)能看到4个G,就可以把1个G的物理地址映射成4个G的虚拟地址。当物理地址不能满足程序运行空间需求时,如果没有虚拟地址,程序就不能正常运行。单片机51和STM32如果程序过大,是禁止你烧写的,而在Linux系统环境下是可以的。
树莓派3b的cpu型号是BCM2835,它是ARM-cotexA53架构
cat /proc/cpuinfo
4.4 MMU内存管理单元
地址框图
可以看到总线地址为FF FF FF FF,即为4G(上面提到的232=4,294,967,296bit);
对ARM的物理地址来说:只有4000000,即为1G(通过cat /proc/meminfo,查看到MEMTotal是1G);
虚拟地址也是FFFFFFFF,即为4G;
内核的页表映射
物理地址的1M通过映射成为4M的虚拟地址(我们写的所有的代码都是在操控虚拟地址,都是假的),这中间有个设计的算法叫页表。
这个表决定了这个4M被映射到虚拟内存的哪一个段,通过MMU进行管理。单片机和ARM处理器的区别就是ARM有MMU(内存管理单元)和CACHE(高速缓存),如下图所示:
如果想要更多地了解Linux对内存的管理,推荐书《unix设计与实现》,类似内核设计文档,讲的是内核设计的思路,讲代码讲的不多。