1.最开始系统上电后 ENTRY(_start)程序入口点是 _start  由board/ap121/u-boot.lds引导

2._start: cpu/mips/start.S 是第一个源程序文件,主要完成初始化看门狗、定时器、重定位(拷贝代码段到内存中)、初始化堆  栈、  跳转到第二阶段等工作。

3. la t9, board_init_f 将函数board_init_f地址赋予t9
j t9 跳转到t9寄存器中保存的地址指向的指令
即跳转到RAM 中执行 C 代码
这里会打印一些信息。

3.1 board_init_f() lib_mips/board.c
初始化外部内存
relocate_code() 回到cpu/mips/start.S中继续执行

4.la t9,board_init_r cpu/mips/start.S
j t9 将函数board_init_r地址赋予t9
跳转到t9寄存器中保存的地址指向的指令
即跳转到RAM 中执行 C 代码
这里会打印一些信息
4.1 board_init_r() 函数 lib_mips/board.c

4.2 main_loop() common/main.c
s=getenv ("bootcmd") 取得环境变量中的启动命令行,如bootcmd=bootm 0xbf020000
run_command (s, 0); //执行这个命令行 ,即bootm
4.3 do_bootm() common/cmd_bootm.c
// printf ("## Booting image at %08lx .../n", addr); //比如

5. bootm 启动内核
5.1 do_bootm_linux() lib_mips/mips_linux.c

函数解析

1.board_init_f()

1.1

  1. void board_init_f(ulong bootflag)
  2. {
  3. for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)
  4. { if ((*init_fnc_ptr)() != 0)
  5. { hang (); }
  6. }
  7. //调用init_sequence 函数队列,对板子进行一些初始化,详细见后面
  8. 初始化external memory,初始化堆栈用cache作堆栈,为
  9. relocate_code (addr_sp, id, addr); //回到cpu/mips/start.S 中
  10. /* NOTREACHED - relocate_code() does not return */
  11. }

1.2

  1. typedef int (init_fnc_t) (void);
  2. init_fnc_t *init_sequence[] =
  3. { clx_board_init, //初始化GPIO,CPU速度,PLL,SDRAM 等
  4. timer_init, //时钟初始化
  5. env_init, //环境变脸初始化
  6. incaip_set_cpuclk, //根据环境变量设置CPU 时钟
  7. init_baudrate, //初始化串口波特率
  8. serial_init, /* serial communications setup */
  9. console_init_f, //串口初始化,后面才能显示
  10. display_banner, //在屏幕上输出一些显示信息
  11. checkboard,
  12. init_func_ram,
  13. NULL,
  14. };

2.board_init_r()
(1)调用一系列的初始化函数。
(2)初始化Flash设备。
(3)初始化系统内存分配函数。
(4)如果目标系统拥有NAND设备,则初始化NAND设备。
(5)如果目标系统有显示设备,则初始化该类设备。
(6)初始化相关网络设备,填写IP、MAC地址等。
(7)进去命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作

  1. void board_init_r (gd_t *id, ulong dest_addr)
  2. {
  3. /* configure available FLASH banks */ //配置可用的flash单元
  4. size = flash_init(); //初始化flash
  5. display_flash_config (size); //显示flash 的大小
  6. /* initialize malloc() area */
  7. mem_malloc_init();
  8. malloc_bin_reloc();
  9. puts ("NAND:");
  10. nand_init(); /* go init the NAND */ //NAND初始化
  11. /* relocate environment function pointers etc. */
  12. env_relocate(); //初始化环境变量
  13. /* board MAC address */
  14. s = getenv ("ethaddr"); //以太网MAC地址
  15. for (i = 0; i < 6; ++i) {
  16. bd->bi_enetaddr[i] = s ? simple_strtoul (s, &e, 16) : 0;
  17. if (s)
  18. s = (*e) ? e + 1 : e;
  19. }
  20. /* IP Address */
  21. bd->bi_ip_addr = getenv_IPaddr("ipaddr");
  22. pci_init(); //pci初始化配置
  23. /** leave this here (after malloc(), environment and PCI are working) **/
  24. /* Initialize devices */
  25. devices_init ();
  26. jumptable_init ();
  27. /* Initialize the console (after the relocation and devices init) */
  28. console_init_r (); //串口初始化
  29. /* miscellaneous platform dependent initialisations */
  30. misc_init_r ();
  31. puts ("Net: ");
  32. eth_initialize(gd->bd);
  33. /* main_loop() can return to retry autoboot, if so just run it again. */
  34. for (;;) {
  35. main_loop (); //循环执行,试图自动启动,接受用户从串口输入的命令,然后进行相应的工作,设置延时时间,确定目标板是进入下载模式还是启动加载模式
  36. }
  37. /* NOTREACHED - no way out of command loop except booting */
  38. }
  39. 3.main_loop()
  40. void main_loop (void)
  41. {
  42. s = getenv ("bootdelay"); //从环境变量中取得bootdelay 内核等待延时
  43. bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
  44. debug ("### main_loop entered: bootdelay=%d/n/n", bootdelay);
  45. s = getenv ("bootcmd"); //从环境变量中取得bootcmd 启动命令行
  46. 如bootcmd=tftp;bootm 或者 bootcmd=bootm 0xbf020000
  47. char *s1 = getenv ("bootargs"); //从环境变量中取得bootargs 启动参数
  48. debug ("### main_loop: bootcmd=/"%s/"/n", s ? s : "<UNDEFINED>");
  49. run_command (s, 0); //执行启动命令
  50. //手动输入命令
  51. for (;;) {
  52. len = readline (CFG_PROMPT); //读取键入的命令到CFG_PROMPT 中
  53. rc = run_command (lastcommand, flag); //执行这个命令
  54. }
  55. #endif /*CFG_HUSH_PARSER*/
  56. }

4.do_bootm()
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
这个函数看着挺长的,其实无非就是将内核解压缩,然后调用do_bootm_linux引导内核

5.do_bootm_linux() lib_mips/mips_linux.c
打印信息Starting kernel ...

  1. void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
  2. ulong addr, ulong * len_ptr, int verify)
  3. {
  4. char *commandline = getenv ("bootargs");
  5. theKernel =
  6. (void (*)(int, char **, char **, int *)) ntohl (hdr->ih_ep);
  7. //hdr为指向image header的指针,hdr->ih_ep就是我们用mkimage创建image时-e选项的参数:内核的入口地址
  8. linux_params_init (UNCACHED_SDRAM (gd->bd->bi_boot_params), commandline);
  9. /* we assume that the kernel is in place */
  10. printf ("/nStarting kernel .../n/n");
  11. theKernel (linux_argc, linux_argv, linux_env, 0); //启动内核
  12. }

u-boot向内核传递启动参数由一系列在include/configs/.h中的宏控制,启动参数传递的地址在board_init中初始化

u-boot简单学习笔记(三)——AR9331 uboot启动分析的更多相关文章

  1. JSP学习笔记(三):简单的Tomcat Web服务器

    注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...

  2. JAVA WEB学习笔记(三):简单的基于Tomcat的Web页面

    注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...

  3. ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心

    作者:Grey 原文地址:ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心 前置知识 完成ZooKeeper集群搭建以及熟悉ZooKeeperAPI基本使用 需求 很多程序往 ...

  4. Log4j简单学习笔记

    log4j结构图: 结构图展现出了log4j的主结构.logger:表示记录器,即数据来源:appender:输出源,即输出方式(如:控制台.文件...)layout:输出布局 Logger机滤器:常 ...

  5. java之jvm学习笔记三(Class文件检验器)

    java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...

  6. VSTO学习笔记(三) 开发Office 2010 64位COM加载项

    原文:VSTO学习笔记(三) 开发Office 2010 64位COM加载项 一.加载项简介 Office提供了多种用于扩展Office应用程序功能的模式,常见的有: 1.Office 自动化程序(A ...

  7. 学习笔记(三)--->《Java 8编程官方参考教程(第9版).pdf》:第十章到十二章学习笔记

    回到顶部 注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法 ...

  8. muduo网络库学习笔记(三)TimerQueue定时器队列

    目录 muduo网络库学习笔记(三)TimerQueue定时器队列 Linux中的时间函数 timerfd简单使用介绍 timerfd示例 muduo中对timerfd的封装 TimerQueue的结 ...

  9. angular学习笔记(三十)-指令(10)-require和controller

    本篇介绍指令的最后两个属性,require和controller 当一个指令需要和父元素指令进行通信的时候,它们就会用到这两个属性,什么意思还是要看栗子: html: <outer‐direct ...

随机推荐

  1. Palindromic Paths(DP)

    描述 Given an N×N grid of fields (1≤N≤500), each labeled with a letter in the alphabet. For example: A ...

  2. CodeIgniter 防止XSS攻击

    CodeIgniter 包含了跨站脚本攻击的防御机制,它可以自动地对所有POST以及COOKIE数据进行过滤,或者您也可以针对单个项目来运行它.默认情况下,它 不会 全局运行,因为这样也需要一些执行开 ...

  3. P1168 中位数 (优先队列,巧解)

    题目描述 给出一个长度为N的非负整数序列A[i],对于所有1 ≤ k ≤ (N + 1) / 2,输出A[1], A[3], …, A[2k - 1]的中位数.即前1,3,5,……个数的中位数. 输入 ...

  4. Python脚本实现值更新事件赋值过程记录日志监控

    #LogWatch 实现值更新事件赋值过程记录日志监控 clr.AddReference('System') clr.AddReference('Kingdee.BOS') clr.AddRefere ...

  5. COdevs 1074 食物链

    1074 食物链 2001年NOI全国竞赛  时间限制: 3 s 空间限制: 64000 KB 题目等级 : 钻石 Diamond 题目描述 Description 动物王国中有三类动物 A,B,C, ...

  6. fmt 包中的函数和方法

    / Fprintf 将参数列表 a 填写到格式字符串 format 的占位符中// 并将填写后的结果写入 w 中,返回写入的字节数func Fprintf(w io.Writer, format st ...

  7. hdu4848 求到达每个点总时间最短(sum[d[i]])。

    开始的时候是暴力dfs+剪枝,怎么也不行.后来参考他人思想: 先求出每个点之间的最短路(这样预处理之后的搜索就可以判重返回了),截肢还是关键:1最优性剪枝(尽量最优:目前的状态+预计还有的最小时间&g ...

  8. hdu 4587 2013南京邀请赛B题/ / 求割点后连通分量数变形。

    题意:求一个无向图的,去掉两个不同的点后最多有几个连通分量. 思路:枚举每个点,假设去掉该点,然后对图求割点后连通分量数,更新最大的即可.算法相对简单,但是注意几个细节: 1:原图可能不连通. 2:有 ...

  9. word2013 交叉引用添加参考文献的尾注编号,通过查找 ^# 替换为 [^&] 的方式添加中括号,在进行“更新域”操作后,中括号消失。

    word2013 交叉引用添加的尾注编号,通过查找 ^# 替换为 [^&] 的方式添加中括号,用这个方法添加中括号很多次了,这次却出现问题:在进行“更新域”操作后,中括号消失.       详 ...

  10. BZOJ——1614: [Usaco2007 Jan]Telephone Lines架设电话线

    Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1930  Solved: 823[Submit][Status][Discuss] Description ...