`
java-mans
  • 浏览: 11339959 次
文章分类
社区版块
存档分类
最新评论

Linux内核中的xx_initcall

 
阅读更多
本文编辑整理自:<wbr style="line-height:25px"><a rel="nofollow" href="http://www.linuxidc.com/Linux/2011-09/43354.htm" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">http://www.linuxidc.com/Linux/2011-09/43354.htm</a> <div style="line-height:25px"> <div style="line-height:25px"><span style="color:#003366; line-height:25px">先看这些宏的定义(定义在文件include/linux/init.h中)</span></div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>pure_initcall(fn) __define_initcall("0",fn,0) </div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>core_initcall(fn) __define_initcall("1",fn,1) </div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>core_initcall_sync(fn) __define_initcall("1s",fn,1s) </div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>postcore_initcall(fn) __define_initcall("2",fn,2) </div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>postcore_initcall_sync(fn) __define_initcall("2s",fn,2s) </div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>arch_initcall(fn) __define_initcall("3",fn,3) </div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>arch_initcall_sync(fn) __define_initcall("3s",fn,3s) </div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>subsys_initcall(fn) __define_initcall("4",fn,4) </div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>subsys_initcall_sync(fn) __define_initcall("4s",fn,4s) </div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>fs_initcall(fn) __define_initcall("5",fn,5) </div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>fs_initcall_sync(fn) __define_initcall("5s",fn,5s) </div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs) </div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span><span style="color:#ff00ff; line-height:25px">device_initcall(fn)</span><span style="color:#ff6600; line-height:25px"></span> <span style="color:#0000ff; line-height:25px"> __define_initcall("6",fn,6) </span> </div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>device_initcall_sync(fn) __define_initcall("6s",fn,6s) </div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>late_initcall(fn) __define_initcall("7",fn,7) </div> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>late_initcall_sync(fn) __define_initcall("7s",fn,7s) </div> <div style="line-height:25px"><span style="color:#003366; line-height:25px">这些宏都用到了__define_initcall(),再看看它的定义(同样定义在文件include/linux/init.h中)</span></div> </div> <div style="line-height:25px"> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span>__define_initcall(level,<span style="color:#ff00ff; line-height:25px">fn</span>,id) \ </div> <div style="line-height:25px"> <span style="color:#ff0000; line-height:25px">static</span><span style="color:#ff9900; line-height:25px">initcall_t</span><span style="color:#99cc00; line-height:25px">__initcall_##fn##id</span><span style="color:#ff6600; line-height:25px">__used</span>\ </div> <div style="line-height:25px"> <span style="color:#ff6600; line-height:25px">__attribute__</span>((<span style="color:#ff6600; line-height:25px">__section__</span>(".<span style="color:#808000; line-height:25px">initcall</span>"<span style="color:#808000; line-height:25px">level</span>"<span style="color:#808000; line-height:25px">.init</span>"))) =<span style="color:#ff00ff; line-height:25px">fn</span> </div> </div> <div style="line-height:25px"> <div style="line-height:25px"> <span style="color:#000080; line-height:25px">这其中</span><span style="color:#ff9900; line-height:25px">initcall_t</span><span style="color:#000080; line-height:25px">是函数指针,原型如下,</span> </div> <div style="line-height:25px"><span style="color:#0000ff; line-height:25px">typedef int (*initcall_t)(void); </span></div> <div style="line-height:25px"> <span style="color:#000080; line-height:25px">而编译器宏</span><span style="color:#ff6600; line-height:25px">__attribute__((__section__()))</span><span style="color:#000080; line-height:25px">则表示把对象放在一个这个由括号中的名称所指代的section中。</span> </div> <div style="line-height:25px"> <span style="color:#000080; line-height:25px"><span style="line-height:25px; color:rgb(0,0,255)">__define_initcall("6",fn,6)</span>则是把fn的地址放到.</span><span style="color:#808000; line-height:22px">initcall</span><span style="color:#ff00ff; line-height:22px">6</span><span style="color:#808000; line-height:22px">.</span><span style="color:#808000; line-height:22px">init</span><span style="color:#000080; line-height:22px">这个selection中</span> </div> <div style="line-height:25px"> <span style="color:#000080; line-height:25px">另外,注意这里</span><span style="line-height:25px; color:rgb(255,0,0)">static</span><span style="line-height:25px; color:rgb(0,0,128)">的作用,只是当前编译单元可见,从全局来看的</span><span style="line-height:25px; color:rgb(153,204,0)">__initcall_##fn##id</span><span style="line-height:25px; color:rgb(0,0,128)">完整名字,是要加当前编译文件名(或称当前编译单位名)作为前缀的</span> </div> <div style="line-height:25px"><span style="color:#000080; line-height:25px">所以__define_initcall的含义是:</span></div> <div style="line-height:25px"> <span style="line-height:25px">1)</span><span style="color:#000080; line-height:25px">声明一个名称为__initcall_##fn的函数指针;</span> </div> <div style="line-height:25px"> <span style="line-height:25px">2)</span><span style="color:#000080; line-height:25px">将这个函数指针初始化为fn;</span> </div> <div style="line-height:25px"> <span style="line-height:25px">3)</span><span style="color:#000080; line-height:25px">编译的时候需要把这个函数指针变量放置到名称为</span><span style="color:#000080; line-height:25px">".</span><span style="color:#808000; line-height:25px">initcall</span><span style="color:#000080; line-height:25px">"</span><span style="color:#808000; line-height:25px">level</span><span style="color:#000080; line-height:25px">"</span><span style="color:#808000; line-height:25px">.init</span><span style="color:#000080; line-height:25px">"的section中</span> </div> </div> <div style="line-height:25px"> <div style="line-height:25px"> <span style="color:#003366; line-height:25px">明确了</span><span style="color:#ff6600; line-height:25px">__define_initcall</span><span style="color:#003366; line-height:25px">的含义,就知道了它其实是分别将这些初始化标号修饰的函数指针放到各自的section中的。</span> </div> <div style="line-height:25px"> <span style="color:#003366; line-height:25px">SECTION“</span><span style="color:#808000; line-height:25px">.initcall</span><span style="color:#003366; line-height:25px">”</span><span style="color:#808000; line-height:25px">level</span><span style="color:#003366; line-height:25px">”.</span><span style="color:#808000; line-height:25px">init</span><span style="color:#003366; line-height:25px">”被放入</span><span style="color:#ff6600; line-height:25px">INITCALLS</span><span style="color:#003366; line-height:25px">(</span><span style="color:#0000ff; line-height:25px">include/asm-generic/vmlinux.lds.h</span><span style="color:#003366; line-height:25px">)</span> </div> </div> <div style="line-height:25px"> <div style="line-height:25px"> <span style="color:#0000ff; line-height:25px">#define</span><span style="color:#ff6600; line-height:25px">INITCALLS</span><span style="color:#3366ff; line-height:25px"> \ </span> </div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcallearly.init) \ </span></div> <div style="line-height:25px"> <span style="color:#3366ff; line-height:25px"> VMLINUX_SYMBOL(</span><span style="color:#99cc00; line-height:25px">__early_initcall_end</span><span style="color:#ff6600; line-height:25px">)</span><span style="color:#3366ff; line-height:25px">=<span style="line-height:25px"></span></span><span style="color:#ff00ff; line-height:25px"><span style="line-height:25px">.</span></span><span style="color:#3366ff; line-height:25px">; \ </span> </div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcall0.init) \ </span></div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcall0s.init) \ </span></div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcall1.init) \ </span></div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcall1s.init) \ </span></div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcall2.init) \ </span></div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcall2s.init) \ </span></div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcall3.init) \ </span></div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcall3s.init) \ </span></div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcall4.init) \ </span></div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcall4s.init) \ </span></div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcall5.init) \ </span></div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcall5s.init) \ </span></div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcallrootfs.init) \ </span></div> <div style="line-height:25px"> <span style="color:#3366ff; line-height:25px"> </span><span style="color:#ff6600; line-height:25px">*(</span><span style="color:#ff00ff; line-height:25px">.initcall6.init</span><span style="color:#ff6600; line-height:25px">)</span><span style="color:#3366ff; line-height:25px"> \ </span> </div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcall6s.init) \ </span></div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcall7.init) \ </span></div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> *(.initcall7s.init) </span></div> <div style="line-height:25px"> <span style="line-height:22px; color:rgb(0,0,255)">VMLINUX_SYMBOL(</span><span style="line-height:22px"><span style="color:#99cc00; line-height:25px">__early_initcall_end</span><span style="color:#0000ff; line-height:25px">)</span></span><span style="line-height:22px; color:rgb(0,0,255)">=<span style="line-height:22px"></span></span><span style="color:#ff6600; line-height:22px"><span style="line-height:22px">.</span></span><span style="line-height:22px; color:rgb(0,0,255)">;</span><span style="color:#3366ff; line-height:22px; color:rgb(0,0,0)"></span><span style="color:#000080; line-height:22px">这里的</span><span style="color:#3366ff; line-height:22px"><span style="line-height:22px"></span></span><span style="color:#ff00ff; line-height:22px"><span style="line-height:22px">.</span></span><span style="color:#000080; line-height:25px">是一个特殊的符号,它是定位器,一个位置指针,指向程序地址空间内的某位置(或某section内的偏移,如果它在SECTIONS命令内的某section描述内),该符号只能在SECTIONS命令内使用。</span> </div> <div style="line-height:25px"> <span style="color:#000080; line-height:25px">这句命令的意思,是对</span><span style="line-height:25px; color:rgb(153,204,0)">__early_initcall_end</span><span style="line-height:25px; color:rgb(0,0,128)">变量赋值为</span><span style="line-height:25px; color:rgb(0,0,128)">当前section内的偏移</span> </div> <div style="line-height:25px"> <span style="color:#ff6600; line-height:25px">*(</span><span style="color:#ff00ff; line-height:25px">.initcall7s.init</span><span style="color:#ff6600; line-height:25px">)</span><span style="color:#000080; line-height:25px">表示的是</span><span style="color:#0000ff; line-height:25px">所有输入文件</span><span style="color:#000080; line-height:25px">中的名为</span><span style="color:#ff00ff; line-height:25px">.initcall7s.init</span><span style="color:#000080; line-height:25px">的</span><span style="color:#ff6600; line-height:25px">SECTIONS</span> </div> <div style="line-height:25px"> <span style="color:#ff6600; line-height:25px">__initcall_start</span><span style="color:#000080; line-height:25px">和</span><span style="color:#ff6600; line-height:25px">__initcall_end</span><span style="color:#000080; line-height:25px">以及</span><span style="color:#ff6600; line-height:25px">INITCALLS</span><span style="color:#000080; line-height:25px">中定义的SECTION都是在arch/xxx/kernel/vmlinux.lds.S中放在</span><span style="color:#0000ff; line-height:25px">.init</span><span style="color:#000080; line-height:25px">段的。</span> </div> <div style="line-height:25px"> <span style="color:#993300; line-height:25px">SECTIONS</span><span style="color:#3366ff; line-height:25px"></span> </div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px">{ </span></div> <div style="line-height:25px"> <span style="color:#3366ff; line-height:25px"> .</span><span style="color:#ff6600; line-height:25px">init</span><span style="color:#3366ff; line-height:25px">: { </span> </div> <div style="line-height:25px"> <span style="color:#3366ff; line-height:25px"> </span><span style="color:#99cc00; line-height:25px">__initcall_start</span><span style="color:#3366ff; line-height:25px">=</span><span style="color:#ff6600; line-height:25px"><span style="line-height:25px">.</span></span><span style="color:#3366ff; line-height:25px">; </span> </div> <div style="line-height:25px"> <span style="color:#3366ff; line-height:25px"> </span><span style="color:#ff00ff; line-height:25px">INITCALLS</span><span style="color:#3366ff; line-height:25px"></span> </div> <div style="line-height:25px"> <span style="color:#3366ff; line-height:25px"> </span><span style="color:#99cc00; line-height:25px">__initcall_end</span><span style="color:#3366ff; line-height:25px">=</span><span style="line-height:25px"><span style="color:#ff6600; line-height:25px">.</span></span><span style="color:#3366ff; line-height:25px">; </span> </div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px"> } </span></div> <div style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span></div> <div style="line-height:25px"> <span style="color:#3366ff; line-height:22px">.</span><span style="color:#ff6600; line-height:22px">init</span><span style="color:#000080; line-height:25px"><span style="line-height:22px">只是用于对</span></span><span style="line-height:25px; color:rgb(153,51,0)">SECTIONS</span><span style="line-height:25px; color:rgb(0,0,128)"><span style="line-height:22px">进行分类</span><span style="line-height:22px"></span></span> </div> <div style="line-height:25px"> <span style="color:#99cc00; line-height:22px">__initcall_start</span><span style="color:#3366ff; line-height:22px">=</span><span style="color:#ff6600; line-height:22px"><span style="line-height:22px">.</span></span><span style="color:#3366ff; line-height:22px">; </span><span style="color:#000080; line-height:25px">和</span><span style="color:#99cc00; line-height:22px">__initcall_end</span><span style="color:#3366ff; line-height:22px">=</span><span style="line-height:22px"><span style="color:#ff6600; line-height:22px">.</span></span><span style="color:#3366ff; line-height:22px">; </span><span style="color:#000080; line-height:25px">表示分别对变量</span><span style="line-height:25px; color:rgb(153,204,0)">__initcall_start</span><span style="color:#000080; line-height:25px">和</span><span style="color:#99cc00; line-height:22px">__initcall_end</span><span style="color:#3366ff; line-height:22px"></span><span style="line-height:22px; color:rgb(0,0,128)">赋值为</span><span style="line-height:22px; color:rgb(0,0,128)">当前section内的偏移。</span> </div> <div style="line-height:25px"> <span style="color:#000080; line-height:25px">而这些</span><span style="color:#0000ff; line-height:25px">SECTION</span><span style="color:#000080; line-height:25px">里的函数在初始化时被顺序执行(init内核线程-&gt;</span><span style="color:#ff9900; line-height:25px">do_basic_setup()</span><span style="color:#000080; line-height:25px">[main.c#778]-&gt;</span><span style="color:#ff9900; line-height:25px">do_initcalls()</span><span style="color:#000080; line-height:25px">)。</span> </div> <div style="line-height:25px"> <span style="color:#000080; line-height:25px">程序(</span><span style="color:#0000ff; line-height:25px">init/main.c</span><span style="color:#000080; line-height:25px">文件</span><span style="color:#ff6600; line-height:25px">do_initcalls()</span><span style="color:#000080; line-height:25px">函数)如下,</span><span style="color:#ff6600; line-height:25px">do_initcalls()</span><span style="color:#000080; line-height:25px">把</span><span style="color:#ff6600; line-height:25px">XX.initcallXX.init</span><span style="color:#000080; line-height:25px">中的函数按顺序都执行一遍。</span> </div> <div style="line-height:25px"> <span style="color:#800000; line-height:25px">for</span><span style="color:#3366ff; line-height:25px">(call =</span><span style="color:#99cc00; line-height:25px">__early_initcall_end</span><span style="color:#3366ff; line-height:25px">; call &lt;</span><span style="color:#ff6600; line-height:25px">_</span><span style="color:#99cc00; line-height:25px">_initcall_end</span><span style="color:#3366ff; line-height:25px">; call++) </span> </div> <div style="line-height:25px"> <span style="color:#3366ff; line-height:25px"> </span><span style="color:#0000ff; line-height:25px">do_one_initcall(*call);</span> </div> </div> <div style="line-height:25px">关于SECTION的更多内容请参考《<strong><a title="阅读全文" target="_blank" href="http://hubingforever.blog.163.com/blog/static/171040579201192472552886/" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">Linux下的lds链接脚本简介</a></strong>》</div> <div><br></div> </wbr>
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics