本文简单分析一下 save_boot_params_ret调用的函数:_main汇编函数。
本文继之前文章的学习,地址如下:
uboot启动流程-涉及s_init汇编函数_凌肖战的博客-CSDN博客
经过之前文章的分析,uboot启动流程的汇编函数调用关系:

下面来分析 _main 函数。
_main 函数定义在文件 arch/arm/lib/crt0.S 中,_main函数的前部分代码内容如下:
- 67 ENTRY(_main)
- 68
- 69 /*
- 70 * Set up initial C runtime environment and call board_init_f(0).
- 71 */
- 72
- 73 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
- 74 ldr sp, =(CONFIG_SPL_STACK)
- 75 #else
- 76 ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
- 77 #endif
- 78 #if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC
- destination */
- 79 mov r3, sp
- 80 bic r3, r3, #7
- 81 mov sp, r3
- 82 #else
- 83 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
- 84 #endif
- 85 mov r0, sp
- 86 bl board_init_f_alloc_reserve
- 56 ulong board_init_f_alloc_reserve(ulong top)
- 57 {
- 58 /* Reserve early malloc arena */
- 59 #if defined(CONFIG_SYS_MALLOC_F)
- 60 top -= CONFIG_SYS_MALLOC_F_LEN;
- 61 #endif
- 62 /* LAST : reserve GD (rounded up to a multiple of 16 bytes) */
- 63 top = rounddown(top-sizeof(struct global_data), 16);
- 64
- 65 return top;
- 66 }

继续分析_main 函数,如下是继以上代码:
- 87 mov sp, r0
- 88 /* set up gd here, outside any C code */
- 89 mov r9, r0
- 90 bl board_init_f_init_reserve

- 27 typedef struct global_data {
- 28 bd_t *bd;
- 29 unsigned long flags;
- 30 unsigned int baudrate;
- 31 unsigned long cpu_clk; /* CPU clock in Hz! */
- 32 unsigned long bus_clk;
- 33 /* We cannot bracket this with CONFIG_PCI due to mpc5xxx */
- 34 unsigned long pci_clk;
- 35 unsigned long mem_clk;
- 36 #if defined(CONFIG_LCD) || defined(CONFIG_VIDEO)
- 37 unsigned long fb_base; /* Base address of framebuffer mem */
- 38 #endif
- ......
- 121 #ifdef CONFIG_DM_VIDEO
- 122 ulong video_top; /* Top of video frame buffer area */
- 123 ulong video_bottom; /* Bottom of video frame buffer area */
- 124 #endif
- 125 } gd_t;
- 110 void board_init_f_init_reserve(ulong base)
- 111 {
- 112 struct global_data *gd_ptr;
- 113 #ifndef _USE_MEMCPY
- 114 int *ptr;
- 115 #endif
- 116
- 117 /*
- 118 * clear GD entirely and set it up.
- 119 * Use gd_ptr, as gd may not be properly set yet.
- 120 */
- 121
- 122 gd_ptr = (struct global_data *)base;
- 123 /* zero the area */
- 124 #ifdef _USE_MEMCPY
- 125 memset(gd_ptr, '\0', sizeof(*gd));
- 126 #else
- 127 for (ptr = (int *)gd_ptr; ptr < (int *)(gd_ptr + 1); )
- 128 *ptr++ = 0;
- 129 #endif
- 130 /* set GD unless architecture did it already */
- 131 #if !defined(CONFIG_ARM)
- 132 arch_setup_gd(gd_ptr);
- 133 #endif
- 134 /* next alloc will be higher by one GD plus 16-byte alignment */
- 135 base += roundup(sizeof(struct global_data), 16);
- 136
- 137 /*
- 138 * record early malloc arena start.
- 139 * Use gd as it is now properly set for all architectures.
- 140 */
- 141
- 142 #if defined(CONFIG_SYS_MALLOC_F)
- 143 /* go down one 'early malloc arena' */
- 144 gd->malloc_base = base;
- 145 /* next alloc will be higher by one 'early malloc arena' size */
- 146 base += CONFIG_SYS_MALLOC_F_LEN;
- 147 #endif
- 148 }
继续分析_main 函数,如下是继以上代码:
- 92 mov r0, #0
- 93 bl board_init_f
- 94
- 95 #if ! defined(CONFIG_SPL_BUILD)
- 96
- 97 /*
- 98 * Set up intermediate environment (new sp and gd) and call
- 99 * relocate_code(addr_moni). Trick here is that we'll return
- 100 * 'here' but relocated.
- 101 */
- 102
- 103 ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */
- 104 #if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC
- destination */
- 105 mov r3, sp
- 106 bic r3, r3, #7
- 107 mov sp, r3
- 108 #else
- 109 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
- 110 #endif
- 111 ldr r9, [r9, #GD_BD] /* r9 = gd->bd */
- 112 sub r9, r9, #GD_SIZE /* new GD is below bd */
下一篇文章继续分析 _main函数。