U-boot分析与移植(3)----U-boot stage2分析

一来到void start_armboot (void)函数,马上出现两个很重要的数据结构gd_t和bd_t
1、gd_t : global data数据结构定义,位于文件 include/asm-arm/global_data.h。其成员主要是一些全局的系统初始化参数。
plain?
- typedef struct global_data {
- bd_t *bd; // struct board_info<span style="font-family:宋体;">指针,保存板子信息</span>
- unsigned long flags; // <span style="font-family:宋体;">指示标志,如设备已经初始化标志等</span>
- unsigned long baudrate;
- unsigned long have_console; /* serial_init() was called */
- unsigned long reloc_off; /* Relocation Offset */
- unsigned long env_addr; /* Address of Environment struct 环境参数地址*/
- unsigned long env_valid; /* Checksum of Environment valid? */
- unsigned long fb_base; /* base address of frame buffer */
- #ifdef CONFIG_VFD
- unsigned char vfd_type; /* display type */
- #endif
- #if 0
- unsigned long cpu_clk; /* CPU clock in Hz! */
- unsigned long bus_clk;
- unsigned long ram_size; /* RAM size */
- unsigned long reset_status; /* reset status register at boot */
- #endif
- void **jt; /* jump table */
- } gd_t;
2.、bd_t :board info数据结构定义,位于文件 include/asm-arm/u-boot.h。保存板子参数。
plain?
- typedef struct bd_info {
- int bi_baudrate; /* serial console baudrate */
- unsigned long bi_ip_addr; /* IP Address */
- unsigned char bi_enetaddr[6]; /* Ethernet adress */
- struct environment_s *bi_env;
- ulong bi_arch_number; /* unique id for this board <span style="font-family:宋体;">板子</span><span style="font-family:Times New Roman;">ID</span><span style="font-family:宋体;">号</span>*/
- ulong bi_boot_params; /* where this board expects params */
- struct /* RAM configuration */
- {
- ulong start;
- ulong size;
- } bi_dram[CONFIG_NR_DRAM_BANKS];
- #ifdef CONFIG_HAS_ETH1
- /* second onboard ethernet port */
- unsigned char bi_enet1addr[6];
- #endif
- } bd_t;
分配一个存储全局数据的区域,地 址给指针 gd
plain?
- gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
清0并分配空间
plain?
- memset ((void*)gd, 0, sizeof (gd_t));
在gd前面的位置给 gd->bd赋值地址
plain?
- gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
清0并分配空间
plain?
- memset (gd->bd, 0, sizeof (bd_t));
执行一系列初始化函数
plain?
- for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
- if ((*init_fnc_ptr)() != 0) {
- hang ();
- }
- }
假如函数指针指向的函数返回值不为0,那么在hang()里就会死循环,初始化失败
plain?
- void hang (void)
- {
- puts ("### ERROR ### Please RESET the board ###\n");
- for (;;);
- }
函数列表如下:
每个初始化函数正常情况下返回值是0
plain?
- init_fnc_t *init_sequence[] = {
- cpu_init, /* 初始化irq/fiq模式的栈*/
- board_init, /* 设置系统时钟*/
- interrupt_init, /*初始化定时器*/
- env_init, /* 检查flash上的环境参数是否有效*/
- init_baudrate, /* 初始化波特率*/
- serial_init, /* 初始化串口*/
- console_init_f, /*初始化串口控制台*/
- display_banner, /* say that we are here */
接着进行一些NOR FLASH,LCD,串口,控制台,sd卡,网卡等初始化,不一一列举了。
终于来到重要的时刻了 - -#
进入一个死循环
plain?
- for (;;)
- {
- main_loop ();
- }
继续跟踪
发现在bootdelay时间内按下键进入命令行,用run_command来解析命令
plain?
- #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
- s = getenv ("bootdelay");
- bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
- debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
如果CONFIG_BOOTDELAY已经定义,用s得到环境变量bootdelay,然后倒数启动内核
plain?
- #ifdef CONFIG_BOOTCOUNT_LIMIT
- if (bootlimit && (bootcount > bootlimit)) {
- printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n",
- (unsigned)bootlimit);
- s = getenv ("altbootcmd");
- }
- else
- #endif /* CONFIG_BOOTCOUNT_LIMIT */
- s = getenv ("bootcmd");
CONFIG_BOOTCOUNT_LIMIT是设置u-boot启动次数的限制
最后s = getenv ("bootcmd");获得启动参数
plain?
- run_command (s, 0);
启动命令解析
在run_command 函数里最终执行命令
plain?
- /* OK - call function to do the command */
- if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {
- rc = -1;
- }
这是一个命令结构体,原型如下:
plain?
- struct cmd_tbl_s {
- char *name; /* Command Name */
- int maxargs; /* 最大的参数个数 */
- int repeatable; /* 命令可否重复 */
- int (*cmd)(struct cmd_tbl_s *, int, int, char *[]);/*对应的函数指针*/
- char *usage; /* Usage message (short) */
正常情况下就会执行U_BOOT_CMD命令,U_BOOT_CMD宏定义一个命令,命令宏原型如下:
plain?
- /*命令宏U_BOOT_CMD*/
- #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}
假若上面是传入的是一个bootm命令启动内核,将会调用相应的
plain?
- U_BOOT_CMD(
- bootm, CFG_MAXARGS, 1, do_bootm,
- "bootm - boot application image from memory\n",
- "[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"
在do_bootm函数里,将用switch case检查内核zImage类型,解压方式,操作系统等,因为zImage是自解压的,不用解压
plain?
- switch (hdr->ih_os) {
- default: /* handled by (original) Linux case */
- case IH_OS_LINUX:
- do_bootm_linux (cmdtp, flag, argc, argv,
- addr, len_ptr, verify);
- break;
最后,将进入Armlinux.c的do_bootm_linux函数启动Linux内核
U_Boot也是通过标记列表向内核传递参数的
plain?
- #ifdef CONFIG_CMDLINE_TAG
- char *commandline = getenv ("bootargs");
- #endif
CONFIG_CMDLINE_TAG在smdk2410.h里已经定义了
theKernel指向内核 存放的地址,(对于ARM架构的CPU,通常是0x30008000),
/*声明内核的入口函数指针*/
plain?
- void (*theKernel)(int zero, int arch, uint params);
/*把内核入口地址赋值给theKernel,hdr是image_header_t结构体,指向uImage头部 ,ih_ep是内核的入口点(Entry Point)*/
plain?
- theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);
/*最后是对内核入口函数的调用,bd->bi_arch_number是这个板子机器类型ID, bd->bi_boot_params是传给内核的参数,从标记列表地址开始*/
plain?
- theKernel (0, bd->bi_arch_number, bd->bi_boot_params);
plain?
- 引导Linux内核启动的必须要满足的几个条件:
plain?
- * CPU register settings //这里也就是我们的theKernel中的作用
- o r0 = 0.
- o r1 = machine type number.
- o r2 = physical address of tagged list in system RAM.
- * CPU mode
- o All forms of interrupts must be disabled (IRQs and FIQs.)
- o The CPU must be in SVC mode. (A special exception exists for Angel.)
- * Caches, MMUs
- o The MMU must be off.
- o Instruction cache may be on or off.
- o Data cache must be off and must not contain any stale data.
- * Devices
- o DMA to/from devices should be quiesced.
- * The boot loader is expected to call the kernel image by jumping directly to the first instruction of the kernel image.
U-boot分析与移植(3)----U-boot stage2分析的更多相关文章
- 【转】U-boot分析与移植(1)----bootloader分析
原文网址:http://blog.csdn.net/jianchi88/article/details/7061089 一.Boot Loader 概念 就是在操作系统内核运行之前运行的一段小程序. ...
- U-boot分析与移植(1)----bootloader分析
一.Boot Loader 概念 就是在操作系统内核运行之前运行的一段小程序.通过这段小程序,我们可以初始化硬件设备.建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作 ...
- spring boot实战(第十三篇)自动配置原理分析
前言 spring Boot中引入了自动配置,让开发者利用起来更加的简便.快捷,本篇讲利用RabbitMQ的自动配置为例讲分析下Spring Boot中的自动配置原理. 在上一篇末尾讲述了Spring ...
- 《深入实践Spring Boot》阅读笔记之三:核心技术源代码分析
刚关注的朋友,可以回顾前两篇文章: 基础应用开发 分布式应用开发 上篇文章总结了<深入实践Spring Boot>的第二部分,本篇文章总结第三部分,也是最后一部分.这部分主要讲解核心技术的 ...
- spring Boot(十九):使用Spring Boot Actuator监控应用
spring Boot(十九):使用Spring Boot Actuator监控应用 微服务的特点决定了功能模块的部署是分布式的,大部分功能模块都是运行在不同的机器上,彼此通过服务调用进行交互,前后台 ...
- Spring Boot (十): Spring Boot Admin 监控 Spring Boot 应用
Spring Boot (十): Spring Boot Admin 监控 Spring Boot 应用 1. 引言 在上一篇文章<Spring Boot (九): 微服务应用监控 Spring ...
- Spring Boot高频面试题:Spring Boot执行原理
之前一篇文章Spring Boot快速入门文章中,我们已经体会到Spring Boot的神器,不再像之前Spring那样需要繁琐的XML,甚至几秒钟就能搭建出Spring的项目骨架.接下来我们简单分析 ...
- Linux之uboot分析与移植20160601
说一下uboot分析与移植: 1.下载.建立source insight工程.编译.烧写.如果无运行分析原因 tar xjf u-boot-2012.04.01.tar.bz2 cd u-boot-2 ...
- 基于Petri网的工作流分析和移植
基于Petri网的工作流分析和移植 一.前言 在实际应用场景,包括PEC的订单流程从下订单到订单派送一直到订单完成都是按照一系列预先规定好的工作流策略进行的. 通常情况下如果是采用面向过程的编程方法, ...
- spring boot系列01--快速构建spring boot项目
最近的项目用spring boot 框架 借此学习了一下 这里做一下总结记录 非常便利的一个框架 它的优缺点我就不在这背书了 想了解的可以自行度娘谷歌 说一下要写什么吧 其实还真不是很清楚,只是想记录 ...
随机推荐
- CheckBox复选框控件
CheckBox复选框控件 一.简介 1. 2.类结构图 二.CheckBox复选框控件使用方法 这里是使用java代码在LinearLayout里面添加控件 1.新建LinearLayout布局 2 ...
- 20165332《Java程序设计》第2周学习总结
<Java程序设计>第2周学习总结 2-3章学习内容 第二章 标识符(名字) 关键字 int class 基本数据类型 逻辑类型 整数类型 字符类型 浮点类型 各类型相互转换 --低级别给 ...
- Referenced file contains errors (http://www.springframework.org/schema/aop/spring-aop-3.0.xsd). For more information, right click on the message in th
XML code<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC &q ...
- 51nod 1009 数位dp入门
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1009 1009 数字1的数量 基准时间限制:1 秒 空间限制:13107 ...
- python---迭代器与生成器(一)
迭代器与生成器 迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式.. 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代 ...
- day13作业
#作业1猜年龄 , 可以让用户最多猜三次! # Auther:bing #!/usr/bin/env python age = 24 print("猜年龄") for i in r ...
- 遮罩效果 css3
CSS3提供了遮罩效果,这是以前CSS2中比较难实现的一个新特性,配合SVG或者canvas同样也可以实现遮罩效果,他的效果就如下图所示: 简单的说就是在一个层上面加一个过滤层,过滤层透明度越低,底层 ...
- [转]页游开发中的 Python 组件与模式Presentation Transcript
转: 页游开发中的 Python 组件与模式Presentation Transcript 1. 页游开发中的 Python 组件与模式 赖勇浩( http://laiyonghao.com ) 20 ...
- C 时间函数总结
头文件 time.h 处理器时间函数 clock_t clock(void) 处理器的处理时间,如可以在 main开始的地方 使用这个函数,然后再 完毕后 调用这个函数 并 减去 之前的返回值,为了 ...
- Java进阶知识点7:不要只会写synchronized - JDK十大并发编程组件总结
一.背景 提到Java中的并发编程,首先想到的便是使用synchronized代码块,保证代码块在并发环境下有序执行,从而避免冲突.如果涉及多线程间通信,可以再在synchronized代码块中使用w ...