一:tag是什么?
tag 是一个数据结构:stract tag 这种数据格式在uboot和kernel是一样的,也就是说uboot在启动的时候将需要传给kernel的参数放在了DDR的某个地址处,而存放格式就是tag格式,然后kernel就会到这个地址去读取这些参数,读取方式也是按tag格式去读取的。
简单来说tag就像是一个数组一样,是一块连续的内存,里面存放了uboot需要传递给kernel的参数信息,我们通过定义一个指针params(static struct tag *params;),先使其指向tag的存放地址(30000100,uboot也就是说在30000100的地方存放了一条信息,告诉kernel去0x54410001这个地方去读取tag(也就是uboot传递给kernel的参数))
二:分析
(1)CONFIG_SETUP_MEMORY_TAGS:tag_mem,传参内容是内存的配置信息
(2)CONFIG_CMDLINE_TAG :tag_cmdline,传参内容是启动命令参数,也就是uboot环境变量bootargs
(3)CONFIG_INITRD_TAG
(4)CONFIG_MTDPARTITION:传参内容是iNand/SD卡的分区表
(5)起始tag是ATAG_CORE 结束tag是ATAG_NONE,其他的ATAG_xxx都是有效信息,传递着某些参数
(params = (struct tag *) bd->bi_boot_params;这里的bi_boot_params为30000100),然后让params(远跳转)指向tag的开头(params->hdr.tag = ATAG_CORE;这里的ATAG_CORE为0x54410001),让其继续指向这个tag中的其他内容,并进行赋值,在这个tag的最后通过params = tag_next (params);将params指向下一个tag,所以当我们操作一个tag时不需要考虑这个时候内存(也就是params指向什么地方)
三:内核如何拿到这些tag信息??
uboot最终通过调用theKernel (0, machid, bd->bi_boot_params);函数来执行linux内核的,uboot调用这个函数(其实就是linux内核)时传递了三个参数。这三个参数就是uboot直接传递给linux内核,这3个参数是通过寄存器来实现的传参的,第一个参数就放在r0中,第二个参数(机器码)放在r1中,第三个参数放在r2中(第三个参数传递的就是tag的首地址这里是30000100)