ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

u-boot-2014-07 代码流程分析

2020-05-01 13:03:45  阅读:314  来源: 互联网

标签:... 07 boot initialize 2014 serial CPU 函数


前言

以前接触到的u-boot启动方式只有Flash和Nand Flash这两种方式,最近接触是SD卡启动方式,SoC是S5P4418,启动方式也第一次接触到,根据S5P4418用户手册可以找到系统使用SD卡启动时,片内iROM内固化的代码会自动映射到0x00地址,也被称为第一阶段引导程序,该程序会检测启动引脚配置,然后从SD卡读取block1~block32内的程序到内置SRAM中执行,读取出来并执行的这段程序被称为第二阶段引导程序,由于其最大为16KB,无法存放完整的u-boot。以上两个引导程序均由芯片厂商提供,没有源码,不开源。第二阶段引导程序从SD卡中加载u-boot到DRAM中执行,至此u-boot才开始登场。

SDHCBOOT --> 2nboot --> u-boot

代码分析

程序入口

由于S5P4418采用的指令集为ARMv7,通常应该去该文件arch/arm/cpu/armv7下寻找该SoC,然而并没有,通过查看board.cfg可以看到它的CPU类型被定义为了slsiap,通过查看arch/arm/cpu/slsiap也确实存在s5p4418文件夹。

# Status, Arch, CPU:SPLCPU, SoC, Vendor
  Active  arm  slsiap  s5p4418  s5p4418

接下来就是找到第一个执行的程序在哪里文件里,即找到程序入口,查看slsiap下的链接文件

.text :
{
    *(.__image_copy_start)
    SDIR/start.o (.text*)
    *(.text*)
}

而SDIR是什么并不知道,打开同文件夹下的config.mk

SDIR=arch/arm/cpu$(if $(CPU),/$(CPU),)$(if $(SOC),/$(SOC),)

替换变量之后

SDIR=arch/arm/cpu/slsiap/s5p4418

即第一个文件是arch/arm/cpu/slsiap/s5p4418/start.S

start.S

不同 CPU 的改文件大致功能都大同小异,设置中断向量表,将 CPU 设置为 SVC 模式,然后设置 CP15,设置 Cache,初始化内存,然后对代码进行重定位,之后开始清理 bss 段,为准备 C 语言运行环境,然后设置栈指针,执行 board_init_f 函数填充 global_data 结构体数据,最后执行 board_init_r,离开start.S不再返回。

board_init_r

该函数中调用的两个有意思的函数:serial_initialize、mmc_initialize。

void serial_initialize(void)
{
    mpc8xx_serial_initialize();
    ...省略若干类似函数...
    s5p_serial_initialize();
    ...省略若干类似函数...
    arc_serial_initialize();
}

可以看到,该函数中不加判断的把各种种类的串口初始化都给写上,也没有使用宏去自动选择使用哪个,给人的第一感觉就是这不是浪费存储空间么,继续查看该函数所在文件其他代码可以发现

/**
 * serial_initfunc() - Forward declare of driver registration routine
 * @name:    Name of the real driver registration routine.
 *
 * This macro expands onto forward declaration of a driver registration
 * routine, which is then used below in serial_initialize() function.
 * The declaration is made weak and aliases to serial_null() so in case
 * the driver is not compiled in, the function is still declared and can
 * be used, but aliases to serial_null() and thus is optimized away.
 */
#define serial_initfunc(name)                    \
    void name(void)                     \
        __attribute__((weak, alias("serial_null")));

serial_initfunc(mpc8xx_serial_initialize);
...省略若干类似函数...
serial_initfunc(s5p_serial_initialize);
...省略若干类似函数...
serial_initfunc(arc_serial_initialize);

英文注释说的很清楚了,这是在利用编译器特性进行自动优化的,使用 __weak 属性先声明驱动程序,因为编译程序之前会先配置程序,在编译的时候在配置阶段产生的宏在预编译阶段会决定哪些驱动程序被编译进来,比如 S5P4418 被选择时,相关的串口驱动 s5p_serial_initialize 就会编译进来,由于其声明为 __weak 属性,编译时会自动覆盖掉前项声明的函数,这样函数 serial_initialize 就不会出现把不必要的程序编译进来的情况了。

mmc_initialize 函数的分析见下回分解吧~

标签:...,07,boot,initialize,2014,serial,CPU,函数
来源: https://www.cnblogs.com/jiau/p/12813180.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有