嵌入式开发(s5pv210)——u-boot中开启mmu(代码片段)

代二毛 代二毛     2023-01-26     567

关键词:

1、MMU介绍

在uboot阶段并不是必须要开启MMU(内存管理单元),在没开启MMU前使用的是物理地址,开启MMU后使用的是虚拟地址。
MMU就是在物理内存和应用程序之间添加了一个层次,专门用来管理内存,这样写应用程序的人就不用关心物理内存的细节。
比如32位的机器理论上最大内存为4G,运行的程序以进程为单位,每个进程都认为自己拥有4G的内存,其实分配给该进程的物理内存肯定是没有4G的,进程的虚拟内存有4G。虚拟内存和物理内存都按照相同大小的划分页,虚拟内存的页和物理内存的页建立映射关系,当程序要访问的页不在内存时就会发生缺页异常,然后将磁盘里的页加载到内存中,如果此时物理内存没有空闲的页则还涉及页面置换。使用虚拟内存的好处:访问控制、内存分配和释放提供方便(比如malloc实际可能不是连续的)、运行超过物理内存大小的程序等。

2、虚拟地址和物理地址的转换

虚拟地址和物理地址的转换是依靠转换表,宏观上理解转换表:整个转换表可以看作是一个int类型的数组,数组中的一个元素就是一个表索引和表项的单元。数组中的元素值就是表项,这个元素的数组下标就是表索引。把虚拟地址按照一定规则进行查表,根据表的内容就可以知道对应的物理地址。映射分为段映射和页映射,这里是按照段映射(1M)进行讲解的,就是把内存按照1M为单位进行划分,4G的内存就分为4096个段,每个段对应一个页表项,每个页表项占4字节,页表总共占16KB。只需要构建好页表然后设置TTB,硬件会自动去查询页表进行转换。

3、开启MMU的步骤

(1)使能域访问,域访问是和MMU的访问控制有关的。
(2)构建虚拟地址转换表,并将转换表的基地址赋值到cp15协处理器的c2;
(3)使能MMU;

4、开启MMU的代码

	#if defined(CONFIG_ENABLE_MMU)
	enable_mmu:
		/* 使能域访问,将cp15的c3寄存器设置成0x0000ffff*/
		ldr	r5, =0x0000ffff
		mcr	p15, 0, r5, c3, c0, 0		@load domain access register

		/* 设置转换表基地址,_mmu_table_base就是转换表的基地址*/
		ldr	r0, _mmu_table_base
		ldr	r1, =CFG_PHY_UBOOT_BASE	//CFG_PHY_UBOOT_BASE是uboot的链接地址
		ldr	r2, =0xfff00000
		bic	r0, r0, r2	//将r0的bit20-bit31清零
		orr	r1, r0, r1	//将r0的值与r1进行或操作,并将结果保存在r1中
		mcr	p15, 0, r1, c2, c0, 0	//将r1的值写到cp15协处理器的c2寄存器中

	mmu_on:
		/* 开启MMU:cp15的c1寄存器的bit0控制MMU的开关。只要将这一个bit置1即可开启MMU。*/
		mrc	p15, 0, r0, c1, c0, 0
		orr	r0, r0, #1
		mcr	p15, 0, r0, c1, c0, 0
	#endif

	#if defined(CONFIG_ENABLE_MMU)
	_mmu_table_base:
		.word mmu_table //mmu_table就是构建虚拟地址映射表
	#endif

5、构建虚拟映射表的代码

	/* form a first-level section entry */
	.macro FL_SECTION_ENTRY base,ap,d,c,b
		.word (\\base << 20) | (\\ap << 10) | \\
			  (\\d << 5) | (1<<4) | (\\c << 3) | (\\b << 2) | (1<<1)
	.endm
	.section .mmudata, "a"
		.align 14
		// the following alignment creates the mmu table at address 0x4000.
		.globl mmu_table
	mmu_table:
		.set __base,0
		// Access for iRAM
		.rept 0x100
		FL_SECTION_ENTRY __base,3,0,0,0
		.set __base,__base+1
		.endr

		// Not Allowed
		.rept 0x200 - 0x100
		.word 0x00000000
		.endr

		.set __base,0x200
		// should be accessed
		.rept 0x600 - 0x200
		FL_SECTION_ENTRY __base,3,0,1,1
		.set __base,__base+1
		.endr

		.rept 0x800 - 0x600
		.word 0x00000000
		.endr

		.set __base,0x800
		// should be accessed
		.rept 0xb00 - 0x800
		FL_SECTION_ENTRY __base,3,0,0,0
		.set __base,__base+1
		.endr

		.set __base,0xB00
		.rept 0xc00 - 0xb00
		FL_SECTION_ENTRY __base,3,0,0,0
		.set __base,__base+1
		.endr

		.set __base,0x300
		.rept 0xD00 - 0xC00
		FL_SECTION_ENTRY __base,3,0,1,1
		.set __base,__base+1
		.endr

		.set __base,0xD00
		.rept 0x1000 - 0xD00
		FL_SECTION_ENTRY __base,3,0,0,0
		.set __base,__base+1
		.endr	

构建页表就是通过多个循环,构建满足特定规则的int型数,因为一个页表项就刚好是4个字节,页表的每个位都有特定含义。
(1)FL_SECTION_ENTRY:这个宏就是用来构建页表项的,具体含义参考一级页表的页表项含义,实际效果就是定义一个特定的word类型数;
(2).rept和.end构成循环语句,比如.rept 0xD00 - 0xC00和.endr,就是循环(0xD00-0xC00)次。

6、一级页表的页表项含义

(1)段基址: 在设计地址映射时,从20bit开始的目的是要映射的物理地址要 1MB 对齐,段基址就是这段1MB 物理地址起始地址的高[31:20]位,每个条目中的描述符的段基址都不一样(以段来说,相差 1MB)。
(2) AP: AP 是用来设置权限的,与 C1 的 R/S 位结合使用。
(3) Domain 域: 不管是段模式还是页模式,系统都把 4GB 空间分为 16 个域,每个域有相同的权限检查(在 C3 设置 ),这里的 Domain 是用来标识本段所在的域
(4) C/B: C/B 位是控制位,与本条目(描述符)所在域的 Cache 和 Buffer 有关(是否允许本域开启 Cache 和 Buffer)
(5) [1:0]=0b10: 表示本描述符是表示段模式(段描述符标识)

7、最终得到的虚拟地址映射表

转换得到的虚拟地址映射表:
	VA					PA					length
	0-10000000			0-10000000			256MB
	10000000-20000000	0					256MB
	20000000-60000000	20000000-60000000	1GB		512-1.5G
	60000000-80000000	0					512MB	1.5G-2G
	80000000-b0000000	80000000-b0000000	768MB	2G-2.75G
	b0000000-c0000000	b0000000-c0000000	256MB	2.75G-3G
	c0000000-d0000000	30000000-40000000	256MB	3G-3.25G
	d-完				d-768MB	3.25G-4G

嵌入式开发(s5pv210)——u-boot中如何确定启动方式(代码片段)

1、嵌入式设备确认启动方式设备确认启动方式分为硬件方式和软件方式,硬件方式是通过芯片某几个引脚的高低电平来决定启动方式;软件方式就是通过代码设置来决定启动方式。(1)硬件方式:比如S5PV210芯片,... 查看详情

嵌入式开发(s5pv210)——u-boot的链接脚本分析(代码片段)

1、脚本内容OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm","elf32-littlearm")/*OUTPUT_FORMAT("elf32-arm","elf32-arm","elf32-arm")*/OUTPUT_ARCH(arm)ENTRY(_s 查看详情

嵌入式开发(s5pv210)——u-boot的顶层mkconfig文件分析(代码片段)

mkconfig文件的调用#第一步:SRCTREE是源码的路径,也就是顶层的目录MKCONFIG :=$(SRCTREE)/mkconfigexportMKCONFIG#第二步:配置#$(@:_config=):作用是将x210_sd_config的_config去掉,得到x210_sdx210_sd_c 查看详情

嵌入式开发(s5pv210)——u-boot的不同来源和目录结构

1、u-boot的不同来源和联系uboot的来源大致有三个途径:uboot官网下载、Soc厂商提供、开发板厂商提供。假设某个厂商推出新的Soc,Soc厂商的工程师会去uboot的官网下载uboot,然后把此款Soc的开发板的uboot移植上去并开源&... 查看详情

嵌入式开发(s5pv210)——u-boot启动过程中三次设置栈(代码片段)

1、多次设置栈的原因无论是汇编代码还是C语言代码,当涉及函数嵌套调用时都需要用栈来保存函数返回地址,所以必须设置栈。多次设置栈的原因是,uboot不同的启动阶段可用的内存空间是不同的。最开始只有IRAM可... 查看详情

嵌入式开发(s5pv210)——u-boot的顶层config.mk分析(代码片段)

1、config.mk的作用config.mk的作用是配置uboot编译的,比如配置交叉编译工具链,链接地址,编译选项,指定头文件路径等,但是config.mk的配置是建立在顶层mkconfig、主Makefile等配置之上的。2、config.mk的调用#loadothe... 查看详情

嵌入式开发(s5pv210)——u-boot的头文件包含问题(代码片段)

前言uboot和kernel的头文件包含比一般的程序更复杂,将头文件的路径用链接来表示,这样的用意是为了程序的可移植性。uboot是高度可移植的,不同的配置和编译指令可以编译出不同Soc和开发板的程序,其中源码是... 查看详情

第一章之s5pv210启动顺序

我所使用的开发板是:友善之臂smart210,cpu为s5pv210.u-boot版本是:u-boot-2012-101,首先在u-boot中配置相对应的开发板的配置文件#makes5p_goni_config2,设事先编译好的交叉编译器放在Makefile中添加上去,打开Makefile在67行补充CROSS_COMPILE?=arm-linux-... 查看详情

嵌入式开发综述

0、嵌入式系统开发流程:   1、S5PV210内部结构图2、S5PV210系统启动三阶段正解     根据S5PV210芯片手册第6章所述S5PV210consistsof64KBROMand96KBSRAMasinternalmemory(意思210芯片有两块片上内存,ROM:64KB,SRAM:96KB),并... 查看详情

嵌入式开发(s5pv210)——adc和触摸屏

1、ADC介绍ADC(analogdigitalconverter)就是AD转换,把模拟量转换为数字量。CPU本身是数字的、离散的,而外部世界却是模拟的、连续的,所以外界的信息是不能直接被计算机进行处理,需要先将模拟量转换为数字量... 查看详情

s5pv210移植minigui3.0.12

...包,在MiniGui官网可以下载http://www.minigui.org/zhcn/【已放在嵌入式软件组资料共享文件夹】---------------- 查看详情

嵌入式开发(s5pv210)——lcd显示器

LCD介绍1.LCD(LiquidCrystalDisplay)俗称液晶,这种材料的一大特点就是在电信号的驱动下液晶分子进行旋转,旋转会影响透光性,不同的透光性会透过不同的颜色的光,于是我们便看到显示屏上五颜六色的画面。2.LCD是... 查看详情

tiny210(s5pv210)移植u-boot(基于2014.4版本号)——移植u-boot.bin(打印串口控制台)

...信息打印。在上节。我们看到调用relocate_code重定位。在u-boot的帮助文档doc/README.arm-relocation中对重定位有说明。u-boot为了生成位置无关码,在链接时指定了-pie选项,这个选项在u-boot-2014.04/arch/arm/config.mk中指定: 查看详情

在s5pv210的开发板上使用串口收发信息

 参考学习教程:周立功嵌入式Linux开发教程-(上册) 材料:首先准备一个安装好Linux的开发板  使用 xshell工具连接开发板 ,winscp工具连接开发板 , 准备一个Ubuntu 32位,装上交叉编译链。。使用下... 查看详情

在s5pv210的开发板上点亮一个led灯

 参考学习教程:周立功嵌入式Linux开发教程-(上册) 材料:首先准备一个安装好Linux的开发板  使用 xshell工具连接开发板 ,winscp工具连接开发板 , 准备一个Ubuntu 32位,装上交叉编译链。。使用下... 查看详情

嵌入式s5pv210的启动流程

S5PV210的启动流程S5PV210上电后执行iROM中的固化代码,即BL0(Bootloader0)。这个代码是厂家出厂前烧写好的,不提供源代码,但提供相应的功能说明,比如进行一些时钟初始化、设备控制器初始化和启动相关... 查看详情

s5pv210|微处理器启动流程(代码片段)

...载到IRAM,然后BL1在IRAM中运行并将BL2加载到SDRAM,BL2加载嵌入式操作系统。BL是BootLoader的简称。S5PV210上电将从IROM处执行固化的启动代码BL0,它对时钟等初始化、对启动设置进行判断,并从启动设备中复制BL1(最大16KB)到IRAM(地... 查看详情

s5pv210启动过程详解(代码片段)

...内存需求量小,而且希望开发尽量简单,适合全部用SRAM嵌入式系统:内存需求量大,而且没有NorFlash等可启动介质PC机:内存需求量大,而且软件复杂,不在乎DRAM的初始化开销,适合全部用 查看详情