zoukankan      html  css  js  c++  java
  • IMX6 uboot的启动流程

    网上看了后,做了个记录,主要是一个流程,具体代码没有分析,有空再细看。

    cpu在上电之后,它们会干些什么?

    答:检查电压大小,确定启动模式等。

    简单的检查之后呢?

    答:一般从固化在cpu内部的rom里面执行一小段code。这一小段code具体做了些什么呢?各个cpu厂商会不同,具体我也不知道。

    但是我们应该知道,这小段code必须完成确认启动模式,并初始化启动设备,搬移烧录在启动设备里面的代码到ddr里面。

    ok,搬移了代码后,cpu如何识别代码?将doc,txt文件烧进去行么?

    答:当然不行,烧录的文件也是有格式要求的。

    格式在哪里定呢?稍等,先要知道生成的uboot.bin文件需要有个指导文件,就是uboot.lds,它的作用是在编译过程中,决定各个可执行程序段的位置。

    其代码如下:

     1 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
     2 OUTPUT_ARCH(arm)
     3 ENTRY(_start)
     4 SECTIONS
     5 {
     6     . = 0x00000000;
     7 
     8     . = ALIGN(4);
     9     .text       :
    10     {
    11       /* WARNING - the following is hand-optimized to fit within    */
    12       /* the sector layout of our flash chips!    XXX FIXME XXX    */
    13       board/freescale/mx6q_sabreauto/flash_header.o    (.text.flasheader)
    14       cpu/arm_cortexa8/start.o
    15       board/freescale/mx6q_sabreauto/libmx6q_sabreauto.a    (.text)
    16       lib_arm/libarm.a        (.text)
    17       net/libnet.a            (.text)
    18       drivers/mtd/libmtd.a        (.text)
    19       drivers/mmc/libmmc.a        (.text)
    20 
    21       . = DEFINED(env_offset) ? env_offset : .;
    22       common/env_embedded.o(.text)
    23 
    24       *(.text)
    25     }
    26 
    27     . = ALIGN(4);
    28     .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
    29 
    30     . = ALIGN(4);
    31     .data : { *(.data) }
    32 
    33     . = ALIGN(4);
    34     .got : { *(.got) }
    35 
    36     . = .;
    37     __u_boot_cmd_start = .;
    38     .u_boot_cmd : { *(.u_boot_cmd) }
    39     __u_boot_cmd_end = .;
    40 
    41     . = ALIGN(4);
    42     _end_of_copy = .; /* end_of ROM copy code here */
    43     __bss_start = .;
    44     .bss : { *(.bss) }
    45     _end = .;
    46 }
    View Code

    代码咱不分析,只看 

    .text    :
     {
       /* WARNING - the following is hand-optimized to fit within */
       /* the sector layout of our flash chips! XXX FIXME XXX */
       board/freescale/mx6q_sabreauto/flash_header.o (.text.flasheader)

    ......

    它的第一要存储的文件是flash_header的内容。回到主题,cpu如何识别代码?在第一个存储的文件里面,必须要有特定的格式。这里称作:IVT(image vector table)结构体。

    good,cpu通过这个结构体规定的顺序来执行。其定义如下:(网上摘录)

    header
    entry: Absolute address of the first instruction to execute from the image
    reserved1: Reserved and should be zero
    dcd: Absolute address of the image DCD. The DCD is optional so this field may be set to NULL if no DCD is required. See
    Device Configuration Data (DCD) for further details on DCD.
    boot data: Absolute address of the Boot Data
    self: Absolute address of the IVT. Used internally by the ROM
    csf: Absolute address of Command Sequence File (CSF) used by the HAB library. See High Assurance Boot (HAB) for
    details on secure boot using HAB. This field must be set to NULL when not performing a secure boot
    reserved2: Reserved and should be zero

    我们关心以下几个:
    entry: 入口函数,在程序中指定,如:ENTRY(_start)
    dcd: Device Configuration Data, 设备配置数据,用来配置设备的。因为刚上电,设备的参数都是默认的,不能达到最优效果,甚至有些设备不进行初始化根本就无法工作。
    那怎么办呢?就需要在使用这些设备之前,进行一些设置,如内存等等。
    dcd中可以设置如下这些东东:
    Address range                                      Start address       Last Address
    IOMUX Control (IOMUXC) registers     0x020E0000        0x020E3FFF
    CCM register set                                   0x020C4000        0x020C7FFF
    ANADIG registers                                 0x020C8000        0x020C8FFF
    MMDC register set                                0x021B0000        0x021B7FFF
    IRAM Free Space                                 0x00907000        0x00937FF0
    EIM                                                       0x08000000        0x0FFEFFFF
    DDR                                                      0x10000000        0xFFFFFFFF

    ////////////////////////////////////////////////////////////////////////////////////////////////////

    ok,既然知道了cpu要执行的顺序,那我们来看看这是个什么顺序,打开flash_header.S

     1 .section ".text.flasheader", "x"
     2     b    _start
     3     .org    CONFIG_FLASH_HEADER_OFFSET
     4 
     5 ivt_header:       .word 0x402000D1 /* Tag=0xD1, Len=0x0020, Ver=0x40 */
     6 app_code_jump_v:  .word _start
     7 reserv1:          .word 0x0
     8 dcd_ptr:          .word dcd_hdr
     9 boot_data_ptr:      .word boot_data
    10 self_ptr:         .word ivt_header
    11 #ifdef CONFIG_SECURE_BOOT
    12 app_code_csf:     .word __hab_data
    13 #else
    14 app_code_csf:     .word 0x0
    15 #endif
    16 reserv2:          .word 0x0
    17 
    18 boot_data:        .word TEXT_BASE
    19 #ifdef CONFIG_SECURE_BOOT
    20 image_len:        .word __hab_data_end - TEXT_BASE + CONFIG_FLASH_HEADER_OFFSET
    21 #else
    22 image_len:        .word _end_of_copy  - TEXT_BASE + CONFIG_FLASH_HEADER_OFFSET
    23 #endif
    24 plugin:           .word 0x0

    dcd的配置在dcd_ptr:          .word dcd_hdr。uboot首先就要通过这个地址段来配置和优化ddr。
    boot_data_ptr:      .word boot_data启动代码放置的地方及大小。

    app_code_jump_v:  .word _start  第一个执行的函数。

    以上文件大多在:/board/freescale/mx6q_sabresd/ 目录下。

    罗里吧嗦那么多,自己都有点乱了,艹,其实就是一个uboot.bin文件要被识别,必须在其文件头的地方,有一个正确的格式。就这样!然后根据这个格式,开启我们的启动之旅吧。

    第一阶段:start.S    /cpu/arm_cortexa8/start.S

    主要完成定义入口地址、设置异常向量、设置CPU的频率、初始化内存控制器、加载Uboot第二阶段代码代码到RAM、初始化堆栈、跳转到RAM运行第二阶段程序。

    第二阶段:lib_arm/board.c中的start_armboot是第二阶段开始的代码,其主要完成系统内核、中断、时钟、接口、设备包括FLASH、DISPLAY、网络等的初始化,并进入命令循环,接收用户命令后完成相应的工作。

    在第二阶段的main_loop函数中,根据设置的参数,可在uboot环境下调试或调转到内核。具体可以网上参考。main_loop-->run_command-->do_bootm_linux.

    大概就是这个流程,代码没分析,见谅!

    参照:

    http://blog.csdn.net/njuitjf/article/details/20563867

    http://blog.csdn.net/sz_zh/article/details/7930341

    谢谢!

  • 相关阅读:
    linux查看端口
    linux下Git代码
    linux安装mysql
    pip工具更新及解决"No module named pip"问题
    demo-bootstrap实现滑动开关
    vue 随笔
    css 解决盒子移动鼠标丢失产生的抖动问题
    笔记-纯css实现select的placeholder
    笔记-移动端rem适配和解决安卓手机键盘唤起引起样式问题
    demo-tab切换
  • 原文地址:https://www.cnblogs.com/cyc2009/p/4077430.html
Copyright © 2011-2022 走看看