第一阶段程序流程图
SVC模式切换
|
针对特定SOC的设置
|
lowlevel_init---->I/Dcache, MMU,sdram
|
relocate
|
进入引导第二阶段
uboot1.1.6 ARCH=arm920t CPU=S3C2410
编译后生成的二进制文件,也就是机器码,这里只是该文件的前16行,不过第一阶段引导的关键代码都在这里了,首先是机器加电PC=0,而这部分代码会被加载到steppingstone里执行。
存储方式:高位高字节
- 0000000: 1200 00ea 14f0 9fe5 14f0 9fe5 14f0 9fe5 ................
- 0000010: 14f0 9fe5 14f0 9fe5 14f0 9fe5 14f0 9fe5 ................
- 0000020: 4001 f833 a001 f833 0002 f833 6002 f833 @..3...3...3`..3
- 0000030: c002 f833 2003 f833 8003 f833 efbe adde ...3 ..3...3....
- 0000040: 0000 f833 0000 f833 d479 f933 fcc0 f933 ...3...3.y.3...3
- 0000050: 0000 0fe1 1f00 c0e3 d300 80e3 00f0 29e1 ..............).
- 0000060: 5304 a0e3 0010 a0e3 0010 80e5 0010 e0e3 S...............
- 0000070: 6003 9fe5 0010 80e5 5c13 9fe5 5c03 9fe5 `.......\...\...
- 0000080: 0010 80e5 5803 9fe5 0310 a0e3 0010 80e5 ....X...........
- 0000090: 1800 00eb 9c00 4fe2 6010 1fe5 0100 50e1 ......O.`.....P.
- 00000a0: 0700 000a 6820 1fe5 6830 1fe5 0220 43e0 ....h ..h0... C.
- 00000b0: 0220 80e0 f807 b0e8 f807 a1e8 0200 50e1 . ............P.
- 00000c0: fbff ffda 8c00 1fe5 0308 40e2 8000 40e2 ..........@...@.
- 00000d0: 0cd0 40e2 9400 1fe5 9410 1fe5 0020 a0e3 ..@.......... ..
- 00000e0: 0020 80e5 0400 80e2 0100 50e1 fbff ffda . ........P.....
- 00000f0: 04f0 1fe5 e00b f833 0000 a0e3 170f 07ee .......3........
执行的第一句指令是ea000012,这句指使得程序跳到PC+0x50处继续执行和地址无关, 此处的机器码是模式转换到svc,转换完成后有个带返回的跳转lowlevel_init,对应的机器码在eb000018,跳到PC+0x68处继续执行和地址无关,返回以后程序还会接着执行,接着是代码的搬运,搬运到ram目的地址_TEXT_BASE存储在0000040【4bytes】,访问该数据是通过相对于PC的偏移,不是直接访问地址,其实arm的B,BL,LDR,都是通过先计算出当前PC的偏移量,再把该内存单元的值取出来。
从44开始的4bytes数据存放的是armboot_start的值=33f80000,
从48开始的4bytes存放的是_BSS_START的值=33f80000,
从4C开始的4bytes存放的是_BSS_END值=33f9c0fc,
取这些值时用的指令有ldr和adr,这两条指令都是通过相对PC的偏移来计算的,是和地址无关。
_BSS_START - armboot_start的值等于uboot的大小。从_start标号处开始复制代码,然后设置SP和BSS段,完成后执行00000f0处的代码e51ff004,将以当前的地址+4的内存单元的值加载到PC里,而该内存单元恰好是33f80000,这里开始到sdram里去执行第二阶段的引导程序。所以第一阶段的机器码不管加载在什么地址在什么介质都可以正常运行。如果直接通过arm-linux-objdump反汇编的代码去分析很容易被链接器链接后那些链接地址欺骗。当然如果知道链接器工作原理后应该不会被反汇编的代码欺骗
阅读(1651) | 评论(0) | 转发(0) |