加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

UBOOT启动流程分析

发布时间:2020-12-15 18:37:46 所属栏目:百科 来源:网络整理
导读:UBOOT特点: 用于多种CPU 用于多种操作系统 查看一下board/smdk2410/u-boot.lds这个链接脚本,可以知道目标程序的各部分链接顺序 ? OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm","elf32-littlearm") /*OUTPUT_FORMAT("elf32-arm","elf32-arm","elf32-

UBOOT特点:

用于多种CPU

用于多种操作系统


查看一下board/smdk2410/u-boot.lds这个链接脚本,可以知道目标程序的各部分链接顺序

?

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);??????????????????????????????????????????????????????????? //伪操作,4字节对齐

????????????????? .text????? :

????????????????? {

????????????????? ? cpu/arm920t/start.o?? (.text)????????????????????????? //指定程序的执行代码段,即start.o文件,

????????????????? ? *(.text)?????????????????????????????????????????????????????????????????????????? //则在最先执行的程序应该是start.s

????????????????? }

?

????????????????? . = 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);

????????????????? __bss_start = .;

????????????????? .bss (NOLOAD) : { *(.bss) }

????????????????? _end = .;

}

?

下面分析cpu/arm920t/start.s文件:

ENTRY(_start)指定了从_start开始执行,?

这个汇编程序是U-Boot的入口程序,开头就是复位向量的代码。

_start: b?????? reset??????? //复位向量

?????? ldr??pc,_undefined_instruction

?????? ldr??pc,_software_interrupt

?????? ldr??pc,_prefetch_abort

?????? ldr??pc,_data_abort

?????? ldr??pc,_not_used

?????? ldr??pc,_irq????? //中断向量

?????? ldr??pc,_fiq????? //中断向量

?/* the actual reset code? */

reset:????????? //复位启动子程序

?????? /* 设置CPU为SVC32模式 */

?????? mrs??r0,cpsr?????????????????????????????? /*修改cpsr时,通过将其拷贝到通用寄存器修改*/

?????? bic??r0,r0,#0x1f

?????? orr??r0,#0xd3

?????? msr??cpsr,r0

?

/* 关闭看门狗 */

……????? ……

relocate:????????????????? /* 把U-Boot重新定位到RAM */

adr?? r0,_start????????? /* r0是代码的当前位置 */

ldr?? r1,_TEXT_BASE????? /*_TEXT_BASE是RAM中的地址 */

cmp???? r0,r1????????? /* 比较r0和r1,判断当前是从Flash启动,还是RAM */

beq???? stack_setup? /* 如果r0等于r1,跳过重定位代码 */

?

/* 准备重新定位代码 */

ldr?? r2,_armboot_start

ldr?? r3,_bss_start

sub?? r2,r3,r2?????? /* r2 得到armboot的大小?? */

add?? r2,r2????? /* r2 得到要复制代码的末尾地址 */

copy_loop: /* 重新定位代码 */

ldmia r0!,{r3-r10}?? /*从源地址[r0]复制 */

stmia r1!,{r3-r10}?? /* 复制到目的地址[r1]*/

cmp?? r0,r2???/* 复制数据块直到源数据末尾地址[r2] */

ble?? copy_loop

?

/* 初始化堆栈等??? */

stack_setup:

ldr?? r0,_TEXT_BASE? /* 上面是128 KiB重定位的u-boot */

sub?? r0,#CFG_MALLOC_LEN? /* 向下是内存分配空间 */

sub?? r0,#CFG_GBL_DATA_SIZE /* 然后是bdinfo结构体地址空间? */

#ifdefCONFIG_USE_IRQ

sub r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

#endif

sub?? sp,#12???? /* 为abort-stack预留3个字 */

clear_bss:

ldr?? r0,_bss_start????? /* 找到bss段起始地址 */

ldr?? r1,_bss_end??????? /*?bss段末尾地址?? */

mov?? r2,#0x00000000???? /* 清零 */

clbss_l:str r2,[r0]??

/* bss段地址空间清零循环...? */

?????? add??r0,#4

?????? cmp??r0,r1

bne?? clbss_l

?

/* 跳转到start_armboot函数入口,_start_armboot字保存函数入口指针 */

ldr?? pc,_start_armboot

_start_armboot:.word start_armboot???? //start_armboot函数在lib_arm/board.c中实现

?

第二阶段

2.lib_arm/board.c

start_armboot是U-Boot执行的第一个C语言函数,完成系统初始化工作,进入主循环,处理用户输入的命令。

?

3.init_sequence[]

init_sequence[]数组保存着基本的初始化函数指针。

?

init_fnc_t*init_sequence[] = {

cpu_init,?? /* 基本的处理器相关配置 --cpu/arm920t/cpu.c */

board_init,/* 基本的板级相关配置 --board/smdk2410/smdk2410.c */

interrupt_init,? /* 初始化中断处理 --cpu/arm920t/s3c24x0/interrupt.c */

env_init,????? /* 初始化环境变量 --common/cmd_flash.c */

init_baudrate,? /* 初始化波特率设置 --lib_arm/board.c */

serial_init,? /* 串口通讯设置 --cpu/arm920t/s3c24x0/serial.c */

console_init_f,?????? /* 控制台初始化阶段1 --common/console.c */

display_banner,?????? /* 打印u-boot信息 --lib_arm/board.c */

dram_init,???? /* 配置可用的RAM --board/smdk2410/smdk2410.c */

display_dram_config,? /* 显示RAM的配置大小 --lib_arm/board.c */

NULL,

};

voidstart_armboot (void)

{

/* 顺序执行init_sequence数组中的初始化函数 */

?????? for (init_fnc_ptr = init_sequence;*init_fnc_ptr; ++init_fnc_ptr) {

????????????? if ((*init_fnc_ptr)() != 0) {

????????????????????? hang ();

????????????? }

?????? }

/*配置可用的Flash */

?????? size = flash_init ();

?????? display_flash_config (size);

?????? /* _armboot_start 在u-boot.lds链接脚本中定义 */

? ?????mem_malloc_init (_armboot_start -CFG_MALLOC_LEN);

?

/* 配置环境变量*/

env_relocate ();

?

/* 从环境变量中获取IP地址 */

gd->bd->bi_ip_addr= getenv_IPaddr ("ipaddr");

/* 以太网接口MAC 地址 */

?????? ……

?????? devices_init ();????? /* 获取列表中的设备 */

?????? jumptable_init ();

?????? console_init_r ();??? /* 完整地初始化控制台设备 */

?????? enable_interrupts (); /* 使能中断处理 */

/* 通过环境变量初始化 */

?????? if ((s = getenv ("loadaddr"))!= NULL) {

?????????????? load_addr = simple_strtoul (s,NULL,16);

?????? }

/* main_loop()循环不断执行 */

for (;;)

{

?????main_loop ();????? /* 主循环函数处理执行用户命令-- common/main.c */

}


注:参考国嵌视频

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读