`
bigBan
  • 浏览: 6656 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

uboot内核启动过程源码分析

 
阅读更多

下面是我对uboot如何启动内核的代码进行的分析

需要了解的数据结构:

bd 数据结构:

typedef struct bd_info {
int bi_baudrate; /* serial console baudrate */
unsigned long bi_ip_addr; /* IP Address */
struct environment_s *bi_env;
unsigned long bi_arch_number; /* unique id for this board */
unsigned long bi_boot_params; /* where this board expects params */
struct /* RAM configuration */
{
unsigned long start;
unsigned long size;
}bi_dram[CONFIG_NR_DRAM_BANKS];
} bd_t;


gd的数据结构:
typedef struct global_data {
bd_t *bd;
unsigned long flags;
unsigned long baudrate;
unsigned long have_console; /* serial_init() was called */
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
#ifdef CONFIG_FSL_ESDHC
unsigned long sdhc_clk;
#endif
#if 0
unsigned long cpu_clk; /* CPU clock in Hz! */
unsigned long bus_clk;
phys_size_t ram_size; /* RAM size */
unsigned long reset_status; /* reset status register at boot */
#endif
void **jt; /* jump table */

} gd_t;


函数的入口,也就是分析开始的地方:

这里是do_bootm_linux()函数,先要进行一些初始化操作
bd_t *bd = gd->bd; //重要的数据结构bd->得到gd中的bd数据结构
char *s;
int machid = bd->bi_arch_number; //获得机器号码
void (*theKernel)(int zero, int arch, uint params); //申明一个函数指针,注意观察结构


#ifdef CONFIG_CMDLINE_TAG
char *commandline = getenv ("bootargs"); //如果定义了命令参数
#endif


theKernel = (void (*)(int, int, uint))images->ep; //其实这个函数就是指向内核的入口地址的,
//参数可见下面的结构体:
还需要了解的一个数据结构uImage给内核加的头:
typedef struct bootm_headers {
/*
* Legacy os image header, if it is a multi component image
* then boot_get_ramdisk() and get_fdt() will attempt to get
* data from second and third component accordingly.
*/
image_header_t *legacy_hdr_os; /* image header pointer */
image_header_t legacy_hdr_os_copy; /* header copy */
ulong legacy_hdr_valid;


#if defined(CONFIG_FIT)
const char *fit_uname_cfg; /* configuration node unit name */


void *fit_hdr_os; /* os FIT image header */
const char *fit_uname_os; /* os subimage node unit name */
int fit_noffset_os; /* os subimage node offset */


void *fit_hdr_rd; /* init ramdisk FIT image header */
const char *fit_uname_rd; /* init ramdisk subimage node unit name */
int fit_noffset_rd; /* init ramdisk subimage node offset */


void *fit_hdr_fdt; /* FDT blob FIT image header */
const char *fit_uname_fdt; /* FDT blob subimage node unit name */
int fit_noffset_fdt;/* FDT blob subimage node offset */
#endif


#ifndef USE_HOSTCC
image_info_t os; /* os image info */
ulong ep; /* entry point of OS */


ulong rd_start, rd_end;/* ramdisk start/end */


#ifdef CONFIG_OF_LIBFDT
char *ft_addr; /* flat dev tree address */
#endif
ulong ft_len; /* length of flat device tree */


ulong initrd_start;
ulong initrd_end;
ulong cmdline_start;
ulong cmdline_end;
bd_t *kbd;
#endif


int verify; /* getenv("verify")[0] != 'n' */


#define BOOTM_STATE_START (0x00000001)
#define BOOTM_STATE_LOADOS (0x00000002)
#define BOOTM_STATE_RAMDISK (0x00000004)
#define BOOTM_STATE_FDT (0x00000008)
#define BOOTM_STATE_OS_CMDLINE (0x00000010)
#define BOOTM_STATE_OS_BD_T (0x00000020)
#define BOOTM_STATE_OS_PREP (0x00000040)
#define BOOTM_STATE_OS_GO (0x00000080)
int state;


#ifdef CONFIG_LMB
struct lmb lmb; /* for memory mgmt */
#endif
} bootm_headers_t;
从上面的结构体中是可以看出来ep的作用的!


下面这个函数就是来设置起始参数的:跟踪
setup_start_tag (bd);
static void setup_start_tag (bd_t *bd)
{
params = (struct tag *) bd->bi_boot_params; //获得参数的起始地址,并且转换成tag结构体类型


params->hdr.tag = ATAG_CORE; //初始化params->hdr->tag
params->hdr.size = tag_size (tag_core); //初始化params->hdr->size


params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;


params = tag_next (params);
}




#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))


这里列出参数的结构体:
struct tag {
struct tag_header hdr;
union {
struct tag_core core;
struct tag_mem32 mem;
struct tag_videotext videotext;
struct tag_ramdisk ramdisk;
struct tag_initrd initrd;
struct tag_serialnr serialnr;
struct tag_revision revision;
struct tag_videolfb videolfb;
struct tag_cmdline cmdline;


/*
* Acorn specific
*/
struct tag_acorn acorn;


/*
* DC21285 specific
*/
struct tag_memclk memclk;
} u;


展开struct tag_header hdr;得到
struct tag_header {
u32 size;
u32 tag;
};

接下来就执到了setup_commandline_tag (bd, commandline)函数 //设置命令行参数,跟踪调试
我们观察一下这个宏:#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))
表示现在params结构体指向tag结构体后面的部分!
下面这个函数就是来设置命令后参数的:跟踪
setup_commandline_tag (bd, commandline); //设置命令行参数,跟踪调试
static void setup_commandline_tag (bd_t *bd, char *commandline)
{
char *p;


if (!commandline)
return;


/* eat leading white space */
for (p = commandline; *p == ' '; p++);


/* skip non-existent command lines so the kernel will still
* use its default command line.
*/
if (*p == '\0')
return;


params->hdr.tag = ATAG_CMDLINE;
params->hdr.size = (sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2;



strcpy (params->u.cmdline.cmdline, p);


params = tag_next (params);
}只是简单的复制参数!
最后会通过一个函数指针调用,完成启动内核:
theKernel (0, machid, bd->bi_boot_params); //真正的启动内核
大家肯定会有疑问:bd->bi_boot_params是在哪里设置的呢?
还记得void setup_start_tag (bd_t *bd)这个函数把,里面有一句:
params = (struct tag *) bd->bi_boot_params;
具体的请参考c和指针!

版权声明:本文为博主原创文章,未经博主允许不得转载。

分享到:
评论

相关推荐

    讯为4412开发板源码.zip

    讯为4412开发板的uboot和kernel内核源码,学习移植过程,学习uboot的启动流程,分析开发板的初始化流程

    嵌入式系统启动流程基础概念、uboot工作流程、kernel启动流程、文件系统特性分析.

    本系列课程属于嵌入式系统入门级的课程,适合于想要接触嵌入式系统、对嵌入式系统比较感兴趣、想要了解系统启动流程...分析uboot的工作原理、指令集、关键源码,简要分析kernel启动流程,带领大家一起进行内核log分析。

    韦东山Linux视频第1期_裸板_UBoot_文件系统_驱动初步

    第10课第1节 内核启动流程分析之编译体验 第10课第2节 内核启动流程分析之配置 第10课第3节 内核启动流程分析之Makefile 第10课第4节 内核启动流程分析之内核启动 第11课第1节 构建根文件系统之启动第1个程序 ...

    嵌入式linux(uboot) 在MPC8250 平台上的移植

    5.3.1 内核源码结构分析 5.3.2 内核源码修改移植 六、文件系统的组建 6.1 组建网络文件系统(NFS) 6.2 组建自己的文件系统 6.2.1 自定义启动脚本 6.2.2 自定义文件系统 6.2.3 完善自定义文件系统 6.2.4 创建FLASH ...

    韦东山视频目录+链接整合-1 视频目录

    第10课第1节 内核启动流程分析之编译体验 第10课第2节 内核启动流程分析之配置 第10课第3节 内核启动流程分析之Makefile 第10课第4节 内核启动流程分析之内核启动 第11课第1节 构建根文件系统之启动第1个程序 ...

    LINUX系统移植及UBOOT代码分析.zip

    3.4 uboot 部分...........................................................................................................................13 3.5 内核部分.................................................

    Linux系统移植光盘第1部分

    8、Uboot启动介绍 9、内核的编译和配置介绍及说明 10、wvdia移植 11、Makefile 12、Boa分析与编译、测试 13、Boa的交叉编译、移植和测试 14、jffs2文件系统的制作 15、SQLite编译安装以及交叉编译 16、MiniGUI的安装...

    郭天祥ARM9视频教程(第13和20讲均可观看).docx

    2. vivi的启动过程分析 3. vivi的配置移植 4. vivi命令详解 第十四讲 uboot原理分析及移植 1. uboot简介 2. uboot源码目录结构 3. uboot运行代码分析 4. uboot在TX2440A上移植 5. uboot常用命令讲解 uboot使用专题 ...

    mini2440国嵌视频教程+课件+工具+软件+镜像+教程源码下载地址

    -国嵌内核驱动进阶班-3-3(内核启动流程).avi -国嵌内核驱动进阶班-3-4(嵌入式文件系统).avi -国嵌内核驱动进阶班-3-5(必修实验).avi -第4天(内存管理子系统) -国嵌内核驱动进阶班-4-1(Linux内存管理).avi ...

    uboott移植实验手册及技术文档

    (3)将从Nor Flash启动改成从 NAND Flash启动 在文件中找到 195-201 代码,并在 201行后面添加如下代码: 195 copy_loop: 196 ldmia r0!, {r3-r10} /* copy from source address [r0] */ 197 stmiar1!, {r3-r10...

Global site tag (gtag.js) - Google Analytics