Linux内核参数传递Tag

在2.4(具体哪个版本记不清了)以后的Linux内核中引入了一种新的向内核传递参数的方法tag标记。内核参数通过一个静态的tag链表在启动的时候传递到内核。每个tag的结构为

                   +-----------+

                    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)(const struct tag*);
}

 

 

其中tag为标识入ATAG_NONE,ATAG_CORE等。parse为处理函数。Linux内核将tagtable也组成了一个静态的链表放入.taglist.init节中,这是通过__tagtable宏来实现的

#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(const struct 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内核smdk2410meminfo没有设置nr_banks,所以必须在内核的启动参数里面传递mem=”memory size”@”memory base address”,否则系统识别内存错误,这点从系统的启动信息就可以看出来,而且在加载initrd的时候也会遇到内存溢出的错误

 

 

static void __init parse_tags(const struct 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)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/434543.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ns学习资料

(一). NS常用基本网站   1. Maillist个人觉得是寻求问题答案最好的地方。   http://mailman.isi.edu/pipermail/ns-users/   2. 柯老师的网站,包含很多非常实用资源:安装,trace文件分析,源代码分析&a…

Oracle备份standby,Oracle 11g 利用泠备份恢复standby库

Oracle 11g 利用泠备份恢复standby库1 开始在备库上进行泠备份先查好控制文件、redo、undo文件、数据文件的路径1.1 先关闭主库的归档日志传输SQL> ALTER system SETlog_archive_dest_state_2 DEFER;System altered.SQL>1.2 先关闭standby库SQL> shutdown immediate;D…

Linux内核参数的介绍

sysctl -a 可以列出当前所有的Linux内核参数。 /proc/sys/目录下的东西,对应着sysctl -a列出来的。 man 5 proc syscall 在 /arch/i386/kernel/entry.S里面列出来,这个看起来可能更方便

matlab单位阶跃响应与单位脉冲响应,python 已知响应函数求单位阶跃响应或脉冲响应...

最近学习自动控制原理,关于控制系统的一些,老师用布置了一些作业说要用matlab画,我试试python首先介绍一下所使用的库:control matplotlib sympy1.control库:用来计算脉冲响应与阶跃响应Paste_Image.png2.sympy&#x…

SQL SERVER 的SQL语句优化方式小结

SQL SERVER 的SQL语句优化方式小结详细出处参考:http://www.jb51.net/article/19547.htm 1、SQL SERVER 2005的性能工具中有SQL Server Profiler和数据库引擎优化顾问,极好的东东,必须熟练使用。 2、查询SQL语句时打开“显示估计的执行计划”…

u-boot向linux内核传递启动参数

U-BOOT 在启动内核时,会向内核传递一些参数.而这些参数是通过 structtag来传递的。 U-boot 把要传递给 kernel 的东西保存在 struct tag数据结构中,启动 kernel 时,把这个结构体的物理地址传给 kernel;Linux kernel通过这个地址分析出u-boot传…

$_server['php_self'] 漏洞,Discuz! $_SERVER['PHP_SELF'] XSS Vulnerability

在common.inc.php文件的69行:$PHP_SELF $_SERVER[PHP_SELF] ? $_SERVER[PHP_SELF] : $_SERVER[SCRIPT_NAME];$SCRIPT_FILENAME str_replace(\\\\, /, (isset($_SERVER[PATH_TRANSLATED]) ? $_SERVER[PATH_TRANSLATED] : $_SERVER[SCRIPT_FILENAME]));$boardurl …

【前端破解系列之一】一分钟教你破解下载虾米音乐

虾米音乐网站上有很多高品质的音乐和精心组织的精选集,但普通用户只能试听,不能下载,下载的话需要使用“米”,这个“米”除了极少数的新手任务可以获得之外,基本上都要靠付费来购买,很多人没有网银或者没有…

网络编程常用接口的内核实现----sys_listen()

listen()函数仅在TCP服务器端调用,它做两个事情:将套接字转换到LISTEN状态和设置套接上的最大连接队列。listen()对应的内核实现为sys_listen(),下面开始对其实现作具体的分析。 一、sys_listen()函数 sys_listen()的源码实现及分析如下所示…

linux查看启动配置文件内容,Linux开机启动项的查看和设置方法总结

一、查看开机自启项1.Centos7自启项查看方式从Centos6的chkconfig改为:systemctl list-unit-files2.用grep过滤查看,比如:查看启动项:systemctl list-unit-files | grep enable查看sshd服务自启动情况:systemctl list-…

sql SET DATEFORMAT对日期处理的影响

--1./*--说明SET DATEFORMAT设置对使用CONVERT把字符型日期转换为日期的处理也具有影响但不影响明确指定了style的CONVERT处理。--*/--示例 ,在下面的示例中,第一个CONVERT转换未指定style,转换的结果受SET DATAFORMAT的影响,第二…

linux怎么设置tomcat自动启动,linux添加tomcat服务并设置开机启动

一,脚本文件,编辑好后放在/etc/rc.d/init.d/下面#!/bin/sh#chkconfig: 2345 10 90# description: Starts and Stops the Tomcat daemon.#by jj###############################################Startup script for Tomcat on Linux#filename tomcat.sh#M…

Linux操作系统内核启动参数详细解析

Linux内核在启动的时候,能接收某些命令行选项或启动时参数。当内核不能识别某些硬件进而不能设置硬件参数或者为了避免内核更改某些参数的值,可以通过这种方式手动将这些参数传递给内核。 如果不使用启动管理器,比如直接从BIOS或者把内核文…

XP Embedded:不同的用户使用不同的外壳程序

摘要: 能够使应用程序成为外壳程序是 Windows XP Embedded 的关键功能之一。设备可以在自定义外壳程序而不是 Explorer 外壳程序中启动,这提供了两个好处。第一个好处是系统能够更快地启动。Explorer 外壳程序需要花费大量的时间来加载所有支持库和文件…

linux系统中 库分为静态库和,Linux系统中“动态库”和“静态库”那点事儿-【经典好文】...

今天我们主要来说说Linux系统下基于动态库(.so)和静态(.a)的程序那些猫腻。在这之前,我们需要了解一下源代码到可执行程序之间到底发生了什么神奇而美妙的事情。在linux操作系统中,普遍使用ELF格式作为可执行程序或者程序生成过程中的中间格式。ELF(Exec…

u-boot环境变量设置

这是我uboot的环境变量设置,在该设置下可以运行initram内核(从内存下载到nandflash再运行),但是运行nfs根文件系统的时候一直出错,各种错误。查看了很多资料后猜想应该是uboot传递给linux内核的参数有问题,…

RHEL6 下Cfengine V3 安装测试1

Cfengine 是一种 GNU 开源配置管理框架,用于计算机系统自动化。此框架是轻量的,可针对几乎所有平台构建。它能运行在所有常见平台上,其中包括 AIX、Linux、UNIX、Apple 和 Windows。 cf-promises 承诺的检验者和编译者,在试图执行…

linux下grpc安装编译,linux下安装grpc插件 (c++和go语言)

在debian/ubuntu系统下,需要做如下准备操作:$ [sudo] apt-getinstallbuild-essential autoconf libtoolpkg-config如果你想要从源码编译并且运行测试,同时运行下面的安装:$ [sudo] apt-getinstalllibgflags-dev libgtest-dev$ [su…

SIP资料汇总

SIP协议 SIP协议过程概念及分析 SIP入门开发之路(含SIP开发需要学习的资源及网址) SIP揭密(中文版) 使用Java的SIP Servlet进行SIP开发 Asterisk: Asterisk安装及测试 Asterisk十问十答 Asterisk入门教程 Asterisk介绍-Asterisk RealTime SIP asterisk配…

Nand Flash Yaffs系统大量写入数据失败问题的解决方法。

一个朋友的问题,我们共同分析后搞定。其实以前也遇到过同样问题,时间长了,没总结。 事发:在Nand Flash上使用2.6.14的linux kernel,三星2440的板子,连续写入文件,到一定大小限制就删除&#xff…