Linux内核参数传递Tag
来源:互联网 发布:盘石软件怎么 编辑:程序博客网 时间:2024/05/21 15:40
+-----------+
tag_header
+-----------+
tag_xxx
+-----------+
其中tag_header为tag头,表明tag_xxx的类型和大小,之所以要标识tag_xxx的类型是因为不同的tag需要不同的处理函数(下文讲tagtable的时候会分析到)。tag_header的结构为
struct tag_header
{
int size;
int tag;
}
size表示tag的结构大小,tag为表示tag类型的常量。这个静态的链表必须以tag_header.tag = ATAG_CORE开始,并以tag_header.tag = ATAG_NONE结束。由于不同的tag所使用的格式可能不尽相同,所以内核又定义了一个结构tagtable来把tag和相应的操作函数关联起来
struct tagtable
{
u32 tag;
int (*parse)(conststruct tag*);
}
#define __tag __attribute_used__ __attribute__((__section__(“.taglist.init”)))
#define __tagble(tag,fn)static struct tagtable __tagtable_##fn __tag= {tag, fn}
以处理命令行参数为例:
static int __init parse_tag_cmdline(conststruct tag* tag)
{
strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
}
__tagtable(ATAG_CMDLINE, parse_tag_cmdline)
可以看到parse_tag_cmdline将命令行参数拷贝到default_command_line里,__tagtable将ATAG_CMDLINE和parse_tag_cmdline挂钩。
以上已经分析了内核和tag相关的两个重要结构。现在分析具体的实现。内核中定义了一些默认的tags
static struct init_tags
{
struct tag_header hdr1;
struct tag_core core;
struct tag_header hdr2;
struct tag_mem32 mem;
struct tag_header hdr3;
}init_tags __initdata = {
{ tag_size(tag_core), ATAG_CORE},
{ 1, PAGE_SIZE, 0xff},
{ tag_size(tag_mem32), ATAG_MEM},
{ MEM_SIZE, PHYS_OFFSET},
{ 0, ATAG_NONE}
}
上述结构中一个tag_header和tag_xxx形成了tag的完整描述,tag_size返回tag_head和tag_xxx的总大小,在tag_size中我们要注意的是u32*指针加1地址值实际上地址加了4
#define tag_next(t) ((struct tag*)((u32*)(t)+(t)->hdr.size))
#define tag_size(type) ((sizeof(struct tag_header)+sizeof(struct type)) >> 2
tag_size实际上计算的是(tag_head+tag_xxx)/4。经过进一步的分析还发现每个tag在内存中的大小并不是相同的,这一点可以从tag_next看出,tag_next只是将指针移到了下一个tag的tag_header处,这种内存布局更加紧凑。对tag的处理代码在arch/arm/setup.c setup_arch里面。以下是一部分的关键代码
struct tag*tags = (struct tag*)&init_tags;//tags指向默认的tag链表
……
mdesc = setup_machine(machine_arch_type);// mdesc包含启动参数在内存中的地址
if( mdesc->boot_params)
tags = phys_to_vert(mdesc->boot_params);// bootloader有传递启动参数到内核
if( tags->hdr.tag!= ATAG_CORE)
convert_to_tag_list(tags);//如果是旧的启动参数结构,将其转成新的tag链表的形式
if( tags->hdr.tags!= ATAG_CORE)
tags = (struct tag*)&init_tags;//转换失败,使用内置的启动参数
if( tags->hdr.tag== ATAG_CORE)
{
if( meminfo.nr_banks!= 0 )
squash_mem_tags(tags);//如果在meminfo中有配置内存tag则跳过对内存tag的处理
parse_tags(tags);
}
*注:2.6.18内核smdk2410的meminfo没有设置nr_banks,所以必须在内核的启动参数里面传递mem=”memory size”@”memory base address”,否则系统识别内存错误,这点从系统的启动信息就可以看出来,而且在加载initrd的时候也会遇到内存溢出的错误
static void __init parse_tags(conststruct tag* t)
{
for(; t->hdr.size; t=tag_next(t))
{
if(!parse_tag(t))
printk(…);
}
}
parse_tags遍历tag链表调用parse_tag对tag进行处理。parse_tags在tabtable中寻找tag的处理函数(通过tag_header结构中的tag)。
- Linux内核参数传递Tag
- Linux内核参数传递Tag
- 为linux传递内核参数
- Linux内核模块传递参数
- linux 内核模块参数传递
- Linux内核启动参数传递
- 关于Linux内核态传递参数
- BootLoader与Linux内核的参数传递
- Linux内核启动参数的传递
- Linux内核启动参数的传递
- BootLoader与Linux内核的参数传递
- BootLoader与Linux内核的参数传递
- BootLoader与Linux内核的参数传递
- BootLoader与Linux内核的参数传递
- linux 给内核模块传递参数
- Linux 内核 给模块传递参数
- BootLoader与Linux内核的参数传递
- BootLoader与Linux内核的参数传递
- FreeCAD Dialog ---> python
- VC中使用wxWidgets 出现的编译错误 error C2059: syntax error : 'constant' 解决
- Documentation\stat.txt
- windows登陆密码的验证
- 三招屏蔽微信公众账号死亡陷阱
- Linux内核参数传递Tag
- C# 中的委托和事件
- java打包doc,中文乱码
- ftp客户端命令详解及实例
- 查询A表中的数据不在B表中
- SQL语句优化经典小技巧
- 4.23 st_dev和st_rdev成员-文件设备号
- 软件版本信息
- .Net 代码安全保护产品DNGuard HVM介绍