系统移植-(二)u-boot:启动过程做的工作(汇编阶段、C阶段)

(一)ctags 安装

ubuntu下的代码追踪工具:ctags
windows下的代码追踪工具:Source Insight

(1)安装ctags,在ubuntu中默认已经安装好ctags.

	sudo apt-get install ctags

(2)进入到要追踪的源码的顶层目录下,
ctags -R:在源码的顶层目录下生成tags文件, -R:递归
执行以下命令:

	vi -t  想追的内容

(3)只能在tags所在目录下,vim/vi + 绝对路径,打开u-boot下的源码文件。

	vi 从源码顶层开始的路径/xxx.c 
	vi arch/arm/cpu/slsiap/s5p6818/start.S

注意:只能一步到位使用:vim + 绝对路径,打开想要追踪的文件;
cd /ls /vim:一步一步打开错误。
eg错误方式:cd arch/arm/cpu/slsiap/s5p6818/ -> vi start.S

(4)代码追踪

  • 将光标放到要追踪的函数处,按ctrl + ] 进入追踪的界面
  • 选择位置序号,进入追踪的代码定义处
    ctrl + t : 返回上一级

注意:
(1)如果函数的调用和定义都在当前文件,则直接命令行搜索:/要追踪的内容
(2)如果不在当前文件中定义,选中要追踪的内容,ctrl + ]使用ctags工具进行追踪

(二)uboot 启动过程

在这里插入图片描述
在这里插入图片描述

(1)链接脚本u-boot.lds

uboot启动过程中做的工作,可以通过追踪u-boot代码的执行过程。即找到ubootpak.bin文件执行的第一条指令。需要查看链接脚本文件,u-boot.lds。
u-boot.lds :指导编译器链接编译目标文件[.o]生成可执行文件[.elf]时,代码在内存空间中的排布。
u-boot.lds脚本源码(部分):

  2 OUTPUT_ARCH(arm)
  3 ENTRY(_stext) //指定程序入口,在start.S中可看到地址符号_stext:                                          
  4 SECTIONS //整个链接脚本
  5 {
  6  . = 0x00000000;//当前地址
  7  . = ALIGN(4);	//申请2^4 = 16字节的占位内存空间
  8  .text ://文本段
  9  {
 10   *(.__image_copy_start)//当前字段是一个变量:表示可以申请的占位内存空间
 11   arch/arm/cpu/slsiap/s5p6818/start.o (.text*)//程序入口执行的第一个文件:start.S
 12   arch/arm/cpu/slsiap/s5p6818/vectors.o (.text*)//第二个是中断异常向量表vectors.S
 13   *(.text*)//其他文件,根据编译器自动排布
 14  }
  • __image_copy_start代码追踪查看:
    char __image_copy_start[0] :占用0字节内存
在arch/arm/lib/sections.c中定义:

 22 char __bss_start[0] __attribute__((section(".__bss_start")));
 23 char __bss_end[0] __attribute__((section(".__bss_end")));
 24 char __image_copy_start[0] __attribute__((section(".__image_copy_start")));  
 25 char __image_copy_end[0] __attribute__((section(".__image_copy_end")));
 26 char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start")));
 27 char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end")));
 28 char _end[0] __attribute__((section(".__end")));
 ~

(2)start.S分析

打开 vi arch/arm/cpu/slsiap/s5p6818/start.S:

  2  * armboot - Startup Code for NXPxxxx/ARM Cortex CPU-core//启动代码-ARM
  
 14  * Exception vectors as described in ARM reference manuals
 15  *
 16  * replace arm/lib/vectors.S
 
 20     .globl  _stext                                                       
 21 _stext:	//程序入口,以下8个指令作用:构建异常向量表,各异常顺序不可改变
 22     b   reset//执行的第一个指令:跳转到reset异常下 -》搜索/reset
 23     ldr pc, _undefined_instruction
 24     ldr pc, _software_interrupt
 25     ldr pc, _prefetch_abort
 26     ldr pc, _data_abort
 27     ldr pc, _not_used
 28     ldr pc, _irq
 29     ldr pc, _fiq
 30 
 31 _undefined_instruction: .word undefined_instruction
 32 _software_interrupt:    .word software_interrupt
 33 _prefetch_abort:    .word prefetch_abort
 34 _data_abort:        .word data_abort
 35 _not_used:      .word not_used
 36 _irq:           .word irq
 37 _fiq:           .word fiq
 38 
 39     .balignl 16,0xdeadbeef
 40 
 ~

(3)Reset handler 分析

 76     .globl reset
 77 
 78 reset:
 79     bl  save_boot_params 	跳转到save_boot_params:保存启动参数
 80     /*
 81      * set the cpu to SVC32 mode
 82      */						设置SVC工作模式
 83     mrs r0, cpsr			把cpsr中的值保存到r0中
 84     bic r0, r0, #0x1f		清除r0后5位并保存到r0
 85     orr r0, r0, #0xd3		
 86     msr cpsr,r0				切换到SVC,确保进入SVC工作模式
 87 
 88     /* disable watchdog*/	禁止看门狗:看门狗上电时默认状态是启动的,禁止WTD防止启动不起来	
 89     ldr r0, =0xC0019000
 90     mov r1, #0
 91     str r1, [r0]
 		
 94 #ifndef CONFIG_SKIP_LOWLEVEL_INIT	因为没有定义此变量,需执行下面两个指令
 95     bl  cpu_init_cp15				完成:
 96     bl  cpu_init_crit
 97 #endif


100 relocate_to_text: u-boot代码自搬移到内存存放文本的位置                   
101     /*
102      * relocate(搬移) u-boot code on memory to text base
103      * for nexell arm core (add by jhkim)
104      */
105     adr r0, _stext              /* r0 <- current position of code   */
106     ldr r1, TEXT_BASE           /* test if we run from flash or RAM */
107     cmp r0, r1                  /* don't reloc during debug         */
108     beq clear_bss
109 
110     ldr r2, _bss_start_ofs
111     add r2, r0, r2              /* r2 <- source end address         */
112 
113 copy_loop_text:
114     ldmia   r0!, {r3-r10}       /* copy from source address [r0]    */
115     stmia   r1!, {r3-r10}       /* copy to   target address [r1]    */
116     cmp r0, r2                  /* until source end addreee [r2]    */
117     ble copy_loop_text
118 
119     ldr r1, TEXT_BASE           /* restart at text base */
120     mov pc, r1

122 clear_bss:     //清除bss段  
123 #ifdef CONFIG_MMU_ENABLE
124     bl  mmu_turn_on
125 #endif
126     ldr r0, _bss_start_ofs
127     ldr r1, _bss_end_ofs
128     ldr r4, TEXT_BASE           /* text addr */
129     add r0, r0, r4
130     add r1, r1, r4
131     mov r2, #0x00000000         /* clear */
...
144     bl  board_init_f                                     
...
160     ldr pc, =board_init_r      自搬移/* this is auto-relocated! */   
...
162 #else   /* CONFIG_RELOC_TO_TEXT_BASE */
163
164     bl  _main 	跳转到主函数                                                                                                                                               
165 #endif
~

(1)bl cpu_init_cp15

禁止MMU和cache,设置协处理器

207  /* cpu_init_cp15
208  *
209  * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless  
211  *设置CP15寄存器(缓存,MMU, TLBs)。除非定义了CONFIG_SYS_ICACHE_OFF打开I-cache。
212  *************************************************************************/
213 ENTRY(cpu_init_cp15)
214     /*
215      * Invalidate L1 I/D
216      */					
217     mov r0, #0          @ set up for MCR  设置协处理器:忽略TLBs、icache、BP组
218     mcr p15, 0, r0, c8, c7, 0   @ invalidate TLBs
219     mcr p15, 0, r0, c7, c5, 0   @ invalidate icache
220     mcr p15, 0, r0, c7, c5, 6   @ invalidate BP array
221 #ifndef CONFIG_MACH_S5P6818
222     mcr p15, 0, r0, c7, c10, 4  @ DSB
223     mcr p15, 0, r0, c7, c5, 4   @ ISB
224 #endif
225 
226     /*
227      * disable MMU stuff and caches
228      */禁止MMU和cache:MMU内存管理单元,进行物理内存和虚拟内存映射;
		   本阶段使用的都是物理内存,所以需要禁止mmu。
229     mrc p15, 0, r0, c1, c0, 0
230     bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
231     bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
232     orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
233     orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
234 #ifdef CONFIG_SYS_ICACHE_OFF
235     bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
236 #else
237     orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
238 #endif
239     mcr p15, 0, r0, c1, c0, 0	返回到跳转前的位置处
240     mov pc, lr          @ back to my caller
241 ENDPROC(cpu_init_cp15)  

(2)bl cpu_init_crit

244 /*************************************************************************
245  *
246  * CPU_init_critical registers	CPU临界资源初始化寄存器
247  *    
248  * setup important registers
249  * setup memory timing
250  *
251  *************************************************************************/
252 ENTRY(cpu_init_crit)
253     /*
254      * Jump to board specific initialization...
255      * The Mask ROM will have already initialized
256      * basic memory. Go here to bump up clock rate and handle
257      * wake up conditions.
258      */
259     b   lowlevel_init       @ go setup pll,mux,memory
260 ENDPROC(cpu_init_crit)
261 #endif
b lowlevel_init
 11 lowlevel_init:  低电平初始化    
 12 
 13     /* get cpu id */ 获取cpu的id
 14     mrc     p15, 0, r0, c0, c0, 5       @ Read CPU ID register
 15     ands    r0, r0, #0x03               @ Mask off, leaving the CPU ID field
 16     mov     r1, #0xF                    @ Move 0xF (represents all four ways) into r1
 17 
 18     /* join SMP */
 19     mrc     p15, 0, r0, c1, c0, 1       @ Read ACTLR
 20     mov     r1, r0
 21     orr     r0, r0, #0x040              @ Set bit 6
 22     cmp     r0, r1
 23     mcrne   p15, 0, r0, c1, c0, 1       @ Write ACTLR
 24 
 25     /* enable maintenance broadcast */使能保持广播设置
 26     mrc     p15, 0, r0, c1, c0, 1       @ Read Aux Ctrl register
 27     mov     r1, r0
 28     orr     r0, r0, #0x01               @ Set the FW bit (bit 0)
 29     cmp     r0, r1
 30     mcrne   p15, 0, r0, c1, c0, 1       @ Write Aux Ctrl register
 31 
 32     mov  pc, lr                         @ back to caller	返回调用处
 

(3)board_init_f

追踪代码:对bd_t/gd_t等底板信息的结构体变量,进行初始化赋值操作。

263 void board_init_f(ulong bootflag)
264 {   
265     bd_t *bd;
266     init_fnc_t **init_fnc_ptr;
267     gd_t *id;
268     ulong addr, addr_sp;
 ...		
 		}          

(4)board_init_r

board_init_r函数:完成了大部分串口,内存,flash,cache等硬件的初始化

509 void board_init_r(gd_t *id, ulong dest_addr)
510 {   
511     ulong malloc_start;
512 #if !defined(CONFIG_SYS_NO_FLASH)
513     ulong flash_size;               
514 #endif
521     /* Enable caches */使能cache
522     enable_caches();
524     debug("monitor flash len: %08lX\n", monitor_flash_len);
525     board_init();   /* Setup chipselects */ 底板初始化
533     set_cpu_clk_info(); /* Setup clock information */     

615     /* initialize environment */初始化环境变量
616     if (should_load_env())
617         env_relocate();
618     else
619         set_default_env(NULL);
625     stdio_init();   /* get the devices list going. */ 设备启动列表
626 
627     jumptable_init();
628 
629 #if defined(CONFIG_API)
630     /* Initialize API */ 初始化API接口
631     api_init();
632 #endif
633 
634     console_init_r();   /* fully init console as a device */ 控制台初始化
635 
636 #ifdef CONFIG_PMIC_REG_DUMP
637     power_init_board();	底板上电初始化
638 #endif 
...
708 
709     /* main_loop() can return to retry autoboot, if so just run it again. */
		main_loop()可以返回重复自动引导u-boot启动,如果是这样的话,只需再次运行它
		
710     for (;;) {
711         main_loop();
712     }

713		除了引导之外,没有方法跳出命令循环
714     /* NOTREACHED - no way out of command loop except booting */
715 }                                                          

(三)u-boot 启动总结

uboot启动阶段,主要干了哪些事?

  • 阶段1:汇编阶段
    1》构建异常向量表
    2》ARM切换到SVC工作模式,关闭看门狗WTD,禁止中断
    3》关闭MMU和cache
    4》一些串口、定时器、环境变量、I2C/SPI总线等的初始化
    5》完成u-boot代码的自搬移,清除bss段

  • 阶段2:c语言阶段
    1》完成对bd和gd结构体的初始化
    2》完成大部分硬件的初始化:串口,网卡,flash,使能中断等等
    3》根据bootdelay倒计时是否为0,切换uboot进入自启动模式还是交互模式
    4》执行u-boot环境变量bootcmd中的命令,并将bootargs参数传递给内核

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值