快速业务通道

《Linux内核修炼之道》精华分享与讨论(7)——分析内核源码如何入手?(下)

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-04-23
us_type);
914 bus_register_failed:
915 ksuspend_usb_cleanup();
916 out:
917 return retval;
918 }
(1)__init标记. 关于usb_init,第一个问题是,第865行的__init标记具有什么意义? 写过驱动的应该不会陌生,它对内核来说就是一种暗示,表明这个函数仅在初始化期间使用,在模块被装载之后,它占用的资源就会释放掉用作它处.它的暗示你懂,可你的暗示,她却不懂或者懂装不懂,多么让人感伤.它在自己短暂的一生中一直从事繁重的工作,吃的是草吐出的是牛奶,留下的是整个USB子系统的繁荣. 受这种精神所感染,我觉得有必要为它说的更多些.__init的定义在include/linux/init.h文件里 43 #define __init __attribute__ ((__section__ (".init.text"))) 好像这里引出了更多的疑问,__attribute__是什么?Linux内核代码使用了大量的GNU C扩展,以至于GNU C成为能够编译内核的唯一编译器,GNU C的这些扩展对代码优化、目标代码布局、安全检查等方面也提供了很强的支持.而__attribute__就是这些扩展中的一个,它主要被用来声明一些特殊的属性,这些属性主要被用来指示编译器进行特定方面的优化和更仔细的代码检查.GNU C支持十几个属性,section是其中的一个,我们查看GCC的手册可以看到下面的描述 ‘section ("section-name")''
Normally, the compiler places the code it generates in the `text''
section. Sometimes, however, you need additional sections, or you
need certain particular functions to appear in special sections.
The `section'' attribute specifies that a function lives in a
particular section. For example, the declaration:      extern void foobar (void) __attribute__ ((section ("bar")));    puts the function ‘foobar'' in the ‘bar'' section.    Some file formats do not support arbitrary sections so the
‘section'' attribute is not available on all platforms. If you
need to map the entire contents of a module to a particular
section, consider using the facilities of the linker instead.
通常编译器将函数放在.text节,变量放在.data或.bss节,使用section属性,可以让编译器将函数或变量放在指定的节中.那么前面对__init的定义便表示将它修饰的代码放在.init.text节.连接器可以把相同节的代码或数据安排在一起,比如__init修饰的所有代码都会被放在.init.text节里,初始化结束后就可以释放这部分内存. 问题可以到此为止,也可以更深入,即内核又是如何调用到这些__init修饰的初始化函数?要回答这个问题,还需要回顾一下subsys_initcall宏,它也在include/linux/init.h里定义 125 #define subsys_initcall(fn) __define_initcall("4",fn,4)
这里又出现了一个宏__define_initcall,它用于将指定的函数指针fn放到initcall.init节里 而对于具体的subsys_initcall宏,则是把fn放到.initcall.init的子节.initcall4.init里.要弄清楚.initcall.init、.init.text和.initcall4.init这样的东东,我们还需要了解一点内核可执行文件相关的概念. 内核可执行文件由许多链接在一起的对象文件组成.对象文件有许多节,如文本、数据、init数据、bass等等.这些对象文件都是由一个称为链接器脚本的文件链接并装入的.这个链接器脚本的功能是将输入对象文件的各节映射到输出文件中;换句话说,它将所有输入对象文件都链接到单一的可执行文件中,将该可执行文件的各节装入到指定地址处. vmlinux.lds是存在于arch/<target>/ 目录中的内核链接器脚本,它负责链接内核的各个

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号