u-boot简单学习笔记(三)——AR9331 uboot启动分析
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
- void board_init_f(ulong bootflag)
- {
- for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)
- { if ((*init_fnc_ptr)() != 0)
- { hang (); }
- }
- //调用init_sequence 函数队列,对板子进行一些初始化,详细见后面
- 初始化external memory,初始化堆栈用cache作堆栈,为
- relocate_code (addr_sp, id, addr); //回到cpu/mips/start.S 中
- /* NOTREACHED - relocate_code() does not return */
- }
1.2
- typedef int (init_fnc_t) (void);
- init_fnc_t *init_sequence[] =
- { clx_board_init, //初始化GPIO,CPU速度,PLL,SDRAM 等
- timer_init, //时钟初始化
- env_init, //环境变脸初始化
- incaip_set_cpuclk, //根据环境变量设置CPU 时钟
- init_baudrate, //初始化串口波特率
- serial_init, /* serial communications setup */
- console_init_f, //串口初始化,后面才能显示
- display_banner, //在屏幕上输出一些显示信息
- checkboard,
- init_func_ram,
- NULL,
- };
2.board_init_r()
(1)调用一系列的初始化函数。
(2)初始化Flash设备。
(3)初始化系统内存分配函数。
(4)如果目标系统拥有NAND设备,则初始化NAND设备。
(5)如果目标系统有显示设备,则初始化该类设备。
(6)初始化相关网络设备,填写IP、MAC地址等。
(7)进去命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作
- void board_init_r (gd_t *id, ulong dest_addr)
- {
- /* configure available FLASH banks */ //配置可用的flash单元
- size = flash_init(); //初始化flash
- display_flash_config (size); //显示flash 的大小
- /* initialize malloc() area */
- mem_malloc_init();
- malloc_bin_reloc();
- puts ("NAND:");
- nand_init(); /* go init the NAND */ //NAND初始化
- /* relocate environment function pointers etc. */
- env_relocate(); //初始化环境变量
- /* board MAC address */
- s = getenv ("ethaddr"); //以太网MAC地址
- for (i = 0; i < 6; ++i) {
- bd->bi_enetaddr[i] = s ? simple_strtoul (s, &e, 16) : 0;
- if (s)
- s = (*e) ? e + 1 : e;
- }
- /* IP Address */
- bd->bi_ip_addr = getenv_IPaddr("ipaddr");
- pci_init(); //pci初始化配置
- /** leave this here (after malloc(), environment and PCI are working) **/
- /* Initialize devices */
- devices_init ();
- jumptable_init ();
- /* Initialize the console (after the relocation and devices init) */
- console_init_r (); //串口初始化
- /* miscellaneous platform dependent initialisations */
- misc_init_r ();
- puts ("Net: ");
- eth_initialize(gd->bd);
- /* main_loop() can return to retry autoboot, if so just run it again. */
- for (;;) {
- main_loop (); //循环执行,试图自动启动,接受用户从串口输入的命令,然后进行相应的工作,设置延时时间,确定目标板是进入下载模式还是启动加载模式
- }
- /* NOTREACHED - no way out of command loop except booting */
- }
- 3.main_loop()
- void main_loop (void)
- {
- s = getenv ("bootdelay"); //从环境变量中取得bootdelay 内核等待延时
- bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
- debug ("### main_loop entered: bootdelay=%d/n/n", bootdelay);
- s = getenv ("bootcmd"); //从环境变量中取得bootcmd 启动命令行
- 如bootcmd=tftp;bootm 或者 bootcmd=bootm 0xbf020000
- char *s1 = getenv ("bootargs"); //从环境变量中取得bootargs 启动参数
- debug ("### main_loop: bootcmd=/"%s/"/n", s ? s : "<UNDEFINED>");
- run_command (s, 0); //执行启动命令
- //手动输入命令
- for (;;) {
- len = readline (CFG_PROMPT); //读取键入的命令到CFG_PROMPT 中
- rc = run_command (lastcommand, flag); //执行这个命令
- }
- #endif /*CFG_HUSH_PARSER*/
- }
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 ...
- void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
- ulong addr, ulong * len_ptr, int verify)
- {
- char *commandline = getenv ("bootargs");
- theKernel =
- (void (*)(int, char **, char **, int *)) ntohl (hdr->ih_ep);
- //hdr为指向image header的指针,hdr->ih_ep就是我们用mkimage创建image时-e选项的参数:内核的入口地址
- linux_params_init (UNCACHED_SDRAM (gd->bd->bi_boot_params), commandline);
- /* we assume that the kernel is in place */
- printf ("/nStarting kernel .../n/n");
- theKernel (linux_argc, linux_argv, linux_env, 0); //启动内核
- }
u-boot向内核传递启动参数由一系列在include/configs/.h中的宏控制,启动参数传递的地址在board_init中初始化
u-boot简单学习笔记(三)——AR9331 uboot启动分析的更多相关文章
- JSP学习笔记(三):简单的Tomcat Web服务器
注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...
- JAVA WEB学习笔记(三):简单的基于Tomcat的Web页面
注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...
- ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心
作者:Grey 原文地址:ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心 前置知识 完成ZooKeeper集群搭建以及熟悉ZooKeeperAPI基本使用 需求 很多程序往 ...
- Log4j简单学习笔记
log4j结构图: 结构图展现出了log4j的主结构.logger:表示记录器,即数据来源:appender:输出源,即输出方式(如:控制台.文件...)layout:输出布局 Logger机滤器:常 ...
- java之jvm学习笔记三(Class文件检验器)
java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...
- VSTO学习笔记(三) 开发Office 2010 64位COM加载项
原文:VSTO学习笔记(三) 开发Office 2010 64位COM加载项 一.加载项简介 Office提供了多种用于扩展Office应用程序功能的模式,常见的有: 1.Office 自动化程序(A ...
- 学习笔记(三)--->《Java 8编程官方参考教程(第9版).pdf》:第十章到十二章学习笔记
回到顶部 注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法 ...
- muduo网络库学习笔记(三)TimerQueue定时器队列
目录 muduo网络库学习笔记(三)TimerQueue定时器队列 Linux中的时间函数 timerfd简单使用介绍 timerfd示例 muduo中对timerfd的封装 TimerQueue的结 ...
- angular学习笔记(三十)-指令(10)-require和controller
本篇介绍指令的最后两个属性,require和controller 当一个指令需要和父元素指令进行通信的时候,它们就会用到这两个属性,什么意思还是要看栗子: html: <outer‐direct ...
随机推荐
- mysql数据库修改字段类型
修改字段类型: alter table 表名 modify column 字段名字 decimal(18, 4) ;
- Leetcode 332.重新安排行程
重新安排行程 给定一个机票的字符串二维数组[from, to],子数组中的两个成员分别表示飞机出发和降落的机场地点,对该行程进行重新规划排序.所有这些机票都属于一个从JFK(肯尼迪国际机场)出发的先生 ...
- dp的两个不错的题
C - Cheapest Palindrome Keeping track of all the cows can be a tricky task so Farmer John has instal ...
- 【java基础 6】java的发展史简介
结合到近期在做springboot框架开发遇到的关于jdk版本的问题,本篇博客,主要介绍一下java的发展历史,侧重纯文介绍每个版本的特性.--主要从理论上做个宏观的了解,不做具体的技术研究讨论! 一 ...
- 【JavaScript 10—应用总结】:连缀
一.总体概述 1.1,什么叫连缀 所谓连缀,最简单的理解就是一句话同时设置一个或多个节点两个或两个以上的操作.比如: <span style="font-size:18px;" ...
- 【Luogu】P2016战略游戏(树形DP)
题目链接 设f[i][j]表示以节点i为根的子树在状态j的情况下的最优解. j有两种情况. j=1:i这个根节点有士兵在站岗. j=0:i这个根节点没有士兵在站岗. 转移方程很好想. f[x][]+= ...
- BZOJ 2720 [Violet 5]列队春游 ——期望DP
很喵的一道题(我可不是因为看了YOUSIKI的题解才变成这样的) $ans=\sum_{x<=n}\sum_{i<=n} iP(L=i)$ 其中P(x)表示视线为x的概率. 所以只需要求出 ...
- Snmp的学习总结——Snmp的基本概念
摘自:http://www.cnblogs.com/xdp-gacl/p/3978825.html 一.SNMP简单概述 1.1.什么是Snmp SNMP是英文"Simple Network ...
- [JSOI2007] 祖玛 (区间DP)
题目描述 这是一个流行在Jsoi的游戏,名称为祖玛. 精致细腻的背景,外加神秘的印加音乐衬托,彷佛置身在古老的国度里面,进行一个神秘的游戏——这就是著名的祖玛游戏.祖玛游戏的主角是一只石青蛙,石青蛙会 ...
- lua学习随笔
1.1 Chunks 1.2 全局变量 访问一个没有初始化的全局变量也不会出错,只不过的到的结果是nil 如果想删除一个全局变量,只需要将变量赋值为nil 1.3 词法约定 标识符 保留字不能作为 ...