arm linux start_kernel之前页表初始化

内核版本是3.19.1

内核的入口在head.S的stext中,进入start_kernel之前,大概经历了如下几步:

1.将CPU工作模式设置成svc模式,屏蔽中断

2.获取CPU ID,然后依据CPU ID查找对应的PROC INFO

3.校验atags指针

4.__create_page_tables 创建页表,本文重点的记录一下这部分内容


页表初始化主要完成了三部分区域的映射。

初始化过程如下。

Step 1. 清零页表内容。

页表的停放在内核镜像前的16K物理空间内,即(phys_offset+text_offset - page_dir_size,phys_offset + text_offset)区间内。

这里的几个宏定义如下:

page_dir_size:页表的大小

phys_offset:代码中要求使用PLAT_PHYS_OFFSET这个宏,总之就是RAM的物理起始地址,比如tq2440中SDRAM挂在BANK6上,对应的值就是BANK6的物理地址。

text_offset:内核镜像的开始地址

Step 2, 映射 __turn_mmu_on 到 __turn_mmu_on_end这段空间,这段空间的物理地址与虚拟地址相同,即所谓的平映射。

__turn_mmu_on到__turn_mmu_on_end这段空间实际中就是一个特别短的一个函数,就在同一个1M空间内,对这段空间进行平映射是为了保证在开启MMU时,CPU的PC指针可以正常的执行,直到通过B命令跳转到内核使用的虚拟地址段上来。

举个例子,假设开启MMU前的一瞬间,PC指向0x100这个物理地址,它的下一条指令,就是0x104,可是开启MMU之后,CPU发出的0x104地址就会被MMU“转译”,不做平映射的话,天知道它跑到哪儿去了。

Step3. 映射内核虚拟地址空间到物理地址开始处。将内核虚拟地址的开始处(3G,0xc000 0000)到.bss段的结尾处(_end)这段空间,映射到物理RAM地址开始处对应的空间。

Step4.映射atags附近2M空间到内核虚拟空间同样偏移的2M空间内。之所以映射2M是担心atag指向的内容(传给内核的参数)正好跨过一个section。

你可能感兴趣的:(arm linux start_kernel之前页表初始化)