一. uboot 启动流程
本文我们来详细的分析一下 uboot 的启动流程,理清 uboot 是如何启动的。通过对 uboot 启动流程的梳理。
我们就可以掌握一些外设是在哪里被初始化的,这样当我们需要修改这些外设驱动的时候就会心里有数。另外,通过分析 uboot 的启动流程可以了解 Linux 内核是如何被启动的。
注意: 分析 uboot启动流程的前提是,uboot源码需要经过编译。
二. 链接脚本 u-boot.lds
要分析 uboot 的启动流程,首先要找到“入口”,找到第一行程序在哪里。
 
 程序的链接是由链接脚本来决定的,所以通过链接脚本可以找到程序的入口。连接脚本在uboot的根目录下u-boot.lds文件。 
  
 
 
 
  注意:如果没有编译过 uboot 的话链接脚本为 arch/arm/cpu/u-boot.lds。但这个不是最终使用的链接脚本,最终的链接脚本是在这个链接脚本的基础上生成的。编译一下 uboot,编译完成以后就会在 uboot 根目录下生成 u-boot.lds 文件。 
 
 
  
 
 只有编译  
 u-boot  
 以后才会在根目录下出现  
 u-boot.lds  
 文件!!! 
 
 
 
 打开  
 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 {
10 *(.__image_copy_start)
11 *(.vectors)
12 arch/arm/cpu/armv7/start.o (.text*)
13 *(.text*)
14 }
15 . = ALIGN(4);
16 .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
17 . = ALIGN(4);
18 .data : {
19 *(.data*)
20 }
21 . = ALIGN(4);
22 . = .;
23 . = ALIGN(4);
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*)
38 }
39 .rel_dyn_end :
40 {
41 *(.__rel_dyn_end)
42 }
43 .end :
44 {
45 *(.__end)
46 }
47 _image_binary_end = .;
48 . = ALIGN(4096);
49 .mmutable : {
50 *(.mmutable)
51 }
52 .bss_start __rel_dyn_start (OVERLAY) : {
53 KEEP(*(.__bss_start));
54 __bss_base = .;
55 }
56 .bss __bss_base (OVERLAY) : {
57 *(.bss*)
58 . = ALIGN(4);
59 __bss_limit = .;
60 }
61 .bss_end __bss_limit (OVERLAY) : {
62 KEEP(*(.__bss_end));
63 }
......
73 .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
74 } 
  第  
  3  
  行为代码当前入口点: 
  _start 
  ,_start  
  在文件 arch/arm/lib/vectors.S 中有定义。vectors.S 如下所示: 
 
 
  
 
 
 
  从 vectors.S 中 
  可以看出, 
  _start  
  后面就是中断向量表,从图中的 “ 
  .section ".vectors",  
  "ax 
  ”可以得到,此代码存放在 
  .vectors  
  段里面。  
 
 
 
  u-boot.map  
  是  
  uboot  
  的内存映射文件,打开 u-boot.map: 
 
 
  
  
 
  
  从 u-boot.map 可以看到,某个文件或者函数链接到了哪个地址,  第 958 
  行可以看到 
  __image_copy_start  
  为 
  0X87800000 
  ,而  
  .text  
  的起始地址也是  
  0X87800000 
  。 
 
 
  继续链接脚本 
 u-boot.lds, 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 
  第  
  11  
  行是  
  vectors  
  段, 
  vectors 段保存中断向量表,从vectors.S 中我们知道了 vectors.S  
  的代码是存在 vectors 段中的。 u-boot.map 文件可以看出:vectors 段的起始地址也是  
  0X87800000 
  ,说明整个  
  uboot  
  的起始地址就是  
  0X87800000 
  ,这也是为什么我们裸机 
  例程的链接起始地址选择  
  0X87800000  
  了,目的就是为了和  
  uboot  
  一致。  
 
 


















