Chapter2.GettingStartedwiththeKernelInthischapter,weintroducesomeoftheBasicsoftheLinuxkernel:wheretogetitssource,howtocompileit,andhowtoinstallthenewkernel.Wethengooversomekernelassumptions,differencesbetweenthekernelanduser-spaceprograms,andcommonmethodsusedinthekernel.Thekernelhassomeintriguingdifferencesoverotherbeasts,butcertainlynothingthatcannotbetamed.Let'stackleit.第二章从内核出发在这一章,我们介绍Linux内核一些基本常识:从何处获取源码,如何编译它,又如何安装新内核。那么,让我们考察一下内核的一些状态、内核程序与用户空间程序的差异,以及内核所用一般函数的特点。内核像性格怪异的猛兽,但并非不可驯服。让我们来驾驭它。ObtainingtheKernelSourceThecurrentLinuxsourcecodeisalwaysavailableinbothacompletetarballandanincrementalpatchfromtheofficialhomeoftheLinuxkernel,获取内核源码在Linux内核官方网站,可以随时获取当前版本的Linux源代码,可以是完整的压缩形式,也可以是增量补丁形式。除非特殊情况下需要Linux源码的旧版本,一般都希望拥有最新的代码。kernel.org是源码的库存之处,那些领导潮流的内核开发者所发布的增量补丁也放在这里。InstallingtheKernelSourceThekerneltarballisdistributedinbothGNUzip(gzip)andbzip2format.Bzip2isthedefaultandpreferredformat,asitgenerallycompressesquiteabitbetterthangzip.TheLinuxkerneltarballinbzip2formatisnamedlinux-x.y.z.tar.bz2,wherex.y.zistheversionofthatparticularreleaseofthekernelsource.Afterdownloadingthesource,uncompressinganduntarringitissimple.Ifyourtarballiscompressedwithbzip2,run$tarxvjflinux-x.y.z.tar.bz2IfitiscompressedwithGNUzip,run$tarxvzflinux-x.y.z.tar.gzThisuncompressesanduntarsthesourcetothedirectorylinux-x.y.z.2.1.1安装内核源代码内核压缩以GNUzip(gzip)和bzip2两种形式发布。bzip2是缺省和首选形式,因为它在压缩上比gzip有相当的优势。以bzip2形式发布的Linux内核叫做linux-x.y.z.tar.bz2,这里x.y.z是内核源码的具体版本。下载了源代码之后,就可以轻而易举地对其解压。如果压缩形式是bzip2,则运行:$tarxvjflinux-x.y.z.tar.bz2如果压缩形式是GNU的zip,则运行$tarxvzflinux-x.y.z.tar.gz解压后的源代码位于linux-x.y.z.目录下。何处安装源码内核源码一般安装在/usr/src/linux目录下。但请注意,不要把这个源码树用于开发。相反,编译你的C库所用的内核版本就链接到这颗树。此外,不要以root身份对内核进行修改,而应当是,建立自己的主目录,仅以root身份安装新内核。即使在安装新内核时,/usr/src/linux目录都应当原封不动。WheretoInstallandHackontheSourceThekernelsourceistypicallyinstalledin/usr/src/linux.Notethatyoushouldnotusethissourcetreefordevelopment.ThekernelversionthatyourClibraryiscompiledagainstisoftenlinkedtothistree.Besides,youdonotwanttohavetoberoottomakechangestothekernelinstead,workoutofyourhomedirectoryanduserootonlytoinstallnewkernels.Evenwheninstallinganewkernel,/usr/src/linuxshouldremainuntouched.2.22使用补丁在Linux内核社区中,补丁是通用语。你可以以补丁的形式发布对代码的修改,也可以以补丁的形式接收其他人所做的修改。时间流失,内核版本在不断更新,增量补丁可以作为版本转移的桥梁。你不再需要下载内核源码的全部压缩,而只需给旧版本打上一个增量补丁,让其旧貌换新颜。这不仅节约了带宽,还省了时间。要应用增量补丁,从你的内部源码树开始,只是运行:$patchp1../patch-x.y.z一般说来,一个给定版本的内核补丁总是打在前一个版本上。有关产生和应用补丁更深入的讨论会在后续章节进行。UsingPatchesThroughouttheLinuxkernelcommunity,patchesarethelinguafrancaofcommunication.Youwilldistributeyourcodechangesinpatchesaswellasreceivecodefromothersaspatches.Morerelevanttothemomentistheincrementalpatchesthatareprovidedtomovefromoneversionofthekernelsourcetoanother.Insteadofdownloadingeachlargetarballofthekernelsource,youcansimplyapplyanincrementalpatchtogofromoneversiontothenext.Thissaveseveryonebandwidthandyoutime.Toapplyanincrementalpatch,frominsideyourkernelsourcetree,simplyrun$patchp1../patch-x.y.zGenerally,apatchtoagivenversionofthekernelisappliedagainstthepreviousversion.Generatingandapplyingpatchesisdiscussedinmuchmoredepthinlaterchapters.2.2内核源码树内核源码树由很多目录组成,而大多数目录又包含更多的子目录。源码树的根目录及其子目录如表2.1所示表2.1内核源码树的根目录描述目录描述arch特定体系结构的源码cryptoCryptoAPIDocumentation内核源码文档drivers设备驱动程序fsVFS和各种文件系统include内核头文件init内核引导和初始化ipc进程间通信代码kernel像调度程序这样的核心子系统lib通用内核函数mm内存管理子系统和VMnet网络子系统scripts编译内核所用的脚本securityLinux安全模块目录描述sound语音子系统usr早期用户空间代码(所谓的initramfs)在源码树根目录中的很多文件值得提及。COPYING文件是内核许可证(GNUGPLv2)。CREDITS是开发者列表,其中还有不少内核代码的细节。MAINTAINERS是维护者列表,他们维护内核子系统和驱动程序。最后,Makefile是基本内核的Makefile。TheKernelSourceTreeThekernelsourcetreeisdividedintoanumberofdirectories,mostofwhichcontainmanymoresubdirectories.Thedirectoriesintherootofthesourcetree,alongwiththeirdescriptions,arelistedinTable2.1.Table2.1.DirectoriesintheRootoftheKernelSourceTreeDirectoryDescriptionarchArchitecture-specificsourcecryptoCryptoAPIDocumentationKernelsourcedocumentationdriversDevicedriversfsTheVFSandtheindividualfilesystemsincludeKernelheadersinitKernelbootandinitializationipcInterprocesscommunicationcodekernelCoresubsystems,suchastheschedulerlibHelperroutinesmmMemorymanagementsubsystemandtheVMnetNetworkingsubsystemscriptsScriptsusedtobuildthekernelsecurityLinuxSecurityModulesoundSoundsubsystemusrEarlyuser-spacecode(calledinitramfs)Anumberoffilesintherootofthesourcetreedeservemention.ThefileCOPYINGisthekernellicense(theGNUGPLv2).CREDITSisalistingofdeveloperswithamorethantrivialamountofcodeinthekernel.MAINTAINERSliststhenamesoftheindividualswhomaintainsubsystemsanddriversinthekernel.Finally,MakefileisthebasekernelMakefile.1.3编译内核编译内核易如反掌。让人叹为观止的是,这实际上比一些像glibc这样的用户级软件包还要简单。2.6内核提供了一套新工具,使编译内核更加容易,比2.4内核有了长足的进步。因为Linux源码随手可得,那就意味着在编译它之前可以配置和定制。的确,你可以把自己需要的功能和驱动程序编译进内核。在编译内核之前,首先你必须配置它。由于内核提供了数不胜数的功能,支持了难以计数的硬件,因而有许多东西需要配置。可以配置的各种选项,以CONFIG_FEATURE形式表示,其前缀为