https://www.cnblogs.com/pokerface/p/5217106.html
![](https://i-blog.csdnimg.cn/blog_migrate/5db189bd7ca03b4276b7631204338297.png)
cmd_bootm.c //传递给内核的参数
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
do_bootm_linux (cmdtp, flag, argc, argv, addr, len_ptr, verify);
原型:void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong addr, ulong *len_ptr, int verify)
char *commandline = getenv ("bootargs");
void (*theKernel)(int zero, int arch, uint params); //函数指针
theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep); //跳转到内核的位置ntohl(hdr->ih_ep)
setup_start_tag //tag分为tag_header、union.u两部分组成
params->hdr.tag = 0x54410001 //tag_header为先size后tag组成
params->hdr.size = tag_size(tag_core) = 5 //union.u由很多部分组成,详见源文件asm-arm/setup.h
#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
struct tag_header { u32 size;u32 tag;}; //8字节
struct tag_core { u32 flags;u32 pagesize;u32 rootdev;}; //12字节
>> 2 //除以4等于5
params->u.core.flags = 0; //struct tag->union.u.tag_core.flags
params->u.core.pagesize = 0; //struct tag->union.u.tag_core.pagesize
params->u.core.rootdev = 0; //struct tag->union.u.tag_core.rootdev
params = tag_next(params); //当前地址修改为下一个tag始地址
#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))params地址+tag大小(此处大小为unsigned int 所以一个大小为4字节)=20字节
setup_memory_tags
params->hdr.tag = 0x54410002 //tag标记
params->hdr.size = tag_size(tag_mem32) = 4 //tag参数个数
#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
struct tag_header { u32 size;u32 tag;}; //8字节
struct tag_mem32 { u32 size; u32 start; }; //8字节
>> 2 //除以4等于4
params->u.mem.start = 0x30000000;
params->u.mem.size = 64*1024*1024;
params = tag_next(params); //当前地址修改为下一个tag始地址
setup_commandline_tag(char *cmdline)
params->hdr.tag = 0x54410009 //tag标记
params->hdr.size = (sizeof (struct tag_header) + strlen(cmdline) + 1 + 4) >> 2 = 未知 //tag参数个数
struct tag_header { u32 size;u32 tag;}; //8字节
int strlen(char *str){int i = 0; while(str[i]) { i++;} return i;} //字符串的大小 未知
>> 2 //除以4等于未知
strcpy(params->u.cmdline.cmdline, cmdline); //将命令拷贝进结构体存储
params = tag_next(params); //当前地址修改为下一个tag始地址
params->hdr.size = (sizeof(struct tag_header)+strlen(cmdline)+1+4)>>2; //’+1’表示字符结束标志’\0’, ‘+4’表示除以4转换成整型时向上取整
setup_end_tag
params->hdr.tag = 0x00000000 //tag标记
params->hdr.size = 0 //tag参数个数