1、启动参数标记列表以标记ATAG_CORE开始,以标记ATAG_NONE结束。每个标记由标识被传递的tag_header结构和随后的参数值结构组成。数据结构tag和tag_header定义在Linux内核源码的include/asm/setup.h头文件中。
static struct tag *params;
struct tag {
struct tag_header hdr;//每个tag都有头
union {
struct tag_core core;//tag的类型
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;
};
#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))//得到下一个tag段地址
#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)//获得tag的大小,长度都是以4个字节为单位
/* The list ends with an ATAG_NONE node. */
#define ATAG_NONE 0x00000000 //表单以ATAG_NONE node点结束
struct tag_header { //tag的头定义
u32 size;
u32 tag;
};
2、/* The list must start with an ATAG_CORE node */
#define ATAG_CORE 0x54410001 //表单必须以ATAG_CORE node点开始
struct tag_core { //ATAG_CORE相关定义
u32 flags; /* bit 0 = read-only */
u32 pagesize;
u32 rootdev;
};
static void setup_start_tag (bd_t *bd)//用于设置ATAG_CORE段(起始段)
{
params = (struct tag *) bd->bi_boot_params;//地址
params->hdr.tag = ATAG_CORE;//设置core段tag
params->hdr.size = tag_size (tag_core);//得到tag标记大小,包含tag头和tag结构体数据
params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;
params = tag_next (params);//得到下一个tag段位置的指针,用于接下来的tag标记保存
}
3、/* it is allowed to have multiple ATAG_MEM nodes */
#define ATAG_MEM 0x54410002
struct tag_mem32 {
u32 size;
u32 start; /* physical start address */物理起始地址
};
#ifdef CONFIG_SETUP_MEMORY_TAGS
static void setup_memory_tags (bd_t *bd)//内存段tag的设置
{
int i;
//系统在存在的内存段来设定此参数,存在多个内存段是需要单独设置
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
params->hdr.tag = ATAG_MEM; //内存段类型设置
params->hdr.size = tag_size (tag_mem32);//设置大小
params->u.mem.start = bd->bi_dram[i].start;//起始地址
params->u.mem.size = bd->bi_dram[i].size;//大小
params = tag_next (params);
}
}
#endif /* CONFIG_SETUP_MEMORY_TAGS */
4、/* command line: \0 terminated string */命令行
#define ATAG_CMDLINE 0x54410009
struct tag_cmdline {
char cmdline[1]; /* this is the minimum size */
};
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);
}
5、/* describes where the compressed ramdisk image lives (physical address) */
#define ATAG_INITRD2 0x54420005
struct tag_initrd {
u32 start; /* physical start address */
u32 size; /* size of compressed ramdisk image in bytes */
};
#ifdef CONFIG_INITRD_TAG
static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end)
{
/* an ATAG_INITRD node tells the kernel where the compressed
* ramdisk can be found. ATAG_RDIMG is a better name, actually.
*/
params->hdr.tag = ATAG_INITRD2;
params->hdr.size = tag_size (tag_initrd);
params->u.initrd.start = initrd_start;
params->u.initrd.size = initrd_end - initrd_start;
params = tag_next (params);
}
#endif /* CONFIG_INITRD_TAG */