自己写bootloader笔记5---设置u-boot传给内核的参数分析

时间:2022-05-21 16:53:00

1、分析

(1)u-boot要启动内核,把内核从flash读到SDRAM ,要调到SDRAM执行,u-boot执行时内核还没执行,内核执行时,u-boot已完结。u-boot传参数给内核(双方约定一个位置),u-boot在那位置存数据,数据格式也要 双方约定好

(2)0x30000000是内存的起始地址,0x30008000地址开始用于存放内核,参数存储双方约定的地址是0x30000100,


自己写bootloader笔记5---设置u-boot传给内核的参数分析


2、结构分析(参数称为tag ,标志的意思)

//表参数设置的开始

setup_start_tag();

//告诉内核,内存有多大

setup_memory_tags();

//命令行参数 root=/dev/mtdblock3表示根文件系统在哪里 init=/linuxrc console=ttySAC0表示内核启动时,内核的打印信息从哪个串口打印出来

setup_commandline_tag("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0");

//表参数设置的结束

setup_end_tag();

3、setup_start_tag()分析(tag的头部)

(1)//定义tag结构体

自己写bootloader笔记5---设置u-boot传给内核的参数分析
static struct tag *params;

(2)指定参数存放的起始地址0x30000100

params = (struct tag *)0x30000100;

自己写bootloader笔记5---设置u-boot传给内核的参数分析

params->hdr.tag = ATAG_CORE; //ATAG_CORE宏定义为0x54410001,表示一个参数开始的标志

 自己写bootloader笔记5---设置u-boot传给内核的参数分析

tag_size()函数表示头部结构体tag_header的大小(8字节)加上tag_core结构体的大小(12字节),单位是右移2位,也就是除以4,单位是4字节。(8+12)/4=5,也就是size为5

params->hdr.size = tag_size (tag_core);
自己写bootloader笔记5---设置u-boot传给内核的参数分析
params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;

自己写bootloader笔记5---设置u-boot传给内核的参数分析

当前位置加上size,由于u32型的,指针相加,指针加1相当于加4个字节

params = tag_next (params);
}

4、setup_memory_tags()分析(tags中的s表示多个,如果板子内存有多段,可设置多个tag)

{
params->hdr.tag = ATAG_MEM; //ATAG_MEM宏定义为0x54410002,表示内存的标志


自己写bootloader笔记5---设置u-boot传给内核的参数分析
size为4

params->hdr.size = tag_size (tag_mem32);
//内存开始地址0x30000000
params->u.mem.start = 0x30000000


//内存大小64M
params->u.mem.size  = 64*1024*1024;

params = tag_next (params);
}

5、setup_commandline_tag(char *cmdline)分析

{自己写bootloader笔记5---设置u-boot传给内核的参数分析

用strlen函数算出字符串cmdline的大小,加1是要包括结束字符
int len = strlen(cmdline) + 1;
//ATAG_CMDLINE宏定义为0x54410009,表示命令行的标志
params->hdr.tag  = ATAG_CMDLINE;

size是以4字节为单位的,所以字符串要向4取整( len + 3
params->hdr.size = (sizeof (struct tag_header) + len + 3) >> 2;

//放的是一大串字符串,把字符串 cmdline拷贝到结构体cmdline的cmdline 成员
strcpy (params->u.cmdline.cmdline, cmdline);


params = tag_next (params);
}

6、 setup_end_tag(void)分析

{ATAG_NONE宏定义为0x00000000.表示结束标志
params->hdr.tag = ATAG_NONE;  


params->hdr.size = 0;
}