第十六章核心源码的物理布局-Read.DOCVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第十六章核心源码的物理布局-Read

核心源码的物理布局到目前为止,我们从写设备驱动程序的角度讨论了Linux核心。但一旦你开始研究核心,你会发现你想“全面理解它”。事实上,你可能整天在浏览源码,搜索源码树,目的只是想搞清楚核心不同部分之间的关系。这种“沉重的搜索”是我在家里专门设一台计算机的任务之一,并且这是从源码中获取信息的一个有效的办法。然而,在坐在你喜欢的shell提示符之前若能得到一些知识基础将会很有帮助。本章基于版本2.0.x,对Linux核心源文件提供一个快速的概览。文件布局在版本之间的改变并不大,尽管我不能保证将来会不会变。因此下面的信息对浏览核心的其它版本应该也很有用,即使它不是权威。在本章中,每个给出的路径名都是相对于源码的根(通常是/usr/src/linux),而没有目录部分的文件名一般假设它居于“当前”目录即正在讨论的哪个。头文件(当以角括弧的形式命名时和)是相对于源码树的include目录给出的。我不想介绍Documantation目录,因为它的作用应该很清楚。引导核心看一个程序的一般方法是从执行开始的地方着手。至于Linux,很难说执行是从那里开始的它取决于你是如何定义“开始”的。体系结构相关的开始点是start_kernel,在init/main.c中。这个函数是从体系结构特定的代码中被调用的,但它并不返回到那里。它掌管着转动轮子,因此可以被认为是“所有函数的母亲”,计算机生命的第一次呼吸。在start_kernel之前是一片混沌。在start_kernel被调用时,处理器已经被初始化了,保护模式(如果有)也被激活了,处理器在最高的优先级执行(通常被称为“管理员模式”),中断被关闭了。start_kernel函数负责初始化所有的核心数据结构。这个通过调用外部函数来执行子任务,因为每个设置函数都在合适的核心子系统定义。start_kernel也调用parse_options(也在init/main.c文件中)来对从用户或引导系统的程序处传来的命令行进行解码。命令行(与memory_start,memory_end一道)用setup_arch从计算机内存中获取。setup_arch,如它的名字提示,是体系结构特定的代码。init/main.c中的代码主要由#ifdefs组成。这是因为初始化是按步发生的,很多步可能被运行或跳过,这依赖于核心的编译时配置。命令行的解释也严重地依赖于条件,因为很多参数只有在被编译的核心含有特定的驱动程序时才有意义。由start_kernel调用的初始化函数有两种风格。一些函数没有参数,返回void;而另一些需要两个unsigned long参数,并返回另一个unsigned long值。其参数是memory_start和 memory_end的当前值,即未分配的物理内存的边界。返回值是新的memory_start值(如你所已知的,核心用unsigned long表达内存地址)。这个技术允许子系统在物理内存的开始处分配一个持续的(和连续的)内存区域,如在第七章“把握内存”中“playing dirty”一节中提到的。这种技术的最大的缺点是它只能在引导时使用,对那些需要用于DMA的巨大内存区段的模块并不可用。初始化完成后,start_kernel打印出旗帜字符串,包括Linux版本号和编译时间,接着通过调用kernel_thread派生出(fork)一个init进程。start_kernel函数接着以任务0(所谓的“空闲”任务)的形式继续,并调用cpu_idle,它是一个调用idle的无限循环。在这一点,SMP(对称多处理器)的工作方式略有不同,但我不打算讲述这个不同。idle函数的真正行为是体系结构相关的,对源码的简单搜索可以把你带到可以研究其功能的位置。引导之前在前一节,我把start_kernel看作第一个核心函数。不过,你可能对这点之前发生的事情感兴趣。在start_kernel之前运行的代码是低级的,包含汇编码,因此你可能对其细节不感兴趣。不过,我将介绍一下固件(在PC世界称为BIOS)将控制交给Linux后计算机中发生了什么。如果你对钻研低级代码没有兴趣,你可以直接跳到“Init进程”。下面提供了关于Intel,Alpha,Sparc引导代码的一些提示,因为这是我能访问的仅有的系统。(如果有人肯捐一些硬件,我将在下一版覆盖更多的平台)。设置X86处理器个人计算机是基于一个老的设计,后向兼容性一直有很高的优先级。因此,PC固件还是以一种老方式引导操作系统。一旦引导设备被选择,它的第一个扇区被加载到内存的0x7C00处,然后让出控制。刚加电的处理器处于实模式(也就是说,它象8086)并只能寻址物理内存的前640KB。其中一部分已经被固件管理的数据表格占用了。由于核心要比这个大,Linux的开发者必须找

文档评论(0)

zhaoxiaoj + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档