uboot的虚拟地址映射学习

2023-12-16 02:59

本文主要是介绍uboot的虚拟地址映射学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参考资料:

1: 关于ARM地址映射的理解.

2: S5PV210 uboot中的 MMU代码分析.

3: 协处理器CP15介绍—MCR/MRC指令(6).

4.朱老师的课程uboot的2.5.10-2.5.12节

虚拟地址映射
把虚拟地址映射到物理地址。
怎么映射
两者之间的进行转换的话会有一个转换关系,这个转换关系对应的是虚拟地址映射表。

uboot是在进行完BL2的重定位之后,开始虚拟地址映射,然后后面都使用的虚拟地址了。
重定位之后进入after_copy
具体思路可以看注释,并且要结合用到的参考资料,知道一个个转换关系到底是怎样结合起来的。
还有,这里只是一级映射,用了段模式,算是最简单的一种映射方法。

after_copy:#if defined(CONFIG_ENABLE_MMU)
enable_mmu:/* enable domain access */ldr	r5, =0x0000ffffmcr	p15, 0, r5, c3, c0, 0		@load domain access register //mcr 把arm处理器的数据传输到协处理器里面 即把r5的值写到c3里面//c3是协处理器cp15的一个寄存器,控制了ARM处理器16个域的访问权限//ffff即16个1对应16个域的权限。/* Set the TTB register */    ldr	r0, _mmu_table_base		//获取mmu_table(转换表)的基地址ldr	r1, =CFG_PHY_UBOOT_BASE //根据注释算得是0x33e000000ldr	r2, =0xfff00000   		//取bit[31:20]位,也就是高12位bic	r0, r0, r2				//取把这个值的高12位清零orr	r1, r0, r1				//把物理地址和这个经过处理的转换表进行位或运算,组合成一个段地址+条目描述符mcr	p15, 0, r1, c2, c0, 0	//把这个得到的转换关系写到c2寄存器,也就是TTB 转换表里面/* Enable the MMU */		//设置完之后就启动mmu
mmu_on:mrc	p15, 0, r0, c1, c0, 0orr	r0, r0, #1mcr	p15, 0, r0, c1, c0, 0nopnopnopnop
#endif

下面这段代码是在lowlevel_init里面,作用就是建立转换表

	/* form a first-level section entry *///ap是设置权限在 cp15 c2寄存器 bit[10-11]//d是domain域 cp15 c2寄存器 bit[5-8]不管是段模式还是页模式,系统都把4GB空间分为16个域,每个域有相同的权限检查//c bit 3  b bit 2   C/B位是控制位,与本条目(描述符)所在域的Cache和Buffer有关(是否允许本域开启Cache和Buffer)//最后的1<<1设置bit1为1,其实bit[0:1]是设置模式描述符,0b10是段模式的描述符标识.macro FL_SECTION_ENTRY base,ap,d,c,b              //.macro 声明一个宏   	 一个宏名,接受5个参数.word (\base << 20) | (\ap << 10) | \(\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1)
.endm												//.end macro 应该是完成的宏定义标志
.section .mmudata, "a"			//.section.mmudata 这里是链接脚本的mmudata段,后面的"a"不懂.align 14// the following alignment creates the mmu table at address 0x4000. 这句注释感觉不对,不止是不是没改还是我理解不对.globl mmu_table
mmu_table:.set __base,0						//base是<<20位,20-31是段基址的地方,也就设置段基址位0// Access for iRAM.rept 0x100                                  //.rept repeat 伪指令 循环0x100次 转成十进制 256次FL_SECTION_ENTRY __base,3,0,0,0				//每一次循环,段基地址都加1  一段1MB 共256MB.set __base,__base+1.endr										//.endr end repeat 构成一个for循环// Not Allowed							.rept 0x200 - 0x100					 //又循环256次	   但是每次循环里面都置零.word 0x00000000						.endr.set __base,0x200                  //设置段基址位0x200 ap权限还是3 也就是11 cb控制为控制cache和buffer开吧// should be accessed.rept 0x600 - 0x200						//循环1024次FL_SECTION_ENTRY __base,3,0,1,1.set __base,__base+1						//每次段基址+1 一段1M 1024段就1024M 1G.endr.rept 0x800 - 0x600         // 循环512次	   但是都是置0.word 0x00000000.endr.set __base,0x800							//设置段基址0x800// should be accessed.rept 0xb00 - 0x800						    // 0x300 256*3次 一次段+1 768MBFL_SECTION_ENTRY __base,3,0,0,0.set __base,__base+1.endr/*	.rept 0xc00 - 0xb00.word 0x00000000.endr */.set __base,0xB00							//设置段基址 B00.rept 0xc00 - 0xb00					    //0x100 256次  256MBFL_SECTION_ENTRY __base,3,0,0,0.set __base,__base+1.endr// 0xC000_0000映射到0x3000_0000             .set __base,0x300                          //设置段基址0x300//.set __base,0x200// 256MB for SDRAM with cacheable.rept 0xD00 - 0xC00							//从0xc00开始到0xd00一共256次,一次1MB,共256MBFL_SECTION_ENTRY __base,3,0,1,1.set __base,__base+1.endr// access is not allowed.@.rept 0xD00 - 0xC80						//从c80到d00又不给用@.word 0x00000000@.endr.set __base,0xD00									//d00到 10000 循环0x300次 768次 即768M// 1:1 mapping for debugging with non-cacheable.rept 0x1000 - 0xD00FL_SECTION_ENTRY __base,3,0,0,0.set __base,__base+1.endr	

抽取前面两端进行分析讲解,如图所示。
在这里插入图片描述
跟着代码一步步分析最终算出了的长度加起来刚刚好是4G的长度,也就是全映射了。
细心点会发现,0xC8000000到0xD0000000也是设置为不可用的。

结果就完成了转换表的建立。

回顾

DRAM有效范围:
DMC0: 0x30000000-0x3FFFFFFF
DMC1: 0x40000000-0x4FFFFFFF
结论:虚拟地址映射只是把虚拟地址的c0000000开头的256MB映射到了DMC0的30000000开头的256MB物理内存上去了。其他的虚拟地址空间根本没动,还是原样映射的。

思考:为什么配置时将链接地址设置为c3e00000,因为这个地址将来会被映射到33e00000这个物理地址。

之前在主Makefile里面的TEXT_BASE设置为c3e00000,经过映射后就到了33e00000的位置。

这篇关于uboot的虚拟地址映射学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/498862

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

线性代数|机器学习-P36在图中找聚类

文章目录 1. 常见图结构2. 谱聚类 感觉后面几节课的内容跨越太大,需要补充太多的知识点,教授讲得内容跨越较大,一般一节课的内容是书本上的一章节内容,所以看视频比较吃力,需要先预习课本内容后才能够很好的理解教授讲解的知识点。 1. 常见图结构 假设我们有如下图结构: Adjacency Matrix:行和列表示的是节点的位置,A[i,j]表示的第 i 个节点和第 j 个

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件