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分析的更多相关文章

  1. STM32F103 ucLinux开发之一(BOOT分析及源码)

    STM32F103 ucLinux开发BOOT STM3210E-EVAL官方开发板主芯片STM32F103ZET6: 片内512K Flash,地址0x0800 0000 ~ 0x0807 FFFF ...

  2. uboot中的mmc命令

    一:mmc的命令例如以下: 1:对mmc读操作 mmc read addr blk# cnt 2:对mmc写操作 mmc write addr blk# cnt 3:对mmc擦除操作 mmc eras ...

  3. android uboot中的mmc命令

    一:mmc的命令如下: 1:对mmc读操作 mmc read addr blk# cnt 2:对mmc写操作 mmc write addr blk# cnt 3:对mmc擦除操作 mmc erase ...

  4. Uboot mmc命令解析&NAND flash uboot命令详解

    转载:http://blog.csdn.net/simonjay2007/article/details/43198353 一:mmc的命令如下: 1:对mmc读操作 mmc read addr bl ...

  5. uboot中的mmc命令(转)

    转载地址:https://blog.csdn.net/a624731186/article/details/37700205 一:mmc的命令如下: 1:对mmc读操作 mmc read addr b ...

  6. 【转】uboot中的mmc命令

    转自:https://www.cnblogs.com/yxwkf/p/3855383.html 1:mmcinfo 输入: mmcinfo 显示结果:Manufacturer ID: 45OEM: 1 ...

  7. spring boot实战(第十三篇)自动配置原理分析

    前言 spring Boot中引入了自动配置,让开发者利用起来更加的简便.快捷,本篇讲利用RabbitMQ的自动配置为例讲分析下Spring Boot中的自动配置原理. 在上一篇末尾讲述了Spring ...

  8. boot.img的分析

    1 boot.img  boot.img是由文件头信息,内核数据以及文件系统数据组成,它们之间非页面对齐部分用0填充 文件头信息的具体结构可以在system/core/mkbootimg/bootim ...

  9. Spring Boot 启动原理分析

    https://yq.aliyun.com/articles/6056 转 在spring boot里,很吸引人的一个特性是可以直接把应用打包成为一个jar/war,然后这个jar/war是可以直接启 ...

  10. 《深入实践Spring Boot》阅读笔记之三:核心技术源代码分析

    刚关注的朋友,可以回顾前两篇文章: 基础应用开发 分布式应用开发 上篇文章总结了<深入实践Spring Boot>的第二部分,本篇文章总结第三部分,也是最后一部分.这部分主要讲解核心技术的 ...

随机推荐

  1. codeforces 484b//Maximum Value// Codeforces Round #276(Div. 1)

    题意:给一个数组,求其中任取2个元素,大的模小的结果最大值. 一个数x,它的倍数-1(即kx-1),模x的值是最大的,然后kx-2,kx-3模x递减.那么lower_bound(kx)的前一个就是最优 ...

  2. 在linux下出现cannot restore segment prot after reloc: Permission denied

    应用程序连接oracle的库时会出现如下错误:XXXXX:: error while loading shared libraries: /usr/local/oracle/product/10.2. ...

  3. C++ string类与scanf和printf

    string要用cin和cout输入和输出. 如果一定要用scanf和printf的话,格式为: s.resize(20);scanf("%s", &s[0]); prin ...

  4. spring--boot @Valid的使用

    spring--boot @Valid的使用 每天一个小知识点,每天进步一点点,总结是积累. springBoot @Valid的使用,解释一下.就是给摸个bean类属性(数据库字段)加一个门槛,比如 ...

  5. Oracle12c中性能优化&amp;功能增强新特性之全局索引DROP和TRUNCATE 分区的异步维护

    Oracle 12c中,通过延迟相关索引的维护可以优化某些DROP和TRUNCATE分区命令的性能,同时,保持全局索引为有效. 1.   设置 下面的例子演示带全局索引的表创建和加载数据的过程. -- ...

  6. pyculiarity 时间序列(异常流量)异常检测初探——感觉还可以,和Facebook的fbprophet本质上一样

    demo: from pyculiarity import detect_ts import matplotlib.pyplot as plt import pandas as pd import m ...

  7. sgu108. Self-numbers 2 滚动数组 打表 难度:1

    108. Self-numbers 2 time limit per test: 0.5 sec. memory limit per test: 4096 KB In 1949 the Indian ...

  8. 微信H5支付 C#

    首先奉上 万能的    官方文档 应用场景(废话) H5支付是指商户在微信客户端外的移动端网页展示商品或服务,用户在前述页面确认使用微信支付时,商户发起本服务呼起微信客户端进行支付.         ...

  9. Linux Mint KDE上安装fcitx+sougou输入法

    今天在韩总废弃的笔记本上安装了Linux Mint系统,装好之后第一件想到的事情就是安装个输入法,由于之前系统自带的输入法框架是ibus,我试用了一下发现很不人性化,所以决定换上fcitx+sougo ...

  10. echarts折线图个性化填充、线条、拐点样式

    由于每组数据的拐点样式.线条颜色都不一样,所以series里的每组数据都需要单独设置样式. 首先先来看一下完成后的效果吧 具体设置如下 series: [ { name:systemName[0], ...