侵权投诉
订阅
纠错
加入自媒体

一款比较常用的bootloader:uboot代码介绍

2021-01-25 17:16
一口Linux
关注

五、uboot启动的几个关键知识点

如何判断第一条机器指令的位置?

链接脚本决定了内存的布局。

uboot链接脚本如下:

u-boot-2013.01/arch/arm/cpu/u-boot.lds

文件内容:

28 ENTRY(_start)
29 SECTIONS
30 {
31     . = 0x00000000;
32

uboot的入口是_start

链接地址是0x00000000

uboot如何搬运代码?

代码位于:

u-boot-2013.01/arch/arm/cpu/armv7/start.S

搬移代码如下:

ENTRY(relocate_code)
mov r4, r0  save addr_sp
mov r5, r1  save addr of gd
mov r6, r2  save addr of destination
adr r0, _start
cmp r0, r6
moveq r9, #0   no relocation. relocation offset(r9) = 0
beq relocate_done   skip relocation
mov r1, r6    r1 <- scratch for copy_loop
ldr r3, _image_copy_end_ofs
add r2, r0, r3   r2 <- source end address    
copy_loop:
ldmia r0!, {r9-r10}   copy from source address [r0]    
stmia r1!, {r9-r10}   copy to   target address [r1]    
cmp r0, r2    until source end address [r2]    
blo copy_loop

详情参考第四章,第3节。

uboot中,如何判断此次开机是从断电状态开机还是从休眠状态启动的?board/samsung/fs4412/lowlevel_init.S

代码如下:

41   lowlevel_init:
54      AFTR wakeup reset
55     ldr r2, =S5P_CHECK_DIDLE
56     cmp r1, r2
57     beq exit_wakeup
58
59      LPA wakeup reset
60     ldr r2, =S5P_CHECK_LPA
61     cmp r1, r2
62     beq exit_wakeup
63
64      Sleep wakeup reset
65     ldr r2, =S5P_CHECK_SLEEP
66     cmp r1, r2
67     beq wakeup_reset
112 wakeup_reset:
113     bl system_clock_init
114     bl mem_ctrl_asm_init
115     bl tzpc_init
116
117 exit_wakeup:
118      Load return address and jump to kernel
119     ldr r0, =(EXYNOS4_POWER_BASE + INFORM0_OFFSET)
120
121      r1 = physical address of exynos4210_cpu_resume function
122     ldr r1, [r0]
123
124      Jump to kernel
125     mov pc, r1

由上可知,当手机因为各种原因进入休眠时,会将当前程序执行的上下文保护起来,并向一些pmic的寄存器中写入指定的数据,以表明此次是因为何种原因进入休眠。

而手机并没有完全断电,而是处于一个低功耗模式下,此时启动RAM仍然有数据,所以在此启动后,只需要从特殊的寄存器中读取相应的值,就可以知道之前是因为什么原因休眠,进而回复休眠之前的上下文即可。

uboot代码搬到ram之后,代码的运行地址发生了变化,如何保证程序跳转不会出错?

除了要保证uboot代码是基于地址无关的,此外.rel.dyn帮我们解决了,其实主要还是编译器帮我们做了很多工作。

位置无关码参考《15. 从0学ARM-什么是位置无关码?》

设备启动的时候,有可能直接从ram启动, 如何知道当前是从flah启动还是ram启动的?

文件:

board/samsung/fs4412/lowlevel_init.S

代码:

lowlevel_init:

85    
86      * If U-boot is already running in ram, no need to relocate U-Boot.
87      * Memory controller must be configured before relocating U-Boot
88      * in ram.
89      
90     ldr r0, =0x0ffffff       r0 <- Mask Bits
91     bic r1, pc, r0       pc <- current addr of code
92                      r1 <- unmasked bits of pc
93     ldr r2, _TEXT_BASE       r2 <- original base addr in ram
94     bic r2, r2, r0       r2 <- unmasked bits of r2
95     cmp r1, r2           compare r1, r2
96     beq 1f           r0 == r1 then skip sdram init

原理:RAM地址空间是:0x40000000-0xA0000000   0xA0000000-0x00000000而iROM/iRAM地址的bit:28-31均是0,所以只需要读取出执行到lowlevel_init时pc的值,判断其bit:28-31是否是0即可知道现在代码是否运行在RAM中。


<上一页  1  2  3  4  
声明: 本文由入驻维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。

发表评论

0条评论,0人参与

请输入评论内容...

请输入评论/评论长度6~500个字

您提交的评论过于频繁,请输入验证码继续

暂无评论

暂无评论

    电子工程 猎头职位 更多
    扫码关注公众号
    OFweek电子工程网
    获取更多精彩内容
    文章纠错
    x
    *文字标题:
    *纠错内容:
    联系邮箱:
    *验 证 码:

    粤公网安备 44030502002758号