17.U-boot的工作流程分析-6410

摘要:
Makefile中的配置选项是makeforlinx_nand_ram256_配置:然后输入makeforlinx.nand_ram256 _配置返回将位于此处:我知道lds文件是一个连接器脚本。{cpu/s3c64xx/start.o(.text)//1您可以看到代码段前面的文件是start.o,ENTRY(_start)是整个程序的条目。

17.U-boot的工作流程分析-6410

6410开发板:

1.uboot的入口:

要看uboot工程的入口,首先打开顶层目录的Makefile:

17.U-boot的工作流程分析-6410第1张

Uboot所支持的开发板,在顶层的Makefile中都会有一个配置选项。比如6410,在Makefile中的配置选项是make forlinx_nand_ram256_config:在vim的命令模式按下/,然后输入make forlinx_nand_ram256_config回车会定位到这里:

17.U-boot的工作流程分析-6410第2张

这是Makefile里的一个目标。这是来配置6410开发板的。看到上图第二行的smdk6410,这个参数决定了开发板的名称。这个名称是有作用的。接下来看看他的作用。

首先是找一下目录:

17.U-boot的工作流程分析-6410第3张

可以看到这里有很多smdk的子目录,也包括smdk6410,这两个是对应的。该目录存放的就是6410开发板相关的文件。里面有一个叫uboot.lds的文件,前面知道lds文件是连接器脚本。Uboot的整个过程的链接,是通过该脚本来链接控制的。打开该链接器脚本:

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/

OUTPUT_ARCH(arm)

ENTRY(_start)

SECTIONS

{

    . = 0x00000000;

    . = ALIGN(4);

    .text :

    {

     cpu/s3c64xx/start.o    (.text) //1可以看到位于代码段前端的文件是start.o,对应的是一个汇编文件。这个汇编文件会最先被运行。但是这个汇编代码里最先执行的代码是哪些呢?

     cpu/s3c64xx/s3c6410/cpu_init.o    (.text)

     cpu/s3c64xx/onenand_cp.o    (.text)

     cpu/s3c64xx/nand_cp.o    (.text)

     cpu/s3c64xx/movi.o (.text)

     *(.text)

     lib_arm/div0.o

    }

    . = ALIGN(4);

    .rodata : { *(.rodata) }

    . = ALIGN(4);

    .data : { *(.data) }

    . = ALIGN(4);

    .got : { *(.got) }

    __u_boot_cmd_start = .;

    .u_boot_cmd : { *(.u_boot_cmd) }

    __u_boot_cmd_end = .;

    . = ALIGN(4);

    .mmudata : { *(.mmudata) }

    . = ALIGN(4);

    __bss_start = .;

    .bss : { *(.bss) }

    _end = .;

}

首先是找到该文件:

17.U-boot的工作流程分析-6410第4张

上面u-boot-lds文件里,在sections的标识之上,有一行:ENTRY(_start)是整个程序的入口。所以就找找start.S文件里有没_start这个标识呢?一搜会马上看到该标号:

17.U-boot的工作流程分析-6410第5张

到这里,看到这个_start才是整个uboot工程的入口。

接下来是第一阶段的代码:

在Linux里,打开上一节创建好的,Source Insight里的uboot工程:

然后找到smdk6410的start.S:

17.U-boot的工作流程分析-6410第6张

接下来看uboot做了什么事,主要是通过注释来分析:

开发板一上电,它会跳转到start.S的中断向量表的开始处执行:

17.U-boot的工作流程分析-6410第7张

从它的注释:

所以1,:知道上电后是跳到中断向量表来执行。执行的第一条指令是b reset。

Start_code的实在start.S的下面定义的:

17.U-boot的工作流程分析-6410第8张

从注释知道,这是actual start code。进入之后,set the cpu to svc32 mode,设置cpu为SVC模式。

接着执行的代码是:

17.U-boot的工作流程分析-6410第9张

3.刷新I/D caches。

4.然后是关闭MMU和cache:

17.U-boot的工作流程分析-6410第10张

5.对外围的基地址进行初始化。

17.U-boot的工作流程分析-6410第11张

6.接着到了bl lowlevel_init

17.U-boot的工作流程分析-6410第12张

点击:17.U-boot的工作流程分析-6410第13张,然后在Symbol里输入:lowlevel_init:

17.U-boot的工作流程分析-6410第14张

会看到出现很多,然后在下面可以看到它们各自的目录。其实每一个开发板都对应一个lowlevel_init.S:

17.U-boot的工作流程分析-6410第15张

进入该文件:

7看到系统进入该文件做的第一件事是:led初始化:

17.U-boot的工作流程分析-6410第16张

17.U-boot的工作流程分析-6410第17张

17.U-boot的工作流程分析-6410第18张

上面是点亮led,是用来帮助调试程序。

8.接着是关闭开门狗的操作:

17.U-boot的工作流程分析-6410第19张

我们想到在2440里没有关闭看门狗,是不是忘记了呢?看看2440代码:

可以看到2440里的lowlevel_init.S的lowlevel_init标识有一个初始化系统时钟的:bl system_clock_init函数。进入该函数:

17.U-boot的工作流程分析-6410第20张

可以看到2440是在初始化系统时钟里关闭看门狗。

9.接着还有屏蔽中断的操作:

17.U-boot的工作流程分析-6410第21张

17.U-boot的工作流程分析-6410第22张

10.到这才初始化系统时钟:

17.U-boot的工作流程分析-6410第23张

17.U-boot的工作流程分析-6410第24张

11.接着初始化串口:

17.U-boot的工作流程分析-6410第25张

12.对nand进行简单初始化:

17.U-boot的工作流程分析-6410第26张

13.初始化内存:

17.U-boot的工作流程分析-6410第27张

17.U-boot的工作流程分析-6410第28张

17.U-boot的工作流程分析-6410第29张

17.U-boot的工作流程分析-6410第30张

17.U-boot的工作流程分析-6410第31张

17.U-boot的工作流程分析-6410第32张

17.U-boot的工作流程分析-6410第33张

17.U-boot的工作流程分析-6410第34张

17.U-boot的工作流程分析-6410第35张

初始完内存之后就返回start.S里:

17.U-boot的工作流程分析-6410第36张

返回:

17.U-boot的工作流程分析-6410第37张

14.跳转回来之后,由于我们选择的是NandFlash启动,所以是跳转到:

17.U-boot的工作流程分析-6410第38张

在2440里,是复制NandFlash里的内容到内存当中去。6410也是一样的:

Bl copy_from_nand。

17.U-boot的工作流程分析-6410第39张

15.接着不管MMU的使能操作:

17.U-boot的工作流程分析-6410第40张

我们看stack栈的初始化:

17.U-boot的工作流程分析-6410第41张

16.清除bss段:

17.U-boot的工作流程分析-6410第42张

最后同样是跳转到start_armboot:

17.U-boot的工作流程分析-6410第43张

我们在2440里讲过,start_armboot的代码,两个板子是同一个文件来的。所以6410的第二阶段与2440的一样的。只有board.c里面有。

验证看看是不是一样的:

三:

执行完上面,程序跳转到_start_armboot处执行:

17.U-boot的工作流程分析-6410第44张

上面的代码,通过伪指令ldr把_start_armboot的值装入pc指针,程序就会跳转到_start_armboot处执行。而此处的地址是start_armboot的地址。就是,程序会跳转到start_armboot函数处执行。就是把我们的pc指针跳转到内存去执行了

17.U-boot的工作流程分析-6410第45张

下面看看start_armboot的地址是不是在内存中。

配置uboot:make forlinx_nand_ram256_config,然后执行make。

17.U-boot的工作流程分析-6410第46张

然后看到生成的文件:

17.U-boot的工作流程分析-6410第47张

其中,u-boot是elf文件,u-boot.bin是二进制文件。

接下来对u-boot的elf文件,进行反汇编,看看start_armboot函数的地址:

arm-linux-objdump -D -S u-boot >dump

查看:

17.U-boot的工作流程分析-6410第48张

看到函数的其实地址cfe02ad0的地址是在内存里的。所以start.S里的:

17.U-boot的工作流程分析-6410第49张

实现了从垫脚石跳转到内存。但是,此时会发现在这里的起始地址被变为了cfe02ad0:

17.U-boot的工作流程分析-6410第50张

在第一阶段里,不是说启动地址是在0吗?为什么这里是cfe02ad0呢?还有就是为什么是这个地址。

前面的学习知道,当去链接一个程序的时候,程序由多个文件构成,起始地址是由链接器脚本决定的。在/home/samba/uboot/Uboot/6410/uboot/board/samsung/smdk6410里的u-boot.lds:

起始地址是0:

17.U-boot的工作流程分析-6410第51张

这里是0,为什么那里会是cfe02ad0呢?我们回到uboot的顶层目录,打开config.mk:

搜索text_base:

找到:

17.U-boot的工作流程分析-6410第52张

在这里-T $(LDSCRIPT)就是定义使用链接器脚本。后面的-Ttext 是制定代码段的基地址的。$(TEXT_BASE)。这里有两个起始地址,然而程序运行的时候以后面的TEXT_BASE的地址为准。它会覆盖掉LDSCRIPT这个地址。

TEXT_BASE是在board/Samsung/smdk6410/config.mk里定义的:

17.U-boot的工作流程分析-6410第53张

接下来就是测试验证一下,把他修改为50008000。然后程序编译:

17.U-boot的工作流程分析-6410第54张

修改之后,执行make。

17.U-boot的工作流程分析-6410第55张

反汇编:

arm-linux-objdump -D -S u-boot >dump

17.U-boot的工作流程分析-6410第56张

上面的起始地址变了,刚才制定的。

那起始地址为什么不是0呢?下图:

17.U-boot的工作流程分析-6410第57张

从上图可以看到,ldr PC,=start_armboot的跳转,把地址从垫脚石跳转到内存里。在前面的代码里,有用到b reset等跳转指令,为什么这不会跳转到内存去执行,而是还在垫脚石里呢?

例如:

17.U-boot的工作流程分析-6410第58张

上面的跳转,bl lowlevel_init的跳转地址:

17.U-boot的工作流程分析-6410第59张

为什么PC指针还是在垫脚石中呢?

这就得讲两个词了。绝对跳转和相对跳转

B和bl是相对跳转。

17.U-boot的工作流程分析-6410第60张

Ldr伪指令是绝对跳转:

17.U-boot的工作流程分析-6410第61张

第三阶段:

是从此函数Start_armboot进入的。主要完成的硬件和软件的初始化,只是一些基础的初始化。

该函数里有一个for循环:

17.U-boot的工作流程分析-6410第62张

在for里首先是让一个指针数组,把里面的函数指针依次调用一次,if里的判断语句就是函数指针。那么指针数组里有哪些函数指针呢。

指针数组:

17.U-boot的工作流程分析-6410第63张

可以看到里面都是函数指针。这里软件的初始化就不看了,我们只看硬件的初始化。在这些函数指针里,硬件初始化的有串口初始化。Serial_init。接着是lcd的初始化:

17.U-boot的工作流程分析-6410第64张

初始化网卡:

17.U-boot的工作流程分析-6410第65张

初始化led:

17.U-boot的工作流程分析-6410第66张

接着进入一个主循环:

17.U-boot的工作流程分析-6410第67张

执行用户输入的命令。例如tftp命令。这里是一个死循环。老是等待执行用户继续输入命令。在第一个阶段,每个开发板可能有不同的地方,但是在这个地方都是一样的。就是,在第二阶段都是跳到start_armboot处执行代码。2440的第一阶段是在start.S的b reset开始。

免责声明:文章转载自《17.U-boot的工作流程分析-6410》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇js动态获取虚拟目录名称 相当于服务端ResolveUrl("")方法S_ISREG等几个常见的宏 struct stat下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

ERP框架开发中的License许可验证机制设计与实现 (包含源代码下载)

ERP框架开发中的License许可验证机制设计与实现 (包含源代码下载) 许可机制是ERP框架中必不可少的一部分,可以有效的保护框架资源在授权范围内应用,增加企业投资的回报。在研究了几种类型的许可机制(序列号注册码,Web服务联机验证,授权License文件)后,最后选定以Signed Xml配合RSA算法,作为许可机制的主要技术实现。 主要达到的目的如...

12.bss段的初始化

12.bss段的初始化 在C代码:有初始化全局的数据段,局部的栈,malloc部分的堆,未初始化的全局的bss段。 从上面的编译的信息知道: Bss段的起始地址:0001052c Bss段的结束地址:00010534 我们的hello变量的地址:00010530是落在bss段里的地址的。所以是存在bss段的。这就是未初始化的全局变量存放在bss段...

CentOS7进程管理systemd详解

  概述: 系统启动过程中,当内核启动完成,后加载根文件系统,后就绪的一些用户空间的服务的管理工作,就交由init进行启动和管理,在CentOS6之前的init的管理方式都类似,相关的内容我们在之前的文章中也做出过介绍。在CentOS7上,init变成了systemd,其管理方式也发生了重大的变化,本章就跟大家欧一起探讨一些关于CentOS7上的sys...

webstorm中配置过visualsvn,后面做更改要更换authentication realm的解决办法

找这个找了好久,一直改不过来,终于找到了解决办法 首先,在提交代码时提示: 但是我的authentication realm已经时这个了,并且账号和密码也改了,所以要更改authentication realm。 使用的时候要安装TortoiseSVN,安装好之后数遍右键会提示相关的操作;在空白处右键,选择TortoiseSVN-重新定位,会弹出下面这个...

Samba服务的配置总结

之前介绍了Linux下Samba服务器部署,这里简单总结下Samba服务参数的配置说明: Samba服务的主配置文件是smb.conf,默认在/etc/samba/目录下。smb.conf含有多个段,每个段由段名开始,直到下个段名。每个段名放在方括号中间。每段的参数的格式是:名称=指。配置文件中一行一个段名和参数,段名和参数名不分大小写。除了[global...

[转]如何:在设备上安装 SQL Server Compact 3.5

将设备连接到计算机,或者将仿真程序插入底座。 有关更多信息,请参见如何:将设备仿真程序插入底座和移除底座。 说明: 计算机上必须已安装了 Windows Mobile Device Center 或 Microsoft ActiveSync。 在桌面计算机上,启动 Windows 资源管理器,然后转至文件夹 驱动器:Program File...