uboot启动分析

本文详细阐述了UBOOT启动流程,包括链接脚本分析、中断向量表设置、内存布局初始化、全局数据gd的结构和作用,以及重定位过程,强调了位置无关代码和环境配置的重要性。

uboot启动分析

uboot是一个操作系统引导程序,多用于嵌入式设备上linux操作系统的引导。它是一个裸机程序,启动流程对其他裸机系统的启动都具有参考意义。下面,我们一起学习一下uboot的启动流程。

uboot的启动流程如下图所示:

我们对启动流程进行分析时,首先需要分析其链接脚本uboot.lds,从中了解大概的镜像布局,来知道程序的入口,以及一些特殊的地址变量定义,段等。

uboot程序的最开始为_start,从_start开始,是中断向量表的定义,这是大多数嵌入式裸机程序的共识,它们总是以复位中断为入口,进入整个系统。在uboot_start标号开始处,我们可以看到复位中断的中断处理程序入口b reset,这样就来到了reset复位程序处。

reset程序是系统启动或复位后执行的程序,因此,其第一步就是设置处理器为SVC,关闭FRQIRQ,以确定处理器的工作模式(SVC:处于特权模式,且有自己的影子寄存器;关中断:中断尚没有配置,防止程序中断引起的程序异常);第二步,立马就进行中断向量表的设置,使中断能够执行,这对用户来说是一个高优先级的配置任务;第三步,也是做一些需要尽快确定的系统状态,比如关闭MMUTLBsD-cache,打开I-cache等相关的操作,以及初始化栈指针使得C语言函数能够调用;这样,复位后基本的极简环境就设置好了,我们可以进一步执行uboot相关程序,进入_main

_main就是uboot的进一步初始化了,其有了前面搭建的极简环境。第一步初始化早期mallocgd全局数组(gd全局数组用于保存uboot的一些重要信息,例如镜像的开始地址,镜像的重装载地址,malloc地址等等,这在后面再详细展开说明),调用board_init_f来执行一系列的函数来初始化硬件和gd结构体。其中,硬件初始化主要是初始化RAM(SRAM,DDR),因为后面重定位uboot需要对RAM进行读写操作,是必要的初始化;其主要的就是进行gd结构体的初始化,完成了完整的内存布局,和其中各种变量的赋值。第二步就是对自己进行重定位,这一部分挺重要的,主要就是需要先将自己拷贝到重定位地址,然后修改.rel.dyn段的位置无关码,最后对环境进行重新配置。因为运行地址进行了变化,所以程序必须是位置无关的,在编译的时候加上-pie选项就可以将它编译成位置无关的,其会将程序中的绝对地址的地址都收集到一个特殊的段rel.dyn中,那么,在进行重定位的时候,只需将该段中记录的地址的数进行一个修改即可,详细过程在后文讲述。第三步,调用board_init_r函数来执行一系列函数,进行最终的uboot初始化,包括malloc,各种板级初始化等,最后调用run_main_loop,进入uboot命令行处理程序。

run_main_loop在开始时会进入倒计时,倒计时结束则会执行bootcmd环境变量中的命令,启动linux之类的系统;在倒计时被按键中断的话会进入cli_loop命令行处理程序,接收用户的指令执行。这部分就是uboot的用户应用功能了,启动流程就到此结束。

以上就是uboot启动流程的全部内容了,关于linux启动方面不属于启动流程的内容,是uboot实现的功能,在以后的文章中说明。下面,就上面提到的几个中间进行展开介绍。

gd全局变量

gd全局变量贯穿整个uboot启动,在前面的启动流程中我们看到了其中存储了重要的地址信息,暗含了内存布局,下面是它的结构体原型中的某些项,我们一起来体会一下它究竟是哪些内容:

typedef struct global_data {
        bd_t *bd;
        unsigned long flags;
        unsigned int baudrate;
        unsigned long cpu_clk;  /* 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值