u-boot版本: v2009.08

在分析代码前,我们需要先了解两个知识点。

1. 链接脚本

路径: uboot-imx/board/freescale/mx6q_sabresd/u-boot.lds

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{. = 0x00000000;. = ALIGN(4);.text     :{/* WARNING - the following is hand-optimized to fit within *//* the sector layout of our flash chips!  XXX FIXME XXX   */board/freescale/mx6q_sabresd/flash_header.o   (.text.flasheader)cpu/arm_cortexa8/start.oboard/freescale/mx6q_sabresd/libmx6q_sabresd.a    (.text)lib_arm/libarm.a     (.text)net/libnet.a         (.text)drivers/mtd/libmtd.a     (.text)drivers/mmc/libmmc.a     (.text). = DEFINED(env_offset) ? env_offset : .;common/env_embedded.o(.text)*(.text)}
......
}

有看到flash_header.S被作为u-boot运行的第一个文件,而不是start.S,请注意这点。

2. Program Image

听标题名字有点抽象,其实就是IMX平台内部自带ROM, 然后CPU从ROM开始运行,接着ROM会读取u-boot,

它需要知道当前u-boot的信息,所以默认规定了编译出来都需要一个所谓的Program Image, 由以下几部分组成:

Program Image的布局格式如下:

格式说明如下:

从上面第一条分析可知,ROM会先去执行flash_header.S里,来看flash_header.S.

#include <config.h>
#include <asm/arch/mx6.h>#ifdef   CONFIG_FLASH_HEADER
#ifndef CONFIG_FLASH_HEADER_OFFSET
# error "Must define the offset of flash header"
#endif#define CPU_2_BE_32(l) \((((l) & 0x000000FF) << 24) | \(((l) & 0x0000FF00) << 8)  | \(((l) & 0x00FF0000) >> 8)  | \(((l) & 0xFF000000) >> 24))
/*.word可以理解成c语言中的 addr = val,后面ddr操作寄存器会用它。*/
#define MXC_DCD_ITEM(i, addr, val)   \
dcd_node_##i:                        \.word CPU_2_BE_32(addr) ;     \.word CPU_2_BE_32(val)  ;     \
/*定义一个段名*/
.section ".text.flasheader", "x"/*跳转到_start,后面展开。*/b    _start/*.org表示后面的代码将会被放到CONFIG_FLASH_HEADER_OFFSET,注意此命令只是链接时候起作用,不是一条伪指令。#define CONFIG_FLASH_HEADER_OFFSET 0x400也就是说code会被放到当前偏移1K的地方,uboot-imx/board/freescale/mx6q_sabresd/config.mk中有TEXT_BASE = 0x27800000所以flash_header.s的text base是0x2780000,而从System.map中也可以看到:27800400 t ivt_header确实如此。*/.org    CONFIG_FLASH_HEADER_OFFSET
/*
Tag: A single byte field set to 0xD1
Length: a two byte field in big endian format containing the overall length of the IVT,
in bytes, including the header. (the length is fixed and must have a value of
32 bytes)
Version: A single byte field set to 0x40 or 0x41
*/
ivt_header:       .word 0x402000D1 /* Tag=0xD1, Len=0x0020, Ver=0x40 */
/*即上面的entry标签,第一条指令的地址,u-boot的执行就从这里开始的了,也就是start.S中的第一条指令。*/
app_code_jump_v:  .word _start
reserv1:          .word 0x0
/*dcd的地址*/
dcd_ptr:          .word dcd_hdr
/*u-boot加载到哪个ram地址。*/
boot_data_ptr:    .word boot_data
/*保存自己的开始地址*/
self_ptr:         .word ivt_header
#ifdef CONFIG_SECURE_BOOT
app_code_csf:     .word __hab_data
#else
app_code_csf:     .word 0x0
#endif
reserv2:          .word 0x0/*加载到0x27800000*/
boot_data:        .word TEXT_BASE
#ifdef CONFIG_SECURE_BOOT
image_len:        .word __hab_data_end - TEXT_BASE + CONFIG_FLASH_HEADER_OFFSET
#else
/*整个image长度,扣除掉前1k.*/
image_len:        .word _end_of_copy  - TEXT_BASE + CONFIG_FLASH_HEADER_OFFSET
#endif
plugin:           .word 0x0#if defined CONFIG_MX6DL_DDR3
......
#else  /* i.MX6Q */
/*DCD不仅可以配置ddr,还可以配置其他外设,参考文档注释:
Upon reset, the Chip uses the default register values for all peripherals in the system.
However, these settings typically are not ideal for achieving optimal system performance
and there are even some peripherals that must be configured before they can be used.
The DCD is configuration information contained in a Program Image, external to the
ROM, that the ROM interprets to configure various peripherals on the Chip.
For example, the EIM default settings allow the core to interface to a NOR flash device
immediately out of reset. This allows the Chip to interface with any NOR flash device,
but has the cost of slow performance. Additionally, some components such as DDR
require some sequence of register programming as part of configuration before it is ready
to be used. The DCD feature can be used to program the EIM registers and MMDC
registers to the optimal settings.*/
/*
Tag: A single byte field set to 0xD2
Length: a two byte field in big endian format containing the overall length of the DCD,
in bytes, including the header
Version: A single byte field set to 0x41
*/
dcd_hdr:          .word 0x40a002D2 /* Tag=0xD2, Len=83*8 + 4 + 4, Ver=0x40 */
/*
Tag: A single byte field set to 0xCC
Length: A two byte field in big endian format containing the length of the Write Data
Command, in bytes, including the header
Parameters: is a single byte divided into bitfields as flags and bytes:bytes: width of target locations in bytes. Either 1, 2 or 4flags: control flags for command behavior.Data Mask = bit 3: if set, only specific bits may be overwritten at target address(otherwise all bits may be overwritten)Data Set = bit 4: if set, bits at the target address overwritten with this flag(otherwise it is ignored)
*/
write_dcd_cmd:    .word 0x049c02CC /* Tag=0xCC, Len=83*8 + 4, Param=0x04 *//*Kris, 20151224, Change to 2GB configuration. {*/
#if 0
......
#else
<pre name="code" class="cpp">/*下面开始就是对ddr的配置参数了,参考ddr spec来定制。*/
/* DCD */
/* DDR3 initialization based on the MX6Q Auto Reference Design (ARD) */
/* DDR IO TYPE: */
MXC_DCD_ITEM(1, IOMUXC_BASE_ADDR + 0x798, 0x000C0000)
MXC_DCD_ITEM(2, IOMUXC_BASE_ADDR + 0x758, 0x00000000)
/* CLOCK: */
MXC_DCD_ITEM(3, IOMUXC_BASE_ADDR + 0x588, 0x00000030)
MXC_DCD_ITEM(4, IOMUXC_BASE_ADDR + 0x594, 0x00000030)
/* ADDRESS: */
MXC_DCD_ITEM(5, IOMUXC_BASE_ADDR + 0x56c, 0x00000030)
MXC_DCD_ITEM(6, IOMUXC_BASE_ADDR + 0x578, 0x00000030)
MXC_DCD_ITEM(7, IOMUXC_BASE_ADDR + 0x74c, 0x00000030)
/* CONTROL: */
MXC_DCD_ITEM(8, IOMUXC_BASE_ADDR + 0x57c, 0x00000030)
MXC_DCD_ITEM(9, IOMUXC_BASE_ADDR + 0x58c, 0x00000000)
/* configured using Group Control Register: IOMUXC_SW_PAD_CTL_GRP_CTLDS */
MXC_DCD_ITEM(10, IOMUXC_BASE_ADDR + 0x59c, 0x00000030)
MXC_DCD_ITEM(11, IOMUXC_BASE_ADDR + 0x5a0, 0x00000030)
MXC_DCD_ITEM(12, IOMUXC_BASE_ADDR + 0x78c, 0x00000030)
/* DATA STROBE: */
MXC_DCD_ITEM(13, IOMUXC_BASE_ADDR + 0x750, 0x00020000)
MXC_DCD_ITEM(14, IOMUXC_BASE_ADDR + 0x5a8, 0x00000028)
MXC_DCD_ITEM(15, IOMUXC_BASE_ADDR + 0x5b0, 0x00000028)
MXC_DCD_ITEM(16, IOMUXC_BASE_ADDR + 0x524, 0x00000028)
MXC_DCD_ITEM(17, IOMUXC_BASE_ADDR + 0x51c, 0x00000028)
MXC_DCD_ITEM(18, IOMUXC_BASE_ADDR + 0x518, 0x00000028)
MXC_DCD_ITEM(19, IOMUXC_BASE_ADDR + 0x50c, 0x00000028)
MXC_DCD_ITEM(20, IOMUXC_BASE_ADDR + 0x5b8, 0x00000028)
MXC_DCD_ITEM(21, IOMUXC_BASE_ADDR + 0x5c0, 0x00000028)
/* DATA: */
MXC_DCD_ITEM(22, IOMUXC_BASE_ADDR + 0x774, 0x00020000)
MXC_DCD_ITEM(23, IOMUXC_BASE_ADDR + 0x784, 0x00000028)
MXC_DCD_ITEM(24, IOMUXC_BASE_ADDR + 0x788, 0x00000028)
MXC_DCD_ITEM(25, IOMUXC_BASE_ADDR + 0x794, 0x00000028)
MXC_DCD_ITEM(26, IOMUXC_BASE_ADDR + 0x79c, 0x00000028)
MXC_DCD_ITEM(27, IOMUXC_BASE_ADDR + 0x7a0, 0x00000028)
MXC_DCD_ITEM(28, IOMUXC_BASE_ADDR + 0x7a4, 0x00000028)
MXC_DCD_ITEM(29, IOMUXC_BASE_ADDR + 0x7a8, 0x00000028)
MXC_DCD_ITEM(30, IOMUXC_BASE_ADDR + 0x748, 0x00000028)
MXC_DCD_ITEM(31, IOMUXC_BASE_ADDR + 0x5ac, 0x00000028)
MXC_DCD_ITEM(32, IOMUXC_BASE_ADDR + 0x5b4, 0x00000028)
MXC_DCD_ITEM(33, IOMUXC_BASE_ADDR + 0x528, 0x00000028)
MXC_DCD_ITEM(34, IOMUXC_BASE_ADDR + 0x520, 0x00000028)
MXC_DCD_ITEM(35, IOMUXC_BASE_ADDR + 0x514, 0x00000028)
MXC_DCD_ITEM(36, IOMUXC_BASE_ADDR + 0x510, 0x00000028)
MXC_DCD_ITEM(37, IOMUXC_BASE_ADDR + 0x5bc, 0x00000028)
MXC_DCD_ITEM(38, IOMUXC_BASE_ADDR + 0x5c4, 0x00000028)MXC_DCD_ITEM(39, MMDC_P0_BASE_ADDR + 0x800, 0xA1390003)
MXC_DCD_ITEM(40, MMDC_P0_BASE_ADDR + 0x80c, 0x001F001F)
MXC_DCD_ITEM(41, MMDC_P0_BASE_ADDR + 0x810, 0x001F001F)
MXC_DCD_ITEM(42, MMDC_P1_BASE_ADDR + 0x80c, 0x001F001F)
MXC_DCD_ITEM(43, MMDC_P1_BASE_ADDR + 0x810, 0x001F001F)
/* Read DQS Gating calibration */
MXC_DCD_ITEM(44, MMDC_P0_BASE_ADDR + 0x83c, 0x4302030B)
MXC_DCD_ITEM(45, MMDC_P0_BASE_ADDR + 0x840, 0x0275026A)
MXC_DCD_ITEM(46, MMDC_P1_BASE_ADDR + 0x83c, 0x4302031A)
MXC_DCD_ITEM(47, MMDC_P1_BASE_ADDR + 0x840, 0x027B0249)
/* Read calibration */
MXC_DCD_ITEM(48, MMDC_P0_BASE_ADDR + 0x848, 0x3F343534)
MXC_DCD_ITEM(49, MMDC_P1_BASE_ADDR + 0x848, 0x3A373345)
/* Write calibration */
MXC_DCD_ITEM(50, MMDC_P0_BASE_ADDR + 0x850, 0x31424732)
MXC_DCD_ITEM(51, MMDC_P1_BASE_ADDR + 0x850, 0x48334736)
/* read data bit delay: (3 is the reccommended default value, although out of reset value is 0): */
MXC_DCD_ITEM(52, MMDC_P0_BASE_ADDR + 0x81c, 0x33333333)
MXC_DCD_ITEM(53, MMDC_P0_BASE_ADDR + 0x820, 0x33333333)
MXC_DCD_ITEM(54, MMDC_P0_BASE_ADDR + 0x824, 0x33333333)
MXC_DCD_ITEM(55, MMDC_P0_BASE_ADDR + 0x828, 0x33333333)MXC_DCD_ITEM(56, MMDC_P1_BASE_ADDR + 0x81c, 0x33333333)
MXC_DCD_ITEM(57, MMDC_P1_BASE_ADDR + 0x820, 0x33333333)
MXC_DCD_ITEM(58, MMDC_P1_BASE_ADDR + 0x824, 0x33333333)
MXC_DCD_ITEM(59, MMDC_P1_BASE_ADDR + 0x828, 0x33333333)
/* Complete calibration by forced measurement: */
MXC_DCD_ITEM(60, MMDC_P0_BASE_ADDR + 0x8b8, 0x00000800)
MXC_DCD_ITEM(61, MMDC_P1_BASE_ADDR + 0x8b8, 0x00000800)
/* MMDC init: */
MXC_DCD_ITEM(62, MMDC_P0_BASE_ADDR + 0x004, 0x00020036)
MXC_DCD_ITEM(63, MMDC_P0_BASE_ADDR + 0x008, 0x09444040)MXC_DCD_ITEM(64, MMDC_P0_BASE_ADDR + 0x00c, 0x8A8F7955)
MXC_DCD_ITEM(65, MMDC_P0_BASE_ADDR + 0x010, 0xFF328F64)
MXC_DCD_ITEM(66, MMDC_P0_BASE_ADDR + 0x014, 0x01FF00DB)MXC_DCD_ITEM(67, MMDC_P0_BASE_ADDR + 0x018, 0x00001740)
MXC_DCD_ITEM(68, MMDC_P0_BASE_ADDR + 0x01c, 0x00008000)
/* t during MMDC set up */
MXC_DCD_ITEM(69, MMDC_P0_BASE_ADDR + 0x02c, 0x000026D2)
/* t values */
MXC_DCD_ITEM(70, MMDC_P0_BASE_ADDR + 0x030, 0x008F1023)
MXC_DCD_ITEM(71, MMDC_P0_BASE_ADDR + 0x040, 0x00000047)
MXC_DCD_ITEM(72, MMDC_P0_BASE_ADDR + 0x000, 0x841A0000)
/* Mode register writes */
MXC_DCD_ITEM(73, MMDC_P0_BASE_ADDR + 0x01c, 0x04088032)
MXC_DCD_ITEM(74, MMDC_P0_BASE_ADDR + 0x01c, 0x00008033)
MXC_DCD_ITEM(75, MMDC_P0_BASE_ADDR + 0x01c, 0x00048031)
MXC_DCD_ITEM(76, MMDC_P0_BASE_ADDR + 0x01c, 0x09408030)
MXC_DCD_ITEM(77, MMDC_P0_BASE_ADDR + 0x01c, 0x04008040)MXC_DCD_ITEM(78, MMDC_P0_BASE_ADDR + 0x020, 0x00005800)
MXC_DCD_ITEM(79, MMDC_P0_BASE_ADDR + 0x818, 0x00011117)
MXC_DCD_ITEM(80, MMDC_P1_BASE_ADDR + 0x818, 0x00011117)
MXC_DCD_ITEM(81, MMDC_P0_BASE_ADDR + 0x004, 0x00025576)
MXC_DCD_ITEM(82, MMDC_P0_BASE_ADDR + 0x404, 0x00011006)
MXC_DCD_ITEM(83, MMDC_P0_BASE_ADDR + 0x01c, 0x00000000)#endif
/*Kris, 20151224, Change to 2GB configuration. }*/
#endif#endif

所以系统加载的流程是这样的:

系统上电运行内部ROM, ROM读取u-boot前面的一段数据到内部ram, 即读取flash_header.S中的配置,并初始化ddr,然后将整个u-boot copy到ddr, 最终执行权交给u-boot,即start.S的_start从而执行u-boot的初始化...

因为无rom的code,所以这只是推断,不一定准确。

不过我有试着修改过TEXT_BASE,发现改掉后系统还能正常运行,所以我猜是rom读取了boot_data_ptr,

而里面正是保存着u-boot.bin要运行的地址。

[IMX6Q]flash_header.S分析相关推荐

  1. 2018十大人气视频网站介绍

    备注:此博文为转载,原博文地址请点击此处 原标题:2018年海外十大人气视频网站介绍 前也给大家介绍过很多国外的网站,很多朋友留言说非常有帮助,今天给大家介绍一些海外的视频网站,部分网站需要挂本地VP ...

  2. IMX6Q 启动过程详细分析

    一.预览 本文主要对IMX6Q的启动过程进行分析,主要参考文档来自NXP官方文档IMX6DQRM.pdf,使用的uboot为NXP官方提供uboot-imx,使用的开发板为迅为iTOP-i.MX6.N ...

  3. uboot2015–启动流程分析 imx6q

    最近项目原因,要在uboot中增加内核验校和内核损坏修复功能,所以需要回头看看uboot.这次选择了uboot2015来进行分析 uboot是明远睿智提供的. 下载地址 链接:https://pan. ...

  4. 基于IMX6Q的uboot启动流程分析(3):_main函数之relocate_code与board_init_r

    基于IMX6Q的uboot启动流程分析(1):uboot入口函数 基于IMX6Q的uboot启动流程分析(2):_main函数之board_init_f 基于IMX6Q的uboot启动流程分析(3): ...

  5. IMX6q ft5x0x_ts触摸芯片分析

    Imx6使用的触摸屏控制芯片是ft5x06系列的,对应的文件为:ft5x06_ts.c. Ft5x06_ts驱动涉及的内容如下: 1.  I2C驱动框架. 2.  中断子系统,中断分层思想. 3.  ...

  6. [IMX6Q][Android5.1]移植笔记 --- kernel停在Starting kernel 分析

    platform: imx6q os: Android5.1 branch: l5.1.1_2.1.0-ga 解决方法: IMX6Q的PMU被bypass导致cpu没有供电而无法开机,只要donwlo ...

  7. IMX6Q的DDR3初始化配置

    处理器:IMX6Q5EYM10ADDDR3时钟频率400MHz.528MHz DDR3:NT5CB128M16BP-CG16位667MHz时钟频率1333MHz数据频率 相比于Exynos4412的内 ...

  8. 【迅为iMX6Q】开发板 烧写工具 MfgTool2.exe 打不开问题的解决

    现象 最近整理电脑,重新搭建了 [迅为iMX6Q]开发板的开发环境,从网盘重新下载的烧写烧写工具:android_m6.0.1_2.0.0_ga_tool_20190725,直接双击MfgTool2. ...

  9. Gstreamer1.0与imx6q IPU转码 wait_for_comp_timeout 问题解决心路历程

    近几个星期在做360度视频编码的过程中遇到一个很棘手的问题,就是调用gstreamer1.0的imxvideoconvert_ipu vpuenc_h264 元件进行转码 + 编码时遇到 wait_f ...

最新文章

  1. 比特币现金锚定货币交易所越来越多
  2. Codeforces 988F. Rain and Umbrellas
  3. 使用正则表达式,取得点击次数,函数抽离
  4. python力导向图论文_力导向图(关系图) echarts的运用
  5. vue组件化学习第一天
  6. XMPP即时通讯协议使用(前传)——协议详解
  7. 输出UTC时间和北京时间
  8. Layui的管理系统的模板
  9. linux tuxedo查看服务进程数,tuxedo管理命令之tmboot与tmshutdown
  10. 关于在使用ztree中同级排序的疑问
  11. git push 失败问题如何解决
  12. 用lua实现竖列转盘游戏
  13. Resilience4j
  14. My97DatePicker-WdatePicker日历日期插件详细示例
  15. 快速生成树(RSTP)
  16. 计算机什么课学mcmc,科学网—MCMC的深入理解 - 蒋秋华的博文
  17. HTML5期末大作业:重庆火锅网站设计——代码质量好-重庆火锅(5页) HTML+CSS+JavaScript 大学生网页制作期末作业
  18. 飞腾服务器平台Benchmark测试指导---Stream
  19. Ubuntu下Ruby的下载和编译源码安装
  20. 新旧工艺比较:PCB制造工艺

热门文章

  1. Avery Dennison推新款RFID嵌体,适用于牛仔服饰
  2. 附下载|华为《Wi-Fi 6 时代的校园无线网络建网标准技术白皮书》
  3. 安科瑞智能照明监控系统,采用智能控制模块控制照明回路的通断
  4. 分拣机器人现场安装过程实录
  5. 国外引进的技术?NO!这款最酷的垃圾分拣机器人是“三国产品”
  6. MB级存储的灵动微单片机MM32F5280
  7. 从属性资源文件中读取连接数据库信息
  8. 蓝桥杯单片机组_学习路线
  9. android pie风格,vivo NEX尝鲜Android“派”,系统风格更清新,AI应用更给力
  10. 2021年中国数字营销十大趋势