第一阶段:汇编语言启动
先看u-boot/board/davinci/dm365_ipnc/下的文件。

u-boot.lds

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
        . = 0x00000000;
        . = ALIGN(4);
        .text   :
        {
          cpu/arm926ejs/start.o (.text)
          *(.text)
        }
        . = 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 = .;
}

config.mk

TEXT_BASE = 0x81080000

board_init.s

#include <config.h>

.globl  dv_board_init
dv_board_init:
        mov     pc, lr

第一个要链接的是cpu/arm926ejs/start.o,那么U-Boot的入口指令一定位于这个程序中。进入/u-boot/cpu/arm926ejs/。

查看start.s。流程为:
reset(复位)——cpu_init_crit(初始化CACHE,关闭MMU)——lowlevel_init(davinci/lowlevel_init.S下,设置pll,mux,memory)——relocate(把U-boot重新定位到RAM)——copy_loop(重新定位代码)——stack_setup(初始化堆栈)——clear_bss(清零bss)——clbss_l(bss段地址空间清零循环)——_start_armboot (start_armboot函数在lib_arm/board.c中实现)

在/u-boot/cpu/arm926ejs/下还有一些文件:
root@ss-desktop:/camera/u-boot/cpu/arm926ejs# ls
at91       cpu.c      da8xx    interrupts.c  omap     versatile
config.mk  cpuinfo.c  davinci  Makefile      start.S
root@ss-desktop:/camera/u-boot/cpu/arm926ejs# ls davinci/
dp83848.c  i2c.c            lxt972.c  nand.c   timer.c
ether.c    lowlevel_init.S  Makefile  reset.S

第二阶段:C语言启动
lib_arm/board.c
    start_armboot是U-Boot执行的第一个C语言函数,完成系统初始化工作,进入主循环,处理用户输入的命令。

1、根据如下定义进行一系列初始化;
init_fnc_t *init_sequence[] = {
    cpu_init,        /* basic cpu dependent setup 基本的处理器相关配置--cpu/arm926ejs/cpu.c */
#if defined(CONFIG_SKIP_RELOCATE_UBOOT)
    reloc_init,        /* Set the relocation done flag, must do this AFTER cpu_init(), but as soon as possible--lib_arm/board.c */
#endif
    board_init,        /* basic board dependent setup 基本 的板级相关配置--board/davinci/dm365_ipnc/dm365_board.c */
    interrupt_init,        /* set up exceptions 初始化中断处理--cpu/arm926ejs/interrupts.c */
    env_init,        /* initialize environment 初始化环境变量--common/cmd_flash.c(??) */
    init_baudrate,        /* initialze baudrate settings 初始化波特率设置--lib_arm/board.c */
    serial_init,        /* serial communications setup 串口通讯设置*/
    console_init_f,        /* stage 1 init of console 控制台初始化阶段1--/common/console.c*/
    display_banner,        /* say that we are here 打印u-boot信息--/lib_arm/board.c */
#if defined(CONFIG_DISPLAY_CPUINFO)
    print_cpuinfo,        /* display cpu info (and speed) */
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
    checkboard,        /* display board info */
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
    init_func_i2c,
#endif
    dram_init,        /* configure available RAM banks 配置可用的RAM --board/davinci/dm365_ipnc/dm365_board.c */
    display_dram_config,   /*显示RAM的配置大小 --/lib_arm/board.c */
    NULL,
};

2、进行nand初始化
使用driver/mtd/nand.c中的nand_init()

3、设备初始化及控制台初始化
使用common/devices.c中的devices_init();进行各设备的初始化,包括网络控制台设备的初始化drv_nc_init();在初始化过程中将dev注册到全局链表devlist中;
使用common/console.c中的console_init_r();这个函数中可将设备的读写接口挂在控制台的读写接口即标准输入/输出上,以实现对不同设备的适配;具体而言是由console_setfile()将dev挂入stdio_devices[file]数组;

4、各类杂项初始化,包括对eth的配置
misc_init_r()

5、进行ether的MII和PHY进行初始化
使用net/eth.c中的eth_initialize()

6、main_loop   /*总是试图自启动,循环不断执行*/
等待控制台命令,该命令可通过键盘输入或或者通过网络输入,不过对于main_loop命令解析层而言是透明的;

至此启动完成。

第三阶段:启动完全,开始运行
1. main_loop()在common/main.c中
1.1 读命令readline()
由于getc最终会调用设备读接口[stdio_devices[file]->getc ()],因此此前将控制台适配为哪种设备,则现在就是和哪种设备通信;

1.2 执行命令run_command()
各种命令通过U_BOOT_CMD宏被链接器搜集到.u_boot_cmd所在的__u_boot_cmd_start和 __u_boot_cmd_end区间中;具体参考include/comman.h和board/davinci/dm365/u-boot.lds;
Find_cmd中,从__u_boot_cmd_start开始查找对应命令结构体变量;如果是tftp等网络命令,则执行 do_tftpb()->netboot_common()->NetLoop();

2. netloop()
在for (;;)循环中使用eth_rx()不断接收数据,同时通过一状态机决定是否处理完毕;

3. eth_rx()
这个函数实际上实现了数据由网络到上层协议栈再到应用层解析的整个过程,应用解析后会更改状态机状态;
对于tftp则是在tftp_start时由于利用NetSetHandler()指定了全局量packetHandler为TftpHandler;因此根据如下调用关系eth_rx()->net_receive()->packetHandler(),可知数据被tftphandler 处理并修改Netstate状态值;

4. nand
对于nand的write操作稍需注意,由于nand是按“与”操作才能写入,也就是擦除后,写入前nand中的bit值必须是1。这就意味着所写如果是 1,将不使nand的bit改变。在uboot nand的驱动中对于oob的fill也正是利用了这一点。看似将memory中的oob数据写到了nand oob中,但由于memory中的oob各bit是1,因此对nand oob值不产生影响。

第四阶段:U-boot引导内核
1. go命令的实现
    go命令调用 common/cmd_boot.c下do_go()函数,跳转到某个地址执行。如果在这个地址准备好了自引导的内核映像,就可以启动了。尽管go命令可以带变参,实际使用时一般不用来传递参数。

2. bootm命令的实现
    bootm命令调用 common/cmd_bootm.c下的do_bootm函数,这个函数专门用来引导各种操作系统,可以支持引导Linux、vxworks等操作系统。引导Linux时,调用do_boom_linux()函数。

3. do_bootm_linux函数的实现
    do_bootm_linux函数在lib_arm/bootm.c下,是专门引导Linux映像的函数,它还可以处理ramdisk文件系统的映像。

DM365 u-boot 启动分析相关推荐

  1. Spring Boot启动过程源码分析--转

    https://blog.csdn.net/dm_vincent/article/details/76735888 关于Spring Boot,已经有很多介绍其如何使用的文章了,本文从源代码(基于Sp ...

  2. Spring Boot(四):Spring Boot启动原理分析

    文章目录 Spring Boot启动原理分析 一.依赖导入原理 二.Spring Boot包扫描原理 三.Spring Boot自动配置原理 Spring Boot启动原理分析 一.依赖导入原理 父项 ...

  3. Spring Boot————Spring Boot启动流程分析

    一.引言 Spring Boot 的启动虽然仅仅是执行了一个main方法,但实际上,运行流程还是比较复杂的,其中包含几个非常重要的事件回调机制.在实际生产开发中,有时候也会利用这些启动流程中的回调机制 ...

  4. 全志h3linux移植教程,全志H3启动分析,移植主线UBOOT

    全志H3启动分析,移植主线UBOOT 参考资源 启动流程 因为使用的是外扩SD卡,因此主要参考了这部分内容:Bootable SD card SD卡Layout如下: start sector siz ...

  5. 浅谈:Spring Boot原理分析,切换内置web服务器,SpringBoot监听项目(使用springboot-admin),将springboot的项目打成war包

    浅谈:Spring Boot原理分析(更多细节解释在代码注释中) 通过@EnableAutoConfiguration注解加载Springboot内置的自动初始化类(加载什么类是配置在spring.f ...

  6. Uboot启动分析--start.S启动分析(1)

    总目录 NXP i.MX8M secure boot流程 Uboot链接脚本分析述 Uboot启动分析–start.S启动分析(1) Uboot启动分析–start.S启动分析(2) Uboot启动分 ...

  7. BSP板机支持包、linux启动分析、ARM裸机编程

    文章目录 一.BSP 二.驱动 驱动的基本要素 三.启动分析 1.uboot 2.uboot的作用 3.uboot相关命令 关键的内容: 1)bootargs,启动参数 2)启动命令 3)修改启动延时 ...

  8. UEFI启动视频详解:启动分析+N项操作实例

    ============================================================= ※※※※最给力的视频解说※※※※ 2011hiboy全部共享资料:立刻去   ...

  9. 内核启动分析(三)——zImage 解压缩阶段

          在上阶段,主要是U-BOOT 向内核传递一些参数.而这些参数是通过 struct tag来传递的.U-boot 把要传递给 kernel 的东西保存在 struct tag 数据结构中,启 ...

  10. 1617_MIT 6.828 JOS boot代码分析

    全部学习汇总: GreyZhang/g_unix: some basic learning about unix operating system. (github.com) JOS的这部分boot相 ...

最新文章

  1. 蚂蚁森林最高效的合种团队—招募队友云植树,最快1天1颗树
  2. 加强版dd工具dc3dd
  3. Android Sensor——传感器
  4. firefox火狐浏览器怎么清除缓存 火狐浏览器清理cookie教程
  5. python图像增强_【Tool】Augmentor和imgaug——python图像数据增强库
  6. idea 调试 js
  7. [Linux] 动态库加载顺序
  8. 了解HTML CSS格式化排版 文字排版
  9. php 单例 重连,PHP单例模式详解
  10. Balanced Numbers数位dp
  11. oem718d 基准站设置_诺瓦泰NovAtel OEM718D全系统多频单机测向板卡
  12. python精通 epub_跟老齐学Python:从入门到精通[azw3+epub+mobi][8.59MB]
  13. 小程序页面收录 sitemap
  14. 搭建Cacti监控(2)
  15. 数学公式div是什么意思
  16. 正則表達式基本使用方法简单介绍
  17. java实现记录日志
  18. HDU 1042 N!(大数阶乘)
  19. UltraISO制作U盘启动盘安装Win7/9/10系统攻略
  20. CNV学习2(illumina芯片分析CNV的主流软件------PennCNV)

热门文章

  1. 面试题3:二维数组查找
  2. 【javascript】操作符:一元操作符
  3. 【转】最牛B的编码套路
  4. (WPF) DataGrid之绑定
  5. 登录页面跳出框架的JS
  6. iOS10 权限访问崩溃
  7. 微信小程序设置底部导航栏目方法
  8. tornado 学习笔记17 HTTPServerRequest分析
  9. background image
  10. WordPress get_allowed_mime_types函数(wp-includes/functions.php)存在跨站脚本漏洞