博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
compressed/head.s __setup_mmu
阅读量:2443 次
发布时间:2019-05-10

本文共 3720 字,大约阅读时间需要 12 分钟。

 

__setup_mmu:	sub	r3, r4, #16384		@ Page directory size,r3 = 0x20004000		bic	r3, r3, #0xff		@ Align the pointer		bic	r3, r3, #0x3f00@ 这里r4中存放着内核执行地址,将16K的一级页表放在这个内核执行地址下面的16K空间里,@ 上面通过 sub  r3, r4, #16384 获得16K空间后,@ 又将页表的起始地址进行16K对齐放在r3中。即ttb的低14位清零。/* * Initialise the page tables, turning on the cacheable and bufferable * bits for the RAM area only. */		mov	r0, r3			@ r0 = 0x20004000 		mov	r9, r0, lsr #18		@ r9 = 0x2000		mov	r9, r9, lsl #18		@ start of RAM,r9 = 0x20000000,先>>18,后<<18,就是256K对齐		add	r10, r9, #0x10000000	@ a reasonable RAM size,r10 = 0x30000000,0x10000000==256M@ 上面这几行把一级页表的起始地址保存在r0中,并通过r0获得一个ram起始地址(256K对齐),@ 并从这个起始地址开始的256M ram空间对应的描述符的C和B位均置”1”, @ r9和r10中存放了这段内存的起始地址和结束地址。 		mov	r1, #0x12		@ XN|U + section mapping@ 一级描述符的bit[1:0]为10,表示这是一个section描述符。@ bit[4]为1, @ 此时bit[8:5]均为0,选择了D0域。   		orr	r1, r1, #3 << 10	@ AP=11,r1 = 0xC12@ 一级描述符的AP(access permission bits) bit[11:10]为11, @ 即all access types permitted in both modes @ bit[31:20]为physical address,为0		add	r2, r3, #16384		@ r2 = 0x20008000@ 一级描述符表(页表)的结束地址存放在r2中。1:		cmp	r1, r9			@ if virt > start of RAM		cmphs	r10, r1			@   && end of RAM > virt		bic	r1, r1, #0x1c		@ clear XN|U + C + B		orrlo	r1, r1, #0x10		@ Set XN|U for non-RAM		orrhs	r1, r1, r6		@ set RAM section settings		str	r1, [r0], #4		@ 1:1 mapping		add	r1, r1, #1048576@ == 0x100000 = 1M 		teq	r0, r2  				@ r0==r2时,不在jump 1处执行,此时r1=4G=0		bne	1b/* case 1:1:		cmp	r1, r9			@ if virt > start of RAM		cmphs	r10, r1			@   && end of RAM > virt		bic	r1, r1, #0x1c		@ clear XN|U + C + B		orrlo	r1, r1, #0x10		@ Set XN|U for non-RAM*//* case 2:1:		cmp	r1, r9			@ if virt > start of RAM		bic	r1, r1, #0x1c		@ clear XN|U + C + B		orrlo	r1, r1, #0x10		@ Set XN|U for non-RAM*//* case 3:1:		cmp	r1, r9			@ if virt > start of RAM		cmphs	r10, r1			@   && end of RAM > virt		bic	r1, r1, #0x1c		@ clear XN|U + C + B		orrhs	r1, r1, r6		@ set RAM section settings*/@ r1 &= ~0x1c		@  1->r1 |= 0x10@ r10 end 0x300000000@  2->r1 |= r6,r1 |= 0x0d,在256M范围内@ r9 start 0x20000000	@  3->r1 |= 0x10	@ 上面这段就是对一级描述符表(页表)的初始化,@ 首先比较这个描述符所描述的地址是否在那个256M的空间中,如果在则这个描述符对应的内存区域是 cacheable ,bufferable。@ 如果不在则noncacheable, nonbufferable。@ 然后将描述符写入一个一级描述符表(页表)的入口,并将一级描述符表(页表)入口地址加4,而指向下一个1M section的基地址。@ 如果页表入口未初始化完,则继续初始化。 @ 一级描述符结构如下:@ 31       20  19 12  11 10  9  8  5 4 3 2 1 0@ 物理地址的基址   0      AP   0   域   1 C B 1 0@    || 1:1映射@    ||	@ 0 <=>  0~(1M-1)@ 1 <=> 1M~(2M-1)@ 2 <=> 2M~(3M-1)@ 4095 <=> (4G-1M)~(4G-1)@ 一级描述符表(页表)的高12位是每个setcion的基地址,可以描述4096个section。@ 一级页表大小为16K,每个页表项,即描述符占4字节,刚好可以容纳4096个描述符,@ 所以这里就映射了4096*1M = 4G的空间。 /* * If ever we are running from Flash, then we surely want the cache * to be enabled also for our execution instance...  We map 2MB of it * so there is no map overlap problem for up to 1 MB compressed kernel. * If the execution is in RAM then we would only be duplicating the above. *//**/ 		orr	r1, r6, #0x04		@ ensure B is set for this		orr	r1, r1, #3 << 10@ 这两行是设置AP和B		mov	r2, pc		mov	r2, r2, lsr #20		orr	r1, r1, r2, lsl #20@ 将当前地址1M对齐,并与r1中的内容结合形成一个描述当前指令所在section的描述符。  		add	r0, r3, r2, lsl #2@ r3为刚建立的一级描述符表(页表)的起始地址0x20004000。@ 将当前地址(pc)的高12位左移两位(形成14位索引)与r3中的地址 @ (低14位为0)相加形成一个4字节对齐的地址 @ 这个地址也在16K的一级描述符表(页表)内,r0的[31:14]为0,所以该地址<2^14=16K。@ 当前地址对应着描述符(貌似这就是一个一级描述符)在一级描述符表(页表)中的位置,这个位置之前已经初始化过了。@ 对于从ram中运行这里只是又重新设置了一次,从flash中运行,会多映射2MB@ 一级页表中索引为r2左移2位。@ r0地址结构如下:@ 31       14  13	        2 1 0@  页表基址        页表index  0 0@ r0里存储的描述符格式如下:@ 31       20  19 12  11 10   9  8  5 4 3 2 1 0@  PC高12bit     0      AP    0   域   1 C B 1 0 		str	r1, [r0], #4		add	r1, r1, #1048576		str	r1, [r0]@ 这里将上面形成的描述符及其连续的下一个section描述 @ 写入上面4字节对齐地址处 		mov	pc, lrENDPROC(__setup_mmu)
mcrne	p15, 0, r3, c2, c0, 0	@ load page table pointer,r3 = 0x20004000

MMU的段页表的虚拟地址与物理地址的转换过程

 

你可能感兴趣的文章
debian 10 安装_如何在Debian 10上安装Webmin
查看>>
使用CentOS 8进行初始服务器设置
查看>>
ecmascript v3_节点v12中的新ECMAScript模块简介
查看>>
盖茨比乔布斯_通过盖茨比使用Airtable
查看>>
mern技术栈好处?_如何开始使用MERN堆栈
查看>>
路由器接路由器_路由器之战:到达路由器vsReact路由器
查看>>
rxjs 搜索_如何使用RxJS构建搜索栏
查看>>
如何在Debian 10上安装MariaDB
查看>>
go函数的可变长参数_如何在Go中使用可变参数函数
查看>>
debian 服务器_使用Debian 10进行初始服务器设置
查看>>
joi 参数验证_使用Joi进行节点API架构验证
查看>>
react-notifications-component,一个强大的React Notifications库
查看>>
如何在Debian 10上设置SSH密钥
查看>>
如何在Debian 10上安装Node.js
查看>>
angular4前后端分离_如何在Angular 4+中使用Apollo客户端GraphQL
查看>>
如何在Ubuntu 18.04上安装Apache Kafka
查看>>
如何在Ubuntu 20.04上安装R [快速入门]
查看>>
debian tomcat_如何在Debian 10上安装Apache Tomcat 9
查看>>
如何为Python 3设置Jupyter Notebook
查看>>
docker 容器共享数据_如何在Docker容器之间共享数据
查看>>