接上回.在borad_init_f函数执行完成,C语言环境就算完全建立起来了.下面就完全是C的代码了.
返回crt0.S , 执行board_init_r(common/board_r.c), 完成board_init_f没有完成的初始化工作,通过调用initcall_run_list来完成,这里注意的参数是一系列的函数集合.

我们回去看这个参数init_sequence_r (common/board_r.c) ,init_sequence_r是一个数组,也就是函数初始化序列,为了兼容多款板子,里面包含了大量的条件编译函数.

/** Over time we hope to remove these functions with code fragments and* stub funtcions, and instead call the relevant function directly.** We also hope to remove most of the driver-related init and do it if/when* the driver is later used.** TODO: perhaps reset the watchdog in the initcall function after each call?*/
init_fnc_t init_sequence_r[] = {initr_trace, /* 初始化buffer 跟踪相关,如果定义了CONFIG_TRACE宏的话,将调用trace_init()函数,是与初始化和调试跟踪相关的内容。*/initr_reloc, /* 设置了gd->flags成员,标记uboot重定位完成。 *//* TODO: could x86/PPC have this also perhaps? */
#ifdef CONFIG_ARMinitr_caches, /* 调用initr_caches,使能芯片的caches。 *//* Note: For Freescale LS2 SoCs, new MMU table is created in DDR.*  A temporary mapping of IFC high region is since removed,*    so environmental variables in NOR flash is not availble*    until board_init() is called below to remap IFC to high*    region.*/
#endifinitr_reloc_global_data, /* 初始化重定为后gd的一些成员变量*/
#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500)initr_unlock_ram_in_cache,
#endifinitr_barrier, /*空函数,直接返回 */initr_malloc, /* 初始化malloc 内存区域 */initr_console_record, /* 初始化控台相关,对于6ull,为空 */
#ifdef CONFIG_SYS_NONCACHED_MEMORYinitr_noncached,
#endifbootstage_relocate, /* 启动状态重定位,用于重定位buutstage相关的东西 */
#ifdef CONFIG_DMinitr_dm,
#endifinitr_bootstage, /* 初始化bootstage相关的内容 */
#if defined(CONFIG_ARM) || defined(CONFIG_NDS32)board_init,  /* Setup chipselects,判定宏CONFIG_ARM是否定义,6ull有定义,调用board_init函数,该函数与板级相关,定义文件为uboot/board/freescale/mx6ul_comp6ul_nand/mx6ul_comp6ul_nand.c,通过函数可以看到包含函数,setup_i2c,setup_fec,setup_usb,board_qsp_init,setup_gpmi_nand,主要是用来初始化板子上的一些外设,如gpio,i2c,网络等相关接口 */
#endif/** TODO: printing of the clock inforamtion of the board is now* implemented as part of bdinfo command. Currently only support for* davinci SOC's is added. Remove this check once all the board* implement this.*/
#ifdef CONFIG_CLOCKSset_cpu_clk_info, /* Setup clock information */
#endifstdio_init_tables,/* stdio相关初始化*/initr_serial,/* serial 接口初始化 */initr_announce,/* 用于调试相关的内容,通知已经在dram中运行 */INIT_FUNC_WATCHDOG_RESET
#ifdef CONFIG_NEEDS_MANUAL_RELOCinitr_manual_reloc_cmdtable,
#endif
#if defined(CONFIG_PPC) || defined(CONFIG_M68K)initr_trap,
#endif
#ifdef CONFIG_ADDR_MAPinitr_addr_map,
#endif
#if defined(CONFIG_BOARD_EARLY_INIT_R)board_early_init_r,
#endifINIT_FUNC_WATCHDOG_RESET
#ifdef CONFIG_LOGBUFFERinitr_logbuffer,
#endif
#ifdef CONFIG_POSTinitr_post_backlog,
#endifINIT_FUNC_WATCHDOG_RESET
#ifdef CONFIG_SYS_DELAYED_ICACHEinitr_icache_enable,
#endif
#if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT)/** Do early PCI configuration _before_ the flash gets initialised,* because PCU ressources are crucial for flash access on some boards.*/initr_pci,
#endif
#ifdef CONFIG_WINBOND_83C553initr_w83c553f,
#endif
#ifdef CONFIG_ARCH_EARLY_INIT_Rarch_early_init_r,
#endifpower_init_board,
#ifndef CONFIG_SYS_NO_FLASHinitr_flash, /* 初始化 nand flash */
#endifINIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_X86) || \defined(CONFIG_SPARC)/* initialize higher level parts of CPU like time base and timers */cpu_init_r,
#endif
#ifdef CONFIG_PPCinitr_spi,
#endif
#ifdef CONFIG_CMD_NANDinitr_nand,  /* 初始化 nand flash ,根据宏定义结果,来判断是否初始化,
#ifdef CONFIG_CMD_NAND
/* go init the NAND */
static int initr_nand(void)
{puts("NAND:  ");nand_init();return 0;
}
#endif
对nand_flash初始化,并在串口以字符串的型式输出nand flash的大小*/
#endif
#ifdef CONFIG_CMD_ONENANDinitr_onenand,
#endif
#ifdef CONFIG_GENERIC_MMCinitr_mmc, /* 宏定义在/include/imx6_common.h中,初始化和sd/mmc 相关的接口 */
#endif
#ifdef CONFIG_HAS_DATAFLASHinitr_dataflash,
#endifinitr_env,/* 初始化环境变量  */
#ifdef CONFIG_SYS_BOOTPARAMS_LENinitr_malloc_bootparams,
#endifINIT_FUNC_WATCHDOG_RESETinitr_secondary_cpu, /* 用来初始化其他的cpu核,对于6ul只有一个cpu,函数无效*/
#if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET)mac_read_from_eeprom,
#endifINIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_PCI) && !defined(CONFIG_SYS_EARLY_PCI_INIT)/** Do pci configuration*/initr_pci,
#endifstdio_add_devices,/* 初始化各种输入输出设备,例如LCD */initr_jumptable, /* 初始化跳转表相关的内容 */
#ifdef CONFIG_APIinitr_api,
#endifconsole_init_r,        /* 完成控制台的初始化,调用后,uboot输出:
In:    serial
Out:   serial
Err:   serial*/
#ifdef CONFIG_DISPLAY_BOARDINFO_LATEshow_board_info, /* 显示开发板相关信息 */
#endif
#ifdef CONFIG_ARCH_MISC_INITarch_misc_init,      /* miscellaneous arch-dependent init */
#endif
#ifdef CONFIG_MISC_INIT_Rmisc_init_r,        /* miscellaneous platform-dependent init */
#endifINIT_FUNC_WATCHDOG_RESET
#ifdef CONFIG_CMD_KGDBinitr_kgdb,
#endifinterrupt_init, /* 初始化中断相关 */
#if defined(CONFIG_ARM) || defined(CONFIG_AVR32)initr_enable_interrupts,/* 使能中断  */
#endif
#if defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32) || defined(CONFIG_M68K)timer_init,       /* initialize timer */
#endif
#if defined(CONFIG_STATUS_LED)initr_status_led, /* 初始化运行状态灯  */
#endif/* PPC has a udelay(20) here dating from 2002. Why? */
#ifdef CONFIG_CMD_NETinitr_ethaddr, /* 调用initr_ethaddr函数初始化网络地址,获得mac地址 */
#endif
#ifdef CONFIG_BOARD_LATE_INITboard_late_init, /* 后期外设初始化 ,紧跟着调用initr_net 初始化板子上的网络设备,并在串口输出信息*/
#endif
#ifdef CONFIG_FSL_FASTBOOTinitr_fastboot_setup,/*初始化快速启动的信息 */
#endif
#if defined(CONFIG_CMD_AMBAPP)ambapp_init_reloc,
#if defined(CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP)initr_ambapp_print,
#endif
#endif
#ifdef CONFIG_CMD_SCSIINIT_FUNC_WATCHDOG_RESETinitr_scsi,
#endif
#ifdef CONFIG_CMD_DOCINIT_FUNC_WATCHDOG_RESETinitr_doc,
#endif
#ifdef CONFIG_BITBANGMIIinitr_bbmii,
#endif
#ifdef CONFIG_CMD_NETINIT_FUNC_WATCHDOG_RESETinitr_net,
#endif
#ifdef CONFIG_POSTinitr_post,
#endif
#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE)initr_pcmcia,
#endif
#if defined(CONFIG_CMD_IDE)initr_ide,
#endif
#ifdef CONFIG_LAST_STAGE_INITINIT_FUNC_WATCHDOG_RESET/** Some parts can be only initialized if all others (like* Interrupts) are up and running (i.e. the PC-style ISA* keyboard).*/last_stage_init,
#endif
#ifdef CONFIG_CMD_BEDBUGINIT_FUNC_WATCHDOG_RESETinitr_bedbug,
#endif
#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)initr_mem,
#endif
#ifdef CONFIG_PS2KBDinitr_kbd,
#endif
#if defined(CONFIG_SPARC)prom_init,
#endif
#ifdef CONFIG_FSL_FASTBOOTinitr_check_fastboot,
#endiflt8618_init,/* 初始化8618芯片 */run_main_loop,/* 主函数,用户处理输入的命令 */
};
最后一脚 run_main_loop 函数
从上面的run_main_loop -> common/main.c [ main_loop() ]
/* We come here after U-Boot is initialised and ready to process commands */
void main_loop(void)
{const char *s;bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");#ifndef CONFIG_SYS_GENERIC_BOARDputs("Warning: Your board does not use generic board. Please read\n");puts("doc/README.generic-board and take action. Boards not\n");puts("upgraded by the late 2014 may break or be removed.\n");
#endif#ifdef CONFIG_VERSION_VARIABLEsetenv("ver", version_string);  /* set version variable */
#endif /* CONFIG_VERSION_VARIABLE */cli_init();run_preboot_environment_command();#if defined(CONFIG_UPDATE_TFTP)update_tftp(0UL, NULL, NULL);
#endif /* CONFIG_UPDATE_TFTP *//* yfc 显示信息Normal Boot */s = bootdelay_process();if (cli_process_fdt(&s))cli_secure_boot_cmd(s);autoboot_command(s);
/* 调用common/autoboot.c [autoboot_command]
void autoboot_command(const char *s)
{debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) {
#if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)int prev = disable_ctrlc(1);    /* disable Control C checking */
#endifrun_command_list(s, -1, 0);#if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)disable_ctrlc(prev);  /* restore Control C checking */
#endif}#ifdef CONFIG_MENUKEYif (menukey == CONFIG_MENUKEY) {s = getenv("menucmd");if (s)run_command_list(s, -1, 0);}
#endif /* CONFIG_MENUKEY */
}abortboot()函数.
static int abortboot(int bootdelay)
{#ifdef CONFIG_AUTOBOOT_KEYEDreturn abortboot_keyed(bootdelay);
#elsereturn abortboot_normal(bootdelay);
#endif
}abortboot_normal(bootdelay)函数static int abortboot_normal(int bootdelay)
{int abort = 0;unsigned long ts;#ifdef CONFIG_MENUPROMPTprintf(CONFIG_MENUPROMPT);
#elseif (bootdelay >= 0)printf("Hit any key to stop autoboot: %2d ", bootdelay);
/* 显示到屏幕 */
#endif#if defined CONFIG_ZERO_BOOTDELAY_CHECK/** Check if key already pressed* Don't check if bootdelay < 0*/if (bootdelay >= 0) {if (tstc()) { /* we got a key press   */(void) getc();  /* consume input  */puts("\b\b\b 0");abort = 1;    /* don't auto boot */}}
#endifwhile ((bootdelay > 0) && (!abort)) {--bootdelay;/* delay 1000 ms */ts = get_timer(0);do {if (tstc()) {   /* we got a key press   */abort  = 1;  /* don't auto boot */bootdelay = 0;   /* no more delay    */
# ifdef CONFIG_MENUKEYmenukey = getc();
# else(void) getc();  /* consume input  */
# endifbreak;}udelay(10000);} while (!abort && get_timer(ts) < 1000);printf("\b\b\b%2d ", bootdelay);}putc('\n');#ifdef CONFIG_SILENT_CONSOLEif (abort)gd->flags &= ~GD_FLG_SILENT;
#endifreturn abort;
}
*/cli_loop();
}

创作不易,欢迎关注点赞,你的关注是我创作的最大动力!

uboot学习笔记之七-第三个函数board_init_r相关推荐

  1. 机器学习理论《统计学习方法》学习笔记:第三章 k近邻法

    机器学习理论<统计学习方法>学习笔记:第三章 k近邻法 3 k近邻法 3.1 K近邻算法 3.2 K近邻模型 3.2.1 模型 3.2.2 距离度量 3.2.3 K值的选择 3.2.4 分 ...

  2. Kinect开发学习笔记之(三)Kinect开发环境配置

    Kinect开发学习笔记之(三)Kinect开发环境配置 zouxy09@qq.com http://blog.csdn.net/zouxy09 我的Kinect开发平台是: Win7 x86 + V ...

  3. Python学习笔记——for循环和range函数

    Python学习笔记--for循环和range函数 Python的for循环 for 目标 in 表达式 :循环体 案例一 >>> example = 'abcdef' >&g ...

  4. JavaScript 学习笔记(第三天)

    JavaScript 学习笔记(第三天) 一.数组 1.1.数组的基础 1.2.数据类型分类 1.3.创建数组 1.3.1.字面量创建一个数组 1.3.2.内置构造函数创建数组 1.4.数组的基本操作 ...

  5. OpenCV学习笔记(5)_ ellipse绘制函数浅析

    OpenCV学习笔记(5)_ ellipse绘制函数浅析 文章目录 OpenCV学习笔记(5)_ ellipse绘制函数浅析 1. ellipse第一种重载--绘制椭圆弧 1.1 函数原型 1.2 参 ...

  6. ① ESP8266 开发学习笔记_By_GYC 【更新 ets_printf 函数 使ESP_IDF 能够支持浮点数打印】

    ① ESP8266 开发学习笔记_By_GYC [更新 ets_printf 函数 使ESP_IDF 能够支持浮点数打印] 在我们日常的开发过程中,经常使用到的一个功能就是串口打印功能.在ESP826 ...

  7. ES6学习笔记二arrow functions 箭头函数、template string、destructuring

    接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...

  8. MySQL学习笔记(四)——分组函数,分组查询,连接查询

    MySQL学习笔记(四)--分组函数,分组查询,连接查询 作者:就叫易易好了 日期:2020/11/18 一.分组函数 功能:用作统计使用,又称为聚合函数或统计函数 分类: sum函数 avg函数 m ...

  9. 判断题:oracle自带的sql语言环境是pl/sql,Oracle之PL/SQL学习笔记之数据类型(三)

    Oracle之PL/SQL学习笔记之数据类型(三) 所有的编程语言中变量是使用最频繁的.PL/SQL作为一个面向过程的数据库编程语言同样少不了变量,利用变量可以把PL/SQL块需要的参数传递进来,做到 ...

最新文章

  1. unity3d游戏开发猜想——当程序猿老去
  2. 鹅厂AI科学家,偷偷把无人摩托写进了年终总结
  3. bat给文件追加换行内容
  4. python完全新手教程-小白的Python新手教程​
  5. 福州华威集团旗下华威客运票务网页界面设计
  6. 【转】Java删除文件夹和文件
  7. java 类 方法继承_java – 在方法重写中返回继承的类而不是超类
  8. docker swarm快速搭建mogodb集群
  9. SQLi Labs Less-1 联合注入+报错注入
  10. Atitit. 衡量项目规模 ----包含的类的数量 .net java类库包含多少类 多少个api方法??
  11. LSTM神经网络和GRU
  12. java 职业规划_java个人职业生涯规划范文
  13. 程序员怎样锻炼批判性思维
  14. 介绍10个免费、强大的PHP编辑器/开发工具
  15. MIPS架构对比ARM架构
  16. 方舟神器/贡品代码大全
  17. 华为开始全面部署启用鸿蒙os系统,华为开始全面部署启用鸿蒙OS系统!
  18. 海外游戏广告应该怎么做
  19. 传奇登录器自动获取服务器,gom引擎配置登录器补丁读取规则的说明
  20. php英文怎么读,100的英文怎么读_单词及读音

热门文章

  1. 【C语言经典100例】-- 06 用*号输出字母C的图案
  2. linux给目录赋访问权限_在Linux上给用户赋予指定目录的读写权限
  3. 北京地铁客流数据特征分析
  4. 深度学习调参:优化算法,优化器optimizer,学习率learning rate
  5. 漫说测试 | 研发虐我千百遍,我待bug如初恋
  6. Tabu Search求解作业车间调度问题(Job Shop Scheduling)-附Java代码
  7. 前方高能 | 如何优化企业“数据消费“策略
  8. VM虚拟机只有IPv6,没有ipv4
  9. 怎么从转移特性曲线上看dibl_半导体器件原理chapter4.ppt
  10. 计算机存储的基本单位