start_amboot()函数分析
一、整体流程
start_amboot()函数是执行完start.S汇编文件后第一个C语言函数,完成的功能自然还是初始化的工作 。
1、全局变量指针r8设定,以及全局变量区清零
2、执行一些类初始化函数,详细见init_sequence所对应的函数
3、初始化norflash
4、初始化显示器
5、初始化堆区
6、初始化nandflash
7、环境变量重定位,详见uboot环境变量(env)初始化
8、网络设置
9、设备初始化,详见uboot的devices_init函数分析
10、函数跳转表初始化,详见uboot的jumptable_init函数分析
11、控制台初始化
12、中断使能
最终:进入main_loop
二、函数注释
void start_armboot (void)
{
init_fnc_t **init_fnc_ptr;
char *s;
#ifndef CFG_NO_FLASH
ulong size;
#endif
#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
unsigned long addr;
#endif /* Pointer is writable since we allocated a register for it */
gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t)); //给全局变量指针gd赋值
/* compiler optimization barrier needed for GCC >= 3.4 */
__asm__ __volatile__("": : :"memory"); //实验中这句话没什么作用 memset ((void*)gd, 0, sizeof (gd_t)); //gd_t存储区域清零
gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
memset (gd->bd, 0, sizeof (bd_t)); monitor_flash_len = _bss_start - _armboot_start; for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {//执行一系列初始化函数
if ((*init_fnc_ptr)() != 0) {
hang ();
}
} #ifndef CFG_NO_FLASH
/* configure available FLASH banks */
size = flash_init (); //norflash的初始化
display_flash_config (size); //打印norflash的大小
#endif /* CFG_NO_FLASH */ #ifdef CONFIG_VFD
# ifndef PAGE_SIZE
# define PAGE_SIZE 4096
# endif
/*
* reserve memory for VFD display (always full pages)
*/
/* bss_end is defined in the board-specific linker script */
addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
size = vfd_setmem (addr);
gd->fb_base = addr;
#endif /* CONFIG_VFD */ #ifdef CONFIG_LCD
# ifndef PAGE_SIZE
# define PAGE_SIZE 4096
# endif
/*
* reserve memory for LCD display (always full pages)
*/
/* bss_end is defined in the board-specific linker script */
addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
size = lcd_setmem (addr);
gd->fb_base = addr;
#endif /* CONFIG_LCD */ /* armboot_start is defined in the board-specific linker script */
mem_malloc_init (_armboot_start - CFG_MALLOC_LEN); #if (CONFIG_COMMANDS & CFG_CMD_NAND) //如果定义了CFG_CMD_NAND,就
puts ("NAND: ");//打印nand信息
nand_init(); //进行nand 初始化
#endif #ifdef CONFIG_HAS_DATAFLASH
AT91F_DataflashInit();
dataflash_print_info();
#endif /* initialize environment */
env_relocate (); //无论使用默认的环境变量还是任何存储器上的,最终都将环境变量加载到内存的指定区域, #ifdef CONFIG_VFD
/* must do this after the framebuffer is allocated */
drv_vfd_init();
#endif /* CONFIG_VFD */ /* IP Address */
gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr"); //从环境变量获取网卡的MAC地址并填充gd结构体变量 /* MAC Address */
{
int i;
ulong reg;
char *s, *e;
char tmp[64]; i = getenv_r ("ethaddr", tmp, sizeof (tmp));
s = (i > 0) ? tmp : NULL; for (reg = 0; reg < 6; ++reg) {
gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
if (s)
s = (*e) ? e + 1 : e;
} #ifdef CONFIG_HAS_ETH1
i = getenv_r ("eth1addr", tmp, sizeof (tmp));
s = (i > 0) ? tmp : NULL; for (reg = 0; reg < 6; ++reg) {
gd->bd->bi_enet1addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
if (s)
s = (*e) ? e + 1 : e;
}
#endif
} devices_init ();//设备初始化 /* get the devices list going. */ #ifdef CONFIG_CMC_PU2
load_sernum_ethaddr ();
#endif /* CONFIG_CMC_PU2 */ jumptable_init (); //跳转表初始化,跳转表建立在堆区 console_init_r (); //控制端初始化 /* fully init console as a device */ #if defined(CONFIG_MISC_INIT_R)
/* miscellaneous platform dependent initialisations */
misc_init_r ();
#endif /* enable exceptions */
enable_interrupts (); //使能中断 /* Perform network card initialisation if necessary */
#ifdef CONFIG_DRIVER_CS8900
cs8900_get_enetaddr (gd->bd->bi_enetaddr); //获得网卡地址
#endif #if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)
if (getenv ("ethaddr")) {
smc_set_mac_addr(gd->bd->bi_enetaddr);
}
#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */ /* Initialize from environment */
if ((s = getenv ("loadaddr")) != NULL) {//读取环境变量loadaddr到全局变量load_addr中
load_addr = simple_strtoul (s, NULL, 16);
}
#if (CONFIG_COMMANDS & CFG_CMD_NET)
if ((s = getenv ("bootfile")) != NULL) {//读取环境变量bootfile到全局变量BootFile中
copy_filename (BootFile, s, sizeof (BootFile));
}
#endif /* CFG_CMD_NET */ #ifdef BOARD_LATE_INIT //没有定义
board_late_init ();
#endif
#if (CONFIG_COMMANDS & CFG_CMD_NET)
#if defined(CONFIG_NET_MULTI)
puts ("Net: ");
#endif
eth_initialize(gd->bd);
#endif
/* 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 */
}
start_amboot()函数分析的更多相关文章
- split(),preg_split()与explode()函数分析与介
split(),preg_split()与explode()函数分析与介 发布时间:2013-06-01 18:32:45 来源:尔玉毕业设计 评论:0 点击:965 split()函数可以实 ...
- string函数分析
string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...
- uboot的jumptable_init函数分析
一.函数说明 函数功能:安装系统函数指针 函数位置:common/exports.c 二.函数分析 void jumptable_init (void) { int i; gd->jt = (v ...
- Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析
Linux-0.11内存管理模块是源码中比較难以理解的部分,如今把笔者个人的理解发表 先发Linux-0.11内核内存管理get_free_page()函数分析 有时间再写其它函数或者文件的:) /* ...
- 31.QPainter-rotate()函数分析-文字旋转不倾斜,图片旋转实现等待
在上章和上上上章: 28.QT-QPainter介绍 30.QT-渐变之QLinearGradient. QConicalGradient.QRadialGradient 学习了QPainter基础绘 ...
- 如何验证一个地址可否使用—— MmIsAddressValid函数分析
又是一篇内核函数分析的博文,我个人觉得Windows的内核是最好的老师,当你想实现一个功能之前可以看看Windows内核是怎么做的,说不定就有灵感呢:) 首先看下官方的注释说明: /*++ Routi ...
- STM32F10X固件库函数——串口清状态位函数分析
STM32F10X固件库函数——串口清状态位函数分析 最近在测试串口热插拔功能的时候,意外发现STM32F10X的串口库函数中,清理串口状态位函数稍稍有点不解.下面是改函数的源码: /******** ...
- 常用string函数分析
string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...
- linux C函数之strdup函数分析【转】
本文转载自:http://blog.csdn.net/tigerjibo/article/details/12784823 linux C函数之strdup函数分析 一.函数分析 1.函数原型: #i ...
随机推荐
- MVC-控制器向View传值的三种方法
1.提供视图模型对象 你能把一个对象作为View方法的参数传递给视图. public ViewResult Index() { DateTime date = DateTime.Now; return ...
- chrome 全屏无法退出
起因:chrome 按F11 全屏后,再按F11 死活无法退出全屏,关掉后,再打开chrome,自动全屏,F11无法退出全屏 系统:centos 6.3 解决:找到 chrome的用户数据存储目录,( ...
- Linux 内核开发—内核简单介绍
内核简单介绍 Linux 构成 Linux 为什么被划分为系统空间和内核空间 隔离核心程序和应用程序,实现对核心程序和数据的保护. 什么内核空间,用户空间 内核空间和用户空间是程序执行的两种不同的状态 ...
- HTML5另类塔防游戏 -《三国战线》公布
关于本作 游戏介绍 本游戏是一款另类塔防游戏.本作以三国这段历史为题材,提供了从颍川之战到官渡之战.官渡之战到夷陵之战.夷陵之战到五丈原之战等15个关卡.在每一个关卡中,你会控制一名三国武将与出现的敌 ...
- [TypeScript] Configuring TypeScript Which Files to Compile with "Files" and "OutDir"
This lesson shows how to configure the .tsconfig so you only compile the .ts files you want. It then ...
- linux中的网络通信指令 分类: 学习笔记 linux ubuntu 2015-07-06 16:02 134人阅读 评论(0) 收藏
1.write write命令通信是一对一的通信,即两个人之间的通信,如上图. 效果图 用法:write <用户名> 2.wall wall指令可将信息发送给每位同意接收公众信息的终端机用 ...
- oracle数据快速删除
上文说了创建数据还原点的事,数据恢复的前提是我们在删除的时候使用了delete命令来删除,delete在删除的过程中会写日志(所以我们的数据才能够恢复),当然,写日志会导致删除速度变慢.如果我们使用t ...
- CXF整合Spring开发WebService
刚开始学webservice时就听说了cxf,一直没有尝试过,这两天试了一下,还不错,总结如下: 要使用cxf当然是要先去apache下载cxf,下载完成之后,先要配置环境变量,有以下三步: 1.打开 ...
- Java基础知识强化之集合框架笔记53:Map集合之Map集合的遍历 键值对对象找键和值
1. Map集合的遍历(键值对对象找键和值) Map -- 夫妻对 思路: A: 获取所有结婚证的集合 B: 遍历结婚证的集合,得到每一个结婚证 C: 根据结婚证获取丈夫和妻子 转换: A: ...
- 微信分组群发45028,微信分组群发has no masssend quota hint
微信分组群发45028,微信分组群发has no masssend quota hint >>>>>>>>>>>>>> ...