Linux Command Line 解析

处理模型

Linux kernel 的启动包括很多组件的初始化和相关配置,这些配置参数一般是通过command line 进行配置的。在进行后续分析之前,先来理解一下command line 的处理模型:
要处理的对象是一个字符串,其中包含了各种配置信息,通常各个配置之间通过空格进行分离,每个配置的表达形式是如:param=value1,value2或者很简单就是一个rw
那么kernel 就需要提供对这些参数进行处理的处理函数列表。根据参数的作用以及执行期的先后不同,这些处理函数被定义到不同的段中。针对每一个参数,Kernel 都会到相应的段中查找相应的处理函数,最终进行各个组件的配置。

1 配置格式

常见的配置格式如:
 
console=ttySAC0,115200 root=nfs nfsroot=192.168.1.9:/source/rootfs initrd=0x10800000,0x14af47

2 配置方式

2.1 Bootloader动态配置

bootloader 进行参数配置,command line 将做为atag_list 的一个节点传递到Kernel

2.2 Kernel 静态配置

通过make menuconfig 进行配置:运行后配置boot options->Default kernel command string 。该配置将被静态编译到Kernel 中,通过变量default_command_line 访问。

解析配置

3.1 相关定义

根据执行的先后顺序,可以将处理函数分为三个大类,他们分别存在于下面三个段中(参考top/arch/arm/kernel/vmlinux.lds:
 
__setup_start = .; *(.init.setup) __setup_end = .;
 
__early_begin = .; *(.early_param.init) __early_end = .;
 
__start___param = .; *(__param) __stop___param = .;
 
这三个段内存储的不是参数,而是command line 参数所需要的处理函数。

3.1.1 .early_param.init

.early_param.init ” 所定义的处理相对靠前一些,它所处理的参数例如:initrd=cachepolicy=nocache nowb ecc= vmalloc= mem= ,等等。
这些处理函数是通过__early_param宏来定义的,例如:

static void __init early_initrd(char **p)
{ …… }
__early_param("initrd=", early_initrd);
对于宏__early_param,可以在top/arch/arm/include/asm/Setup.h 中找到如下定义:
 
struct early_params {
    const char *arg;
    void (*fn)(char **p);
};
#define __early_param(name,fn) \
static struct early_params __early_##fn __used \
__attribute__((__section__(".early_param.init"))) = { name, fn }
 
3.1.2 .init.setup
.init.setup ”定义的处理则要靠后一些,它所处理的参数例如:nfsroot= ip= ,等等。
这些处理函数是通过__setup宏来定义的,例如:
 
static int __init nfs_root_setup(char *line)
{ …… }
__setup("nfsroot=", nfs_root_setup);
 
对于宏__setup,可以在top/include/linux/Init.h 中看到:
 
#define __setup_param(str, unique_id, fn, early) \
    static char __setup_str_##unique_id[] __initdata __aligned(1) = str; \
    static struct obs_kernel_param __setup_##unique_id \
           __used __section(.init.setup) \
           __attribute__((aligned((sizeof(long))))) \
           = { __setup_str_##unique_id, fn, early }

#define __setup(str, fn) \
    __setup_param(str, fn, fn, 0)

/* NOTE: fn is as per module_param, not __setup! Emits warning if fn
 * returns non-zero. */
#define early_param(str, fn) \
    __setup_param(str, fn, fn, 1)
 
注意看的话,可以看到还有一个宏early_param ,它与宏__setup的定义相似,只不过最后一个宏参数是1 而不是01 表示需要提前处理的参数。

3.1.3 __param

这个段中保存的是build-in 类型module 的配置参数。该宏直接用来修饰需要的变量。

3.2  解析

3.2.1 相关变量

相关的变量包括:
default_command_line
保存memuconfig 配置的参数,如果bootloader 传入了命令行参数,那么这个新的配置将被更新到该变量中。
boot_command_line
存在于.init.data 段。最初是default_command_line 的拷贝。
command_line
存在于.init.data 段。在parse_cmdline() 中被赋值,数据来源是default_command_line
saved_command_line
用于保存没有处理过的命令行参数,是boot_caommand_line 的拷贝。
static_command_line
command_line 的拷贝。

3.2.2 主要函数

函数名称:parse_cmdline()
操作数据:default_command_line
函数列表: .early_param.init 段(在__early_begin__early_end 之间)。
函数功能: 依据函数列表对default_command_line 中的参数进行处理。
函数名称:parse_early_param()
操作数据:boot_command_line
函数列表: .init.setup 段中(__setup_start__setup_end 之间),主要是通过宏early_param定义的部分。
函数功能: 依据函数列表对boot_command_line 中的参数进行处理。
注意parse_one() 的第四个入参是0 ,而且第五个参数是NULL 。这里没有给出参数队列,不会对boot_command_line 的每个参数在参数队列中进行对比查找,而是直接在do_early_param() 中进行条件判断,如果满足下面的条件,那么对该参数进行对应的操作:
if ((p->early && strcmp(param, p->str) == 0) ||
                  (strcmp(param, "console") == 0 &&
                   strcmp(p->str, "earlycon") == 0)
              )
函数名称:parse_args()
操作数据:static_command_line
函数列表: __param 段(__start___param__stop___param 之间)。
函数功能: 该操作将依据函数列表,对static_command_line 中的参数进行相应的操作。这个操作在parse_one() 的第一部分代码完成:
for (i = 0; i < num_params; i++) {
          if (parameq(param, params[i].name)) {
                 DEBUGP("They are equal! Calling %p\n",
                        params[i].set);
                 return params[i].set(val, &params[i]);
          }
   }
接下来对于不被这个列表所支持的参数,将在unknown_bootoption() 中进行处理。在unknown_bootoption() 中主要是obsolete_checksetup() 的操作。
函数名称:obsolete_checksetup()
操作数据:static_command_line
函数列表: .init.setup 段中(__setup_start__setup_end 之间),主要是通过宏__setup定义的部分。
函数功能: 该操作将依据函数列表,对static_command_line 中的参数进行相应的操作。如果是在parse_early_param() 中已经处理的操作,那么这里不再处理;如果是查找到的条目中没有操作函数,那么这表示是过时的数据定义(有些早期的代码,没有定义这个函数);如果不是以上两种情形,那么利用找到的函数对参数进行处理。

3.2.3图示


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

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

相关文章

COSCon'21 参会指南 你想要的这里都有

“ 点击蓝字 / 关注我们 ”| 作者&#xff1a;袁睿斌| 编辑&#xff1a;Corrie| 设计&#xff1a;宋传琪开源社寄语2021年的10月&#xff0c;第六届中国开源年会&#xff08;COSCon21&#xff09;再一次如期召开了。今年的开源寄语&#xff0c;我们能够想到是三个关键词&#x…

为什么说减速带是脑残的设计?

全世界只有3.14 % 的人关注了爆炸吧知识开车的谁没有压过减速带啊&#xff0c;当你以较高车速通过它时&#xff0c;剧烈振动会带给你强烈的刺激&#xff0c;有时候胃都感觉不舒服&#xff0c;加强你的不安全疑虑&#xff0c;促使你减速行驶。简单来说&#xff0c;就是“顶你起来…

C++语言基本概念(5)

面向对象编程与面向过程的一个根本区别&#xff0c;就是面向对象编程在虚拟的计算机世界构造出了形形的对象&#xff0c;很显然这些对象之间必然要发生关系&#xff0c;如何区别描述这些关系也是面向对象这门课所要研究的问题。我们都知道其中有非常多的概念&#xff0c;有些概…

创建工程师文化的3个步骤 | IDCF

原文地址&#xff1a;https://dzone.com/articles/3-steps-to-create-an-engineering-culture作者博文地址&#xff1a;https://start2grow.net/?screateagreatengineeringculture作者&#xff1a;Linda Bovaird译者&#xff1a;冬哥在之前的文章&#xff08;https://start2gr…

UIButton的竖排图片和文本

UIButton的竖排图片和文本UIButton的竖排图片和文本第一想法:实现思路第二种方法UIContentHorizontalAlignment/UIControlContentVerticalAlignment完整代码片段:参考资料:更新UIButton的竖排图片和文本UIButton的竖排的话,如果不知道方法,就会走很多弯路了第一想法:实现思路橙…

他是绝世天才,却只开了半辈子的挂!死后惨遭封号200年,这就是和牛顿抬杠的下场.........

全世界只有3.14 % 的人关注了爆炸吧知识既生胡何生顿1703年3月3日&#xff0c;68岁的“英国达芬奇”躺在病床上&#xff0c;奄奄一息。临终前&#xff0c;他仍在惦记一个事儿&#xff1a;他希望&#xff0c;当年砸牛顿头上的&#xff0c;是个榴莲。因为是牛顿&#xff0c;让终身…

使用LightBDD轻松实现行为驱动开发

前言上次&#xff0c;我们介绍了行为驱动开发&#xff08;BDD&#xff09;它的优点是可以使用纯文本编写测试用例&#xff0c;不需要编程经验。如果测试用例也全部是程序员写的情况&#xff0c;这种方式反而存在障碍&#xff0c;feature使用与编写代码的语言完全不同的语言来编…

Android百度地图开发01之初体验

做关于位置或者定位的app的时候免不了使用地图功能&#xff0c;本人最近由于项目的需求需要使用百度地图的一些功能&#xff0c;所以这几天研究了一下&#xff0c;现写一下blog记录一下&#xff0c;欢迎大家评论指正&#xff01; 一、申请AK&#xff08;API Key&#xff09; 要…

会按摩的充气颈枕,只占行李箱一个角,却能让你的脖子爽到爆

▲ 点击查看出差、旅游、探亲&#xff0c;舟车劳顿的路上&#xff0c;想要休息实在太难。临近国庆&#xff0c;有多少人准备外出旅游、回家或者出差的&#xff1f;然而在舟车劳顿的路上&#xff0c;想要休息一下&#xff0c;不要太难。睡到一半撞到车窗痛醒&#xff0c;不小心歪…

Envoy实现.NET架构的网关(一)静态配置与文件动态配置

什么是Gateway在微服务体系结构中&#xff0c;如果每个微服务通常都会公开一组精细终结点&#xff0c;这种情况可能会有以下问题如果没有 API 网关模式&#xff0c;客户端应用将与内部微服务相耦合。在客户端应用中&#xff0c;单个页面/屏幕可能需要多次调用多个服务。 如果没…

corosync和pacemaker实现httpd和mysql双集群

一、环境介绍&#xff1a;三台均为双网卡&#xff1a;openstack-control.example.com openstack-control eth0:172.16.171.100eth1:10.1.1.100 openstack-nova.example.com openstack-novaeth0:172.16.171.110eth1:10.1.1.110openstack-neutron.example.com openstack-neutrone…

25岁男生要有多少存款才能让女友满意?

1 男女观念差异这么大的吗&#xff1f;▼2 演绎人生从落魄到适应再到悠哉的三个阶段▼3 牌子大&#xff0c;了不起咯~▼4 这鬼才文案用在这里屈才了▼5 狗子&#xff1a;你就说&#xff0c;我演的哪里不像&#xff1f;▼6 7个月一点没变我觉得已经蛮厉害得了▼7 不小心跟…

心得9--jsp设计模版

1.常用的面向对象设计模式有4种&#xff1a; Factory模式、Singleton模式、Facade模式和MVC架构模式。 SUN公司推出JSP技术后&#xff0c;同时也推荐了两种web应用程序的开发模式&#xff0c;一种是JSPJavaBean模式&#xff0c;一种是ServletJSPJavaBean(MVC)模式。 JSP设计模…

C# 泛型的使用

01—泛型概述泛型是用于处理算法、数据结构的一种编程方法。泛型的目标是采用广泛适用和可交互性的形式来表示算法和数据结构&#xff0c;以使它们能够直接用于软件构造。泛型类、结构、接口、委托和方法可以根据它们存储和操作的数据的类型来进行参数化。泛型能在编译时提供强…

在数学世界,都有这些美妙的数学公式是你不认识的......

全世界只有3.14 % 的人关注了爆炸吧知识什么是数学&#xff1f;华罗庚说&#xff1a;宇宙之大&#xff0c;粒子之微&#xff0c;火箭之速&#xff0c;化工之巧&#xff0c;地球之变&#xff0c;生物之谜&#xff0c;日用之繁&#xff0c;无处不用数学......回首往昔&#xff0c…

Android MediaScanner:(一)MediaScanner总体架构

Android MediaScanner&#xff1a;&#xff08;一&#xff09;MediaScanner总体架构 分类&#xff1a; Android android.multimedia2012-05-19 18:29 5050人阅读 评论(5) 收藏 举报androidservice数据库工作interfaceinsert田海立csdn 2012-05-19 本文是笔者的分析归纳&#xf…

报表系统FineReport通过权限控制数据访问方案

2019独角兽企业重金招聘Python工程师标准>>> 问题&#xff1a;实际应用环境中&#xff0c;不同角色的人可能对数据具有不同的访问权限&#xff0c;通过直接在SQL语句中筛选出需要的数据制作模板可以解决该需求&#xff0c;但对于角色较多的情况&#xff0c;就需要制…

SkyWalking配上告警更优秀

前言对于监控系统来说&#xff0c;不可能让人一直盯着监控看板&#xff0c;而更多的是以自动提醒的方式&#xff0c;比如邮件、短信或微信推送等&#xff0c;当达到或超出预设的告警指标时&#xff0c;就自动发送消息提醒&#xff0c;下面就来说说如何配置SkyWalking的告警。正…

神抓拍!2020搞笑野生动物摄影大赛,哈哈哈哈哈笑到头掉

全世界只有3.14 % 的人关注了爆炸吧知识图片来自CWPAs 2020小动物们到底能有多好玩让我们来看看今年的搞笑野生动物摄影大赛吧保准叫你从头笑到尾&#xff08;以下是入围作品&#xff09;“飚自行车的”猴看起来像个酷猴▲摄影&#xff1a;Yevhen Samuchenko真情实感演绎“我太…

绝不翻车珍珠奶茶做法

1 如何在家自制珍珠奶茶▼2 儿子&#xff0c;妈妈给你烤小饼干哦▼3 放假太久了连自己哪个班都忘了▼4 想问下&#xff0c;鸟是在哪都能起窝吗&#xff1f;▼5 不到万不得已&#xff0c;绝不去做▼6 这个店名太童年阴影了▼7 小鸡做错了什么&#xff1f;▼你点的每个赞&…