【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第四十一章 物理地址与虚拟地址

i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT、4G模块、CAN、RS485等接口一应俱全。H264、VP8视频硬编码,H.264、H.265、VP8、VP9视频硬解码,并提供相关历程,支持8路PDM接口、5路SAI接口、2路Speaker。系统支持Android9.0(支持获取root限)Linux4.14.78+Qt5.10.1、Yocto、Ubuntu20、Debian9系统。适用于智能充电桩,物联网,工业控制,医疗,智能交通等,可用于任何通用工业和物联网应用、

【公众号】迅为电子

【粉丝群】258811263(加群获取驱动文档+例程)


四十一 章 物理地址 虚拟地址

本章导读

本章讲解了在裸机程序中操作寄存器方式和Linux系统中使用MMU。讲解了在Linux系统中物理地址到虚拟地址的转换。

本章内容对应视频讲解链接(在线观看):

linux物理地址到虚拟地址映射 → https://www.bilibili.com/video/BV1Vy4y1B7ta?p=12

目前,大多数嵌入式微控制器(如ARM、PowerPC等)中并不提供I/O空间,而仅存在内存空间。内

存空间可以直接通过地址、指针来访问,程序及在程序运行中使用的变量和其他数据都存在于内存空间中。

内存地址可以直接由C语言指针操作,例如,操作一个寄存器,可以定义一个指针来操作寄存器,如下所示:

unsighted int *p = 0x12345678;

*p=0x87654321;

以上程序的意义是在绝对地址0x12345678(ARM、PowerPC)中写入0x87654321。

高性能处理器一般会提供一个内存管理单元(MMU),该单元辅助操作系统进行内存管理,提供虚

拟地址和物理地址的映射、内存访问权限保护和Cache缓存控制等硬件支持。操作系统内核借助MMU可以

让用户感觉到程序好像可以使用非常大的内存空间,从而使得编程人员在写程序时不用考虑计算机中物理

内存的实际容量。

MMU具有虚拟地址和物理地址转换、内存访问权限保护等功能,这将使得Linux操作系统能单独为系

统的每个用户进程分配独立的内存空间并保证用户空间不能访问内核空间的地址,为操作系统的虚拟内存

管理模块提供硬件基础。上层应用看到的内存都是虚拟内存,应用就不能直接访问硬件,所以这样就保证了系统安全。

对于包含MMU的处理器而言,Linux系统提供了复杂的存储管理系统,使得进程所能访问的内存达到

4GB。在Linux系统中,进程的4GB内存空间被分为两个部分------用户空间与内核空间。用户空间的地址一

般分布为0~3GB(即PAGE_OFFSET,在0x86中它等于0xC0000000),这样,剩下的3~4GB为内核空间,如下图所示。用户进程通常只能访问用户空间的虚拟地址,不能访问内核空间的虚拟地址。用户进程只有通过系统调用(代表用户进程在内核态执行)等方式才可以访问到内核空间。

每个进程的用户空间都是完全独立、互不相干的,用户进程各自有不同的页表。而内核空间是由内核

负责映射,它并不会跟着进程改变,是固定的。内核空间的虚拟地址到物理地址映射是被所有进程共享的,内核的虚拟空间独立于其他程序。

MMU非常复杂,那么我们如何完成物理地址到虚拟地址的转换呢?内核给我们提供了相关的函数,我们先来了解下这些函数。函数定义在内核源码目录include/asm-generic/io.h

cpp 复制代码
ioremap: 把物理地址转换成虚拟地址
iounmap: 释放掉ioremap映射的地址

|----------------------|-----------------------------------------------------------------------|
| 函数 | static inline void __iomem *ioremap(phys_addr_t offset, size_t size) |
| 参数phys_addr_t offset | 映射物理地址的起始地址 |
| 参数size_t size | 要映射多大的内存空间 |
| 返回值 | 成功返回虚拟地址的首地址失败返回NULL。 |
| 功能 | 把物理地址转换成虚拟地址 |

|---------------|-------------------------------------------------|
| 函数 | static inline void iounmap(void __iomem *addr) |
| 参数*addr | 要取消映射的虚拟地址的首地址 |
| 参数size_t size | 要映射多大的内存空间 |
| 功能 | 释放掉ioremap映射的地址 |

注意: 物理地址只能被映射一次,多次映射会失败。如何查看哪些物理地址被映射过了呢?可以使用以下命令来查看。

cat /proc/iomem

相关推荐
Mr_Orangechen12 分钟前
Linux 下使用 VS Code 远程 GDB 调试 ARM 程序
linux·运维·arm开发
悟空胆好小23 分钟前
分音塔科技(BABEL Technology) 的公司背景、股权构成、产品类型及技术能力的全方位解读
网络·人工智能·科技·嵌入式硬件
lilian1291 小时前
linux系统mysql性能优化
linux·运维·mysql
Meraki.Zhang1 小时前
【STM32实践篇】:最小系统组成
stm32·单片机·嵌入式硬件·最小系统
共享家95272 小时前
linux_线程概念
linux·开发语言·jvm
乌云暮年2 小时前
Linux常用命令
linux·服务器·ssh·php
weixin_516023072 小时前
Geant4 安装---Ubuntu
linux·运维·ubuntu
稀液蟹-plus2 小时前
zynq-PS篇——bperez77中DMA驱动注意事项
linux·fpga
Do vis8243 小时前
STM32第二十一天定时器TIM
stm32·单片机·嵌入式硬件
brave_zhao3 小时前
JavaBeanUtils javaBean转map, 实体类转map,实体集合转List<Map>
linux·windows·python