1.5.7. bl lowlevel_init

	/*
	 * before relocating, we have to setup RAM timing
	 * because memory timing is board-dependend, you will
	 * find a lowlevel_init.S in your board directory.
	 */
	mov	ip, lr
	bl	lowlevel_init
	mov	lr, ip1
	mov	pc, lr2
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */3
        

1

将lr的值给ip,即指令指针r12,此处之所以要保存一下lr是因为此处是在子函数cpu_init_crit中,lr已经保存了待会用于返回主函数的地址,即上次调用时候的pc的值,而此处如果在子函数cpu_init_crit中继续调用其他子函数lowlevel_init,而不保存lr的话,那么调用完lowlevel_init返回来时候,就丢失了cpu_init_crit要返回的位置。

说白了就是,每次你要调用函数之前,你自己要确保是否已经正确保存了lr的值,要保证函数调用完毕后,也能正常返回。当然,如果你此处根本不需要返回,那么就不用去保存lr的值了。

2

典型的子函数调用,通过将lr的值赋值给pc,实现函数调用完成后而返回的。

3

这里,其是和前面的代码:

#ifndef CONFIG_SKIP_LOWLEVEL_INIT
	bl	cpu_init_crit
#endif
                

是对应的。