__setup这条宏在Linux Kernel中使用最多的地方就是定义处理Kernel的启动参数的函数及数据结构,宏定义如下:

 #define __setup(str, fn) \
__setup_param(str, fn, fn, )
#define __setup_param(str, unique_id, fn, early) \
static char __setup_str_##unique_id[] __initdata __aligned() = str; \
static struct obs_kernel_param __setup_##unique_id \
__used __section(.init.setup) \
__attribute__((aligned((sizeof(long))))) \
= { __setup_str_##unique_id, fn, early }

使用Kernel中的例子分析一下这两条定义:

 __setup("root=",root_dev_setup);

这条语句出现在init/do_mounts.c中,其作用是处理Kernel启动时的像root=/dev/mtdblock3之类的参数的。

分解一下这条语句,首先变为:

 __setup_param("root=",root_dev_setup,root_dev_setup,);

继续分解,将得到下面这段代吗:

 static char __setup_str_root_dev_setup_id[] __initdata __aligned() = "root=";
static struct obs_kernel_param __setup_root_dev_setup_id
__used __section(.init.setup)
__attribute__((aligned((sizeof(long)))))
= { __setup_str_root_dev_setup_id, root_dev_setup, };

这段代码定义了两个变量:字符数组变量__setup_str_root_dev_setup_id,其初始化内容为"root=",由于该变量用 __initdata修饰,它将被放入.init.data输入段;另一变量是结构变量__setup_root_dev_setup_id,其类型为 struct obs_kernel_param, 该变理被放入输入段.init.setup中。结构struct struct obs_kernel_param也在该文件中定义如下:

 struct obs_kernel_param {
const char *str;
int (*setup_func)(char *);
int early;
};

变量__setup_root_dev_setup_id的三个成员分别被初始化为:

__setup_str_root_dev_setup_id --> 前面定义的字符数组变量,初始内容为"root="。

root_dev_setup --> 通过宏传过来的处理函数。

0 -->常量0,该成员的作用以后分析。

现在不难想像内核启动时怎么处理启动参数的了:通过__setup宏定义obs_kernel_param结构变量都被放入.init.setup段中,这样一来实际是使.init.setup段变成一张表,Kernel在处理每一个启动参数时,都会来查找这张表,与每一个数据项中的成员str进行比较,如果完全相同,就会调用该数据项的函数指针成员setup_func所指向的函数(该函数是在使用__setup宏定义该变量时传入的函数参数),并将启动参数如root=后面的内容传给该处理函数。

转自:http://blog.csdn.net/fdaopeng/article/details/7895037

【转】Linux Kernel __setup(str, fn)解析的更多相关文章

  1. linux kernel的cmdline参数解析原理分析【转】

    转自:https://blog.csdn.net/skyflying2012/article/details/41142801 版权声明:本文为博主kerneler辛苦原创,未经允许不得转载. htt ...

  2. Linux kernel 之 uart 驱动解析

    uart 是一种非常之常见的总线,比如DEBUG信息输出,小数据量数据传输,485,以及蓝牙的控制,GPS,很多都是通过uart 进行数据传输并进行控制. 在Linux kernel 内部,uart ...

  3. linux kernel的cmdline參数解析原理分析

    利用工作之便,今天研究了kernel下cmdline參数解析过程.记录在此.与大家共享.转载请注明出处.谢谢. Kernel 版本:3.4.55 Kernel启动时会解析cmdline,然后依据这些參 ...

  4. Linux Kernel - Debug Guide (Linux内核调试指南 )

    http://blog.csdn.net/blizmax6/article/details/6747601 linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级 ...

  5. andriod and linux kernel启动流程

    虽然这里的Arm Linux kernel前面加上了Android,但实际上还是和普遍Arm linux kernel启动的过程一样的,这里只是结合一下Android的Makefile,讲一下boot ...

  6. linux kernel 结构体赋值方法{转载}

    原文地址: http://www.chineselinuxuniversity.net/articles/48226.shtml 这几天看Linux的内核源码,突然看到init_pid_ns这个结构体 ...

  7. Linux kernel的中断子系统之(六):ARM中断处理过程

    返回目录:<ARM-Linux中断系统>. 总结:二中断处理经过两种模式:IRQ模式和SVC模式,这两种模式都有自己的stack,同时涉及到异常向量表中的中断向量. 三ARM处理器在感知到 ...

  8. Linux kernel的中断子系统之(七):GIC代码分析

    返回目录:<ARM-Linux中断系统>. 总结: 原文地址:<linux kernel的中断子系统之(七):GIC代码分析> 参考代码:http://elixir.free- ...

  9. Linux Kernel C语言编程范式

    介绍 不同的编程语言具有不同的抽象原语(如下),有的原语抽象层次低,有的原语抽象层次高.其中函数式.DSL是这几年十分热门的编程语言概念. 过程式抽象原语:变量 对象式抽象原语:对象 函数式抽象原语: ...

随机推荐

  1. Stream语法详解

    1. Stream初体验 我们先来看看Java里面是怎么定义Stream的: A sequence of elements supporting sequential and parallel agg ...

  2. sqlldr导入数据

    直接在cmd输入sqlldr即可,不需要先输sqlplus. 参考链接:每次提交多少行很重要:http://www.cnblogs.com/wingsless/archive/2012/08/04/2 ...

  3. Codeforces 626C Block Towers「贪心」「二分」「数学规律」

    题意: 一堆人用方块盖塔,有n个人每次只能加两块方块,有m个人每次只能加三块方块.要求每个人盖的塔的高度都不一样,保证所用方块数最少,求最高的塔的高度. 0<=n+m  0<=n,m< ...

  4. 嵌入式X86运行linux及QtEmbedded+触摸屏(X86PC104+Xlinux+QtE+触摸屏解决办法)

    嵌入式X86运行linux及QtEmbedded+触摸屏(X86PC104+Xlinux+QtE+触摸屏解决办法) QQ:5724308 邮箱:sankye@163.com

  5. window8.1中用户的管理员权限的提升方法

    1.使用命令netplwiz 2.点击确定后出现如下所示的内容,选择待修改的用户 3.然后点击属性,出现如图的内容 在上图中选中管理员左侧的单选按钮便可以了,将当前用户提升为管理员账户.

  6. Java GUI 画点

    import java.awt.EventQueue; public class Paint { private JFrame frame; /** * Launch the application. ...

  7. 转载:Windows Phone 8.1 投影我的屏幕使用教程

    原文地址:http://livesino.net/archives/6851.live 更新了软件的下载地址. Windows Phone 8.1 新功能投影我的屏幕(Project My Scree ...

  8. 区域生长算法(附MATLAB代码实现)

    一.理论概念 区域生长是按照事先定义的生长准则将一个像素或者子区域逐步聚合成一个完整独立的连通区域过程.对于图像感兴趣目标区域R,z为区域R上事先发现的种子点,按照规定的生长准则逐步将与种子点z一定邻 ...

  9. 解决setInterval计时器不准的问题

    在js中如果打算使用setInterval进行倒数,计时等功能,往往是不准确的,因为setInterval的回调函数并不是到时后立即执行,而是等系统计算资源空闲下来后才会执行.而下一次触发时间则是在s ...

  10. MSP430F149学习之路——UART

    代码一: #include <msp430x14x.h> void int_clk() { BCSCTL1 &= ~XT2OFF; BCSCTL2 |= SELM_2 + SELS ...