自己根据正点原子IMX6UL整理的
PDF下载地址: https://download.csdn.net/download/a2267542848/16618952
想要分析如何启动,就要分析链接文件, 如果没编译过的链接脚本在 arch/arm/cpu/u-boot.lds
编译过的在根目录
1 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") 2 OUTPUT_ARCH(arm)
3 ENTRY(_start)
4 SECTIONS
5{
6 . = 0x00000000;
7 . = ALIGN(4);
8 .text :
9{
*(.__image_copy_start)
*(.vectors) arch/arm/cpu/armv7/start.o (.text*) *(.text*)
}
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
17 . = ALIGN(4); 18 .data : {
19 *(.data*)
20 }
21 .
22 .
23 .
24 .u_boot_list : {
25 KEEP(*(SORT(.u_boot_list*))); 26 }
27 . = ALIGN(4);
28 .image_copy_end :
29 {
30 *(.__image_copy_end) 31 }
32 .rel_dyn_start :
33 {
34 *(.__rel_dyn_start) 35 }
36 .rel.dyn : {
37 *(.rel*)
.rel_dyn_end : {
*(.__rel_dyn_end) }
.end : {
*(.__end) }
_image_binary_end = .; . = ALIGN(4096); .mmutable : {
*(.mmutable) }
.bss_start __rel_dyn_start (OVERLAY) : { KEEP(*(.__bss_start));
__bss_base = .;
}
.bss __bss_base (OVERLAY) : {
*(.bss*)
. = ALIGN(4);
59 __bss_limit = .;
60 }
61 .bss_end __bss_limit (OVERLAY) : {
62 KEEP(*(.__bss_end));
63 }
64 .dynsym _image_binary_end : { *(.dynsym) }
65 .dynbss : { *(.dynbss) }
66 .dynstr : { *(.dynstr*) }
67 .dynamic : { *(.dynamic*) }
68 .plt : { *(.plt*) }
69 .interp : { *(.interp*) }
70 .gnu.hash : { *(.gnu.hash) }
71 .gnu : { *(.gnu*) }
72 .ARM.exidx : { *(.ARM.exidx*) }
73 .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) } 74 }
-start是入口点, 定义在 arch/arm/lib/vectors.S
后面直接是中断向量表, 代码放在.verctors中
reset函数在arch/arm/cpu/armv7/start.S 里面 先进行save_boot_parmas
reset:
/* Allow the board to save important registers */
b save_boot_params
save_boot_params_ret:
/*
* disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
* except if in HYP mode already
*/
mrs r0, cpsr // 读取cpsr的值放到r0中
and r1, r0, #0x1f @ mask mode bits, 和1f做and运算,放到r1中
teq r1, #0x1a @ test for HYP mode , 判断是否等到1a,
bicne r0, r0, #0x1f @ clear all mode bits ,如果不等于就清楚模式
orrne r0, r0, #0x13 @ set SVC mode 如果等于就与0x13或运算, 进入SVC模式
orr r0, r0, #0xc0 @ disable FIQ and IRQ, 关闭中断
msr cpsr,r0 , 写回寄存器
然后设置中断向量表偏移
然后初始化cp15等, 执行cpu_init-crint
函数 lowlevel_init 在文件 arch/arm/cpu/armv7/lowlevel_init.S 中定义
sp 指向 CONFIG_SYS_INIT_SP_ADDR,在 include/configs/mx6ullevk.h 文件中,在 mx6ullevk.h 中有如下所示定义
#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR 235 #define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE
#define CONFIG_SYS_INIT_SP_OFFSET \
(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) 239 #define CONFIG_SYS_INIT_SP_ADDR \
(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
IRAM_BASE_ADDR 和 IRAM_SIZE 在 文 件 arch/arm/include/asm/arch-mx6/imx-regs.h 中有定义,如下所示,其实就是 IMX6UL/IM6ULL 内 部 ocram 的首地址和大小。
最终lowlevel_init调用s_init, 这个函数在 arch/arm/cpu/armv7/mx6/soc.c 中
_main 函数定义在文件 arch/arm/lib/crt0.S 中,函数内容如下:
main 函数里面调用了 board_init_f、relocate_code、
board_init_r 函数定义在文件 common/board_r.c 中,代码如下