微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > arm linux 从入口到start_kernel 代码分析 - 4

arm linux 从入口到start_kernel 代码分析 - 4

时间:11-10 来源:互联网 点击:

239, 240行: TEXTADDR是内核的起始虚拟地址(0xc0008000), 这两行是设置kernel起始虚拟地址的页表项(注意,这里设置的页表项和上面的231 - 233行设置的页表项是不同的 )
执行完后,r0指向kernel的第2个section的虚拟地址所在的页表项.


242行: 这一行计算kernel镜像的大小(bytes).
_end 是在vmlinux.lds.S中162行定义的,标记kernel的结束位置(虚拟地址):
00158 .bss : {
00159__bss_start = .;
00160*(.bss)
00161*(COMMON)
00162_end = .;
00163}

kernel的size = _end - PAGE_OFFSET -1, 这里 减1的原因是因为 _end 是 location counter,它的地址是kernel镜像后面的一个byte的地址.

243行: 地址右移20位,计算出kernel有多少sections,并将结果存到r6中

245 - 248行: 这几行用来填充kernel所有section虚拟地址对应的页表项.

253行: 将r0设置为RAM第一兆虚拟地址的页表项地址(page entry)
254行: r7中存储的是mmu flags, 逻辑或上RAM的起始物理地址,得到RAM第一个MB页表项的值.
255行: 设置RAM的第一个MB虚拟地址的页表.
上面这三行是用来设置RAM中第一兆虚拟地址的页表. 之所以要设置这个页表项的原因是RAM的第一兆内存中可能存储着boot params.

这样,kernel所需要的基本的页表我们都设置完了, 如下图所示:

_,,_ _,,_
-` `-.,,. -` `-.,,.
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
+-----------+ | |
| | | |
| |-------------\ | |
| | | | |
| KERNEL | | | |
| | | | |
| | | | |
| | | | |
| | | | |
+0x8000 ->+-----------+--------\ | | |
| | | | | |
| L1 | | | | |
| Page Table| | | | |
| | | | | |
+0x4000 ->+-----------+ | | | |
| | | | +-----------+
| Boot | | | | |
| Params | | | | |
| | | | | |
PAGE_OFFSET(3G) ->+-----------+---\ | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | +-----------+
| | | | | | |
| | | | \-->| |
| | | | | |
| | | | | KERNEL |
| | | | | |
| | | | | |
+- - - - - -+ | | | |
| 1MB | | | | |
PHYS_OFFSET+0x8000 ->+- - - - - -+--------+------->-----------+<- +0x8000
| | | | |
| | | | L1 |
| | | | Page Table|
| | | | |
| | | +-----------+<- +0x4000
| | | | |
| | | | Boot |
| | | | Params |
| | | | |
| | \------------>+-----------+<- PHYS_OFFSET
| | | |
| | | _,,_ |
| | -` `-.,,.
0 --+-----------+

VIRT Address PHYS Address

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top