u-boot分析
4.Bootloader:u-boot.2009.08分析与移植
4.1:分析u-boot根文件夹下的Makefile,能够看到uboot编译的顺序例如以下,由此可知编译运行的第一个文件是cpu/$(CPU)/start.o,又因为是基于
arm920t架构的,所以去分析cpu/arm920t/start.S源文件。
# U-Boot objects....order is important (i.e. start must be first)
OBJS = cpu/$(CPU)/start.o
OBJS := $(addprefix $(obj),$(OBJS))
LIBS = lib_generic/libgeneric.a
LIBS += lib_generic/lzma/liblzma.a
LIBS += lib_generic/lzo/liblzo.a
LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo \
"board/$(VENDOR)/common/lib$(VENDOR).a"; fi)
LIBS += cpu/$(CPU)/lib$(CPU).a
LIBS += lib_$(ARCH)/lib$(ARCH).a
LIBS += fs/...(.a)
LIBS += net/libnet.a
LIBS += disk/libdisk.a
LIBS += drivers/...(.a)
LIBS += common/libcommon.a
LIBS += libfdt/libfdt.a
LIBS += api/libapi.a
LIBS += post/libpost.a
LIBS := $(addprefix $(obj),$(LIBS))
4.2:分析cpu/arm920t/start.S源文件:由ARM架构可知程序的运行顺序是开发板一上电即从零地址開始运行,在零地址存放的是一条复位异常中断处
理,依次分析可知程序从上电開始的运行依次例如以下:设置处理器模式、关闭看门狗、关闭中断、设置分频系数比、系统初始化(flush I/D cache、disable MMU、内存sdram相关初始化)、重定位代码(从flash复制uboot代码到SDRAM中)、初始化堆栈、清除bss段、跳转到第二阶段的C语言代码入口函数start_armboot处
运行。
(1).globl _start
_start:
b start_code
(2)start_code:
/* set the cpu to SVC32 mode*/
/* turn off the watchdog */
/* mask all IRQs by setting all bits in the INTMR - default */
/* setup FCLK:HCLK:PCLK */
bl cpu_init_crit /*do sys-critical inits only at reboot*/
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
/* relocate U-Boot from nor flash to RAM */
/* Set up the stack */
/* Clear bss */
/* jump to second stage */
ldr pc, _start_armboot
_start_armboot:.word start_armboot
4.3:分析/lib_arm/board.c里的start_armboot函数:
gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));
memset ((void*)gd, 0, sizeof (gd_t));等,初始化gd_t结构体指针gd,并初始化。
typedef int (init_fnc_t) (void);
init_fnc_t *init_sequence[] = {
#if defined(CONFIG_ARCH_CPU_INIT)
arch_cpu_init,/* basic arch cpu dependent setup */
#endif
board_init,
/* basic board dependent setup */
#if defined(CONFIG_USE_IRQ)
interrupt_init,/* set up exceptions */
#endif
timer_init,
/* initialize timer */
env_init,
/* initialize environment */
init_baudrate,/* initialze baudrate settings */
serial_init,
/* serial communications setup */
console_init_f,/* stage 1 init of console */
display_banner,/* say that we are here */
#if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo,/* display cpu info (and speed) */
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
checkboard,
/* display board info */
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
init_func_i2c,
#endif
dram_init,
/* configure available RAM banks */
#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)
arm_pci_init,
#endif
display_dram_config,
NULL,
};
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
},通过一个for循环来依次訪问函数指针数组init_sequence中的成员函数,进一步完毕相关初始化和相关设置。
nand_init();
/* go init the NAND */。初始化nand flash。
serial_initialize(); 。初始化串口。
/* 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 */,在无限for循环内,运行main_loop函数。
4.4:分析/common/main.c里的main_loop函数:处理uboot命令。
/*
* Main Loop for Monitor Command Processing
*/
for(;;){
#ifdef CONFIG_BOOT_RETRY_TIME
if (rc >= 0) {
/* Saw enough of a valid command to
* restart the timeout.
*/
reset_cmd_timeout();
}
#endif
len = readline (CONFIG_SYS_PROMPT);
flag = 0;
/* assume no special flags for now */
if (len > 0)
strcpy (lastcommand, console_buffer);
else if (len == 0)
flag |= CMD_FLAG_REPEAT;
#ifdef CONFIG_BOOT_RETRY_TIME
else if (len == -2) {
/* -2 means timed out, retry autoboot
*/
puts ("\nTimed out waiting for command\n");
# ifdef CONFIG_RESET_TO_RETRY
/* Reinit board to run initialization code again */
do_reset (NULL, 0, 0, NULL);
# else
return;
/* retry autoboot */
# endif
}
#endif
if (len == -1)
puts ("<INTERRUPT>\n");
else
rc = run_command (lastcommand, flag);
if (rc <= 0) {
/* invalid command or not repeatable, forget it */
lastcommand[0] = 0;
}
}
依据输入的命令格式,解析命令參数,运行命令(运行run_command函数)。/common/main.c里的run_command函数。依据命令表结构体cmd_tbl_s来找到输入命令所相应的实现函数。
/*
* Monitor Command Table
*/
struct cmd_tbl_s {
char *name;/* Command Name
*/
int maxargs;/* maximum number of arguments
*/
int repeatable;/* autorepeat allowed?
*/
/* Implementation function*/
int (*cmd)(struct cmd_tbl_s *, int, int, char *[]);
char *usage;/* Usage message
(short)*/
#ifdef
CONFIG_SYS_LONGHELP
char *help;/* Help message
(long)*/
#endif
#ifdef CONFIG_AUTO_COMPLETE
/* do auto completion on the arguments */
int (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]);
#endif
};
typedef struct cmd_tbl_scmd_tbl_t;
cmd_tbl_t *cmdtp;
/* OK - call function to do the command */
if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {
rc = -1;
}//至此。依据不同的uboot命令,去运行不同的实现函数。
4.5:uboot启动linux操作系统的命令是bootm。uboot的bootm命令的实现文件是cmd_bootm.c,所以接着来分析/common/cmd_bootm.c文件:命令实现的格式例如以下:当中命令是bootm,实现函数是do_bootm函数。
#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))
#ifdef CONFIG_SYS_LONGHELP
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}
#else /* no long help info */
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage}
#endif
/* CONFIG_SYS_LONGHELP */
U_BOOT_CMD(
bootm,
CONFIG_SYS_MAXARGS, 1,do_bootm,
"boot application image from memory",
"[addr [arg ...]]\n - boot application image stored in memory\n"
"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
"\t'arg' can be the address of an initrd image\n"
"\tbdt - OS specific bd_t processing\n"
"\tcmdline - OS specific command line processing/setup\n"
"\tprep - OS specific prep before relocation or go\n"
"\tgo - start OS"
);
4.6:分析/common/cmd_bootm.c中的do_bootm函数:
static bootm_headers_t images;/* pointers to os/initrd/fdt images */
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
disable_interrupts();
usb_stop();
icache_disable();
dcache_disable();
ret = bootm_load_os(images.os, &load_end, 1); //载入详细的操作系统
images.os.os == IH_OS_LINUX //假设详细载入的是linux,则有下面
boot_os_fn
*boot_fn;
boot_fn = boot_os[images.os.os];//boot_fn指针指向boot_os数组中的特定类型函数
boot_fn(0, argc, argv, &images);//调用do_bootm_linux函数
boot_os_fn * boot_os[] = {
#ifdef CONFIG_BOOTM_LINUX
[IH_OS_LINUX] = do_bootm_linux,
#endif
... ...
}; //由此可知,若载入的是linux系统。则调用do_bootm_linux函数,do_bootm_linux在/lib_arm/bootm.c文件中
4.7:分析/lib_arm/bootm.c中的do_bootm_linux函数:
void (*theKernel)(int zero, int arch, uint params);
theKernel = (void (*)(int, int, uint))images->ep;//images->ep(entry point)
setup_start_tag (bd);
... ...
setup_end_tag (bd);
theKernel (0, machid, bd->bi_boot_params); //至此。跳转到linux内核開始运行,系统启动起来
/* does not return */
return 1;
u-boot分析的更多相关文章
- STM32F103 ucLinux开发之一(BOOT分析及源码)
STM32F103 ucLinux开发BOOT STM3210E-EVAL官方开发板主芯片STM32F103ZET6: 片内512K Flash,地址0x0800 0000 ~ 0x0807 FFFF ...
- uboot中的mmc命令
一:mmc的命令例如以下: 1:对mmc读操作 mmc read addr blk# cnt 2:对mmc写操作 mmc write addr blk# cnt 3:对mmc擦除操作 mmc eras ...
- android uboot中的mmc命令
一:mmc的命令如下: 1:对mmc读操作 mmc read addr blk# cnt 2:对mmc写操作 mmc write addr blk# cnt 3:对mmc擦除操作 mmc erase ...
- Uboot mmc命令解析&NAND flash uboot命令详解
转载:http://blog.csdn.net/simonjay2007/article/details/43198353 一:mmc的命令如下: 1:对mmc读操作 mmc read addr bl ...
- uboot中的mmc命令(转)
转载地址:https://blog.csdn.net/a624731186/article/details/37700205 一:mmc的命令如下: 1:对mmc读操作 mmc read addr b ...
- 【转】uboot中的mmc命令
转自:https://www.cnblogs.com/yxwkf/p/3855383.html 1:mmcinfo 输入: mmcinfo 显示结果:Manufacturer ID: 45OEM: 1 ...
- spring boot实战(第十三篇)自动配置原理分析
前言 spring Boot中引入了自动配置,让开发者利用起来更加的简便.快捷,本篇讲利用RabbitMQ的自动配置为例讲分析下Spring Boot中的自动配置原理. 在上一篇末尾讲述了Spring ...
- boot.img的分析
1 boot.img boot.img是由文件头信息,内核数据以及文件系统数据组成,它们之间非页面对齐部分用0填充 文件头信息的具体结构可以在system/core/mkbootimg/bootim ...
- Spring Boot 启动原理分析
https://yq.aliyun.com/articles/6056 转 在spring boot里,很吸引人的一个特性是可以直接把应用打包成为一个jar/war,然后这个jar/war是可以直接启 ...
- 《深入实践Spring Boot》阅读笔记之三:核心技术源代码分析
刚关注的朋友,可以回顾前两篇文章: 基础应用开发 分布式应用开发 上篇文章总结了<深入实践Spring Boot>的第二部分,本篇文章总结第三部分,也是最后一部分.这部分主要讲解核心技术的 ...
随机推荐
- 一篇关于oracle psu的文章(转)
Oracle Database PSU/CPU Posted on 2011-07-28 16:27 dbblog 阅读(2569) 评论(0) 编辑 收藏 1. 什么是PSU/CPU?CPU: Cr ...
- Sql Server约束的学习一(主键约束、外键约束、唯一约束)
一.约束的分类 1.实体约束 实体约束是关于行的,比如某一行出现的值不允许出现在其他行,例如主键约束. 2.域约束 域约束是关于列的,对于所有行,某一列有那些约束,例如检查约束. 3.参照完整性约束 ...
- learning shell script prompt to run with superuser privileges (4)
Shell script prompt to run with superuser privileges [Purpose] Check whether have root privil ...
- mongodb的capped Collection集合
db.createCollection(name, {capped: true, autoIndexId: true, size: 1000, max :100} ) name:集合的名字 cappe ...
- 使用MyEclipse开发Java EE应用:企业级应用程序项目(下)
你开学,我放价!MyEclipse线上狂欢继续!火热开启中>> [MyEclipse最新版下载] 二.项目组织.依赖性和类解析 JEE规范为企业应用程序定义了一个分层的Java类解决策略, ...
- CUDA ---- Shared Memory
CUDA SHARED MEMORY shared memory在之前的博文有些介绍,这部分会专门讲解其内容.在global Memory部分,数据对齐和连续是很重要的话题,当使用L1的时候,对齐问题 ...
- 增量打包DOC版
压缩zip的命令有的系统没有的自己去下载一个,否则关闭压缩zip的命令. 有需要的自行更改,这是满足我需求的. 执行 publish.bat 即可,当然需要将文件清单写好放在 resources.tx ...
- Tomcat启动失败:Server Tomcat v8.0 Server at localhost was unable to start within 45 seconds
问题如下: 解决办法: 再次重启服务器就能解决这个问题.
- webservice之wsdl
最近项目中需要将原来的通信协议改成webservice,由于业务需要,我们需要向server端传送数据,故server方提供给我们一个.wsdl文件,内容如下: WSDL即Web Services D ...
- php 易忽略问题