Linux内核学习的第一步之README文档解读

近来下班之后的闲暇时间偶尔会思考我现在的对Linux的内核的迷惑还在那里,我觉得是因为迷惑太多而不知道该怎么理出头绪,我就在想是不是先从内核源码的顶层Makefile开始着手呢?是的,我先着手看看,会发现什么东东!!(其实只有你动手去做才会牵连出很多相关的信息,然后你再在适当的时间节点去搂一眼被牵连的东东,然后又牵出一大片,就像当今抓贪官一般,一个老虎的身后隐藏了无数只老鼠!!!!)当然我没有别的意思只是茶余饭后的闲谈,如果击中了某位还烦请海涵!!!

其实开始呢我是在看README的原文,但自己又是一个心急的人,英文虽然读着意思理解的到位,但是还是想先搂一眼,细节之处再处理。所以万能的网络世界中有位童鞋已经对此作了一番工作,索性就先拿来主义,readme一番!!!


个人对文中认为不太合适的地方稍加改动,感谢原作者的努力与分享!!!


翻译原文地址:http://blog.sina.com.cn/s/blog_8e037f440100vtld.html

原文地址:http://lxr.linux.no/#linux+v2.6.32/README
说明:linux kernel 源代码顶层目录下的README文件

本篇是Linux 2.6 版本的发行注记。仔细阅读本篇文章,你将知道这篇文档都说了些什么、如何安装内核,出错时该如何处理。

啥是Linux!!!
  Linux是Unix操作系统的一个克隆版本,由Linux Torvalds(以其名命名)和网络上的骇客团队共同编写的,目标是更加符合POSIX和Single Unix 规格标准.

  它拥有现代成熟Unix操作系统的所有特性,包括真正的多任务、虚拟内存、共享库、加载器、执行程序的共享写时拷贝技术(STL)、优化的内存管理,还有多网络协议如IPv4和IPv6。


  它在GNU公共许可证的保护下发行 - 详情请查看附带的COPYING文件

硬件环境
 
  虽然最初Linux开发在32位机(386或更高)上,但如今Linux也能至少在以下架构的处理器上运行:
  Compaq Alpha AXP, Sun SPARC and UltraSPARC, Motorola 68000, PowerPC,
  PowerPC64, ARM, Hitachi SuperH, Cell, IBM S/390, MIPS, HP PA-RISC,
  Intel IA-64, DEC VAX, AMD x86-64, AXIS CRIS, Xtensa, AVR32 ,
  Renesas M32R.
 
    只要含有分页机制的内存管理单元(PMMU)和GNU C编译器接口(The GNU Compiler Collection的组成部分,GCC),Linux就能很容易的移植到主流的32或64位体系结构的处理器上。Linux也能在一些没有PMMU的架 构上进行移植,虽然功能性上面或多或少有所限制。Linux还能移植到它自己身上。你可以像用户空间的应用程序一样运行内核--这叫“用户模式 Linux”(UserMode Linux,简称UML)。

文档:
- 已经有大量针对Linux或关于通用Unix问题的文档,或以电子档的形式在网络上,
   或以书本的形式发行。这里建议在任何Linux FTP的各子目录里相看有关Linux的文章。这份注记不是作为系统的文档而提供的:有很多更好的资源适合你去阅读。

 - 在Documentation/的子目录下有许多不同的README文件,比如其中会有关于一些驱动的内
核安装说明。Documentation/00-INDEX 文件中包含关于各文件主要内容介绍的索引。也看下Changes 文件,其中有关于升级内核的一些信息。

 - Documentation/DocBook/ 子目录下包含一些内核开发人员和用户的指南。这些指南提供多
种 格式:PostScript (.ps), PDF, HTML, 和man-pages 等。内核代码安装好之后,可以通过使用 "make psdocs", "make pdfdocs", "make htmldocs"或"make mandocs"命令来生成相应格式的文档。

安装内核源码(这里指简单意义上的安装):
#安装实际就是代码的拷贝,这里理解为下载并解压一份Linux内核源代码在你的系统上;


- 如果安装所有的源代码,将压缩包放在某个你有相应权限的目录下(在你的home目录下就可以了),然后解压:

gzip -cd linux-2.6.XX.tar.gz | tar xvf -
       
   或
      
bzip2 -dc linux-2.6.XX.tar.bz2 | tar xvf -

   其中“XX”指对应的内核版本号(一般升级时我们都选择最新的内核版本)

   请不要使用 /usr/src/linux 这个区域。这个区域包含库头文件需要使用的大量(通常不完全)的内核头文件。它们必须与库相匹配,而不应该因为内核变更弄的一团糟。

 - 你可以通过打补丁在2.6XX发布版之间升级。补丁以传统的gzip格式和较新的bzip2格式提供。打补丁时,先下载所有新的补丁文件,进入内核源码的顶层目录,然后执行以下命令:
      
gzip -cd ../patch-2.6.xx.gz | patch -p1
   或  
bzip2 -dc ../patch-2.6.xx.bz2 | patch -p1

   (xx 表示比现在内核源码版本更大的版本号).
   这样补丁就打好了。如果想要删除备份文件(xxx~或xxx.orig),确认没有打失败的补丁(xxx# 或 xxx.rej)。如果有,则说明不是你就是我出错了。

   与2.6.x内核补丁不同,2.6.x.y内核补丁(稳定版)的版本号并不是递增而是在2.6.x内核版本号基础上提供的。详情请阅读 Documentation/applying-patches.txt 文件。

   另外,内核补丁的脚本文件会自动的完成打补丁这一步骤。这会取决于当前的内核版本以及提供的补丁。

        linux/scripts/patch-kernel linux

   第一个参数linux是当前内核源码的路径。补丁文件都在当前的目录里,但也可以用第二个参数来指定。

 - 如果你在发布版间升级实用稳定版的补丁(例如,patch-2.6.xx.y),需要知道这种“点-发布板”(即稳定版)的版本号不是递增的,必须提供 2.6.xx基础的版本树。比如,如果当前的内核源码是2.6.12版本的,要打2.6.12.3的补丁,则不需要打2.6.12.1 和2.6.12.2 这两个补丁。类似的,如果你现在运行的内核版本为2.6.12.2,想要升级到2.6.12.3,则你需要先卸掉2.6.12.2的补丁(patch -R)。
   详情请阅读 Documentation/applying-patches.txt文件。

 - 确保没有过期的 .o 文件和依赖关系:
        
        cd linux
        make mrproper    #关于这个命令你可以百度,解释很多!!

   相信现在你已经成功地安装好内核源码了。

需要的软件

    编译并运行2.6.xx内核需要一些较新的软件包。从 Documentation/Changes 中查找有关于所需软件包的最低版本号,以及如何升级这些软件。注意使用一些过老版本的软件包会导致间接的错误,且这些错误非常难去跟踪,所以不要认为你可 以在很明显的问题出现时再升级包。

构建内核路径:

    默认情况下,编译内核源代码所有生成的文件会与内核源代码在同个目录下。
    使用 “make O=output/dir" ,这样就可以让你在不同的目录下来放生成的文件(包括 .config)
    例:
      内核代码的目录    /usr/src/linu=2.6.N
      编译目录          /home/name/build/kernel

    使用下面的命令来配置和编译内核
    cd /usr/src/linux-2.6.N
    make O=/home/name/build/kernel menuconfig
    make O=/home/name/build/kernel
    sudo make O=/home/name/build/kernel moudules_install install

    请注意:一旦使用了'O=output/dir'这个选项,则后面的命令都要使用这个选项。

配置内核:

       不要跳过这一步,即使你是在升级一个次要的版本。每个发行版都会有新的配置选项加入,如果并不按设想的来建立配置文件的话可能会导致一些奇怪的问题。如 果你只想通过以最少的工作来配置新的版本,使用"make oldconfig"命令,这样配置时只需要回答一些新添的配置问题。

    - 更改配置的命令如下:
       "make config"         文字界面
       "make menuconfig"   基于文字的有色菜单,有提示和对话框
       "make xconfig"       基于Qt的配置工具
       "make gconfig"       基于Gtk的配置工具
       "make oldconfig"    根据已经存在的./.config文件默认配置,只需要对一些新添的配置符号进行选择。
       "make silentoldconfig"
                      和上面一样,不过避免了已经回答了的问题在屏幕上的杂乱显示。增加了一些升级依赖。
       "make defconfig"    
      通过使用从 arch/$ARCH/defconfig 或 arch/$ARCH/configs/${PLATFORM}_defconfig  文件中默认的符号值来创建一个新的                         ./.config 文件,与架构有关。
       "make ${PLATFORM}_defconfig"
                                 使用arch/$ARCH/configs/${PLATFORM}_defconfig 中默认的符号值来创建一个新的 ./.config 文件。使用 make help                             来查看所有支持的平台和架构。
       "make allyesconfig"
                      尽可能多的安装内核支持的所有特性,生成 ./.config
       "make allmodconfig"
                      尽可能多的安装内核支持的所有驱动来生成 ./.config
       "make allnoconfig"
                      以最小安装的形式来生成 ./.config
       "make randconfig"  
通过给所需符号值随机赋值的形式来生成 ./.config

       可以在 Documentation/kbuild/kconfig.txt 中找到更多关于Linux内核配置工具的信息。

             注意 "make config":
             - 将不必要的驱动程序编译进内核会使得最终的内核变大,也可能会造成一些
                其他的问题:移植到一个不存在的控制卡可能与其他控制器相冲突。
             - 编译时指定非386处理器类型,会使得编译后得到的内核映像不能运行于386处
                理器。内核会在引导时检测到这个问题,然后放弃引导内核。
             - 如果存在协处理器的话,内核编译时仍会将协处理器作为数学仿真器来使用。
                内核中是不会使用到数学仿真器的。内核也许会大一点,但是可以在不同类
                别的机器上运行而不必去关心是否有一个数学协处理器。
             - "kernle hacking"这个配置项选中的话会导致编译处的内核大一些或慢一些(或两者都有),如果通过改变一些固定而有规则的程序的配置来测试坏代码可能使内核 变得不稳定(像kmalloc())。因此你应该在 “develoment”,“expermental“,或“debugging” 选项上回答 ’n‘。

编译内核:

  - 确认gcc至少为3.2版本。在 Documentation/Changes 中可查阅到更多的信息。
     
     请注意当前的内核仍能够运行 a.out 形式的用户程序。

  - "make" 命令用来生成一个已压缩的内核映像。如果你有lilo(Linux Loader)来生成内核的makefiles文件,你也可以使用 "make install" 命令,但首先你需要检查你的lilo是否安装了。

     真正安装时需要root权限,但其他的编译动作不需要。尽量不要使用root身份来执行命令。

  - 如果将某个部份编译成了模块`modules',还需要运行 "make modules_install" 命令

  - 内核编译/构建时的详细输出信息:

     一般编译内核时都是一种安静模式(当然也不是绝对的)。有些时候也需要你或其他内核开发者来看看编译、连接或其他命令是不是如预期那样地执行。此时,使用"verbose"编译模式,只需在编译命令"make"时插入"V=1"即可:
            
             make V=1 all

如果要在编译系统的同时对重复编译每个对象的原因进行说明,用 "V=2".默认是 "V=0"。

  - 保留旧内核的备份以防新内核安装时出现错误。特别是对于开发版本来说,因为新发布的内核包含新的未调试的代码。确保你保留与旧内核相匹配的各模块备份。在"make modules_install"之前进行备份。
     另外,在编译之前,使用内核配置选项"LOCALVERSION"在规则的内核版本后面添加唯一的后缀。LOCALVERSION在"General Setup"菜单中设置。

  - 为了能够引导新的内核,需要将内核映像(../linux/arch/i386/boot/bzImage)复制到可以成功引导的内核的地方存放。

  - 不通过引导程序如LILO而直接从软盘启动内核的方式现在已经不支持。

     如果从硬件起动,使用LILO时,内核映像是在/etc/lilo.conf中指定的。通常的内
     核映像文件是/vmlinuz, /boot/vmlinuz, /bzImage 或 /boot/bzImage。使用新的内
     核,请保留旧内核的备份,然后将新内核覆盖旧内核即可。接着,切记必须重新运行LILO中
     来更新加载映射!!如果这一步没有做,则不能引导新的内核。

     重新安装LILO通常只需要运行/sbin/lilo。用户还可以编辑/etc/lilo.conf,来为旧
     内核指定一个入口(叫,/vmlinux.old),使得在新内核停止使用从旧内核开始执行。更多的信息
     请查阅 LILO 的相关说明。

     重装完LILO之后,所有的工作都作完了。然后关掉系统,重启后开始愉快的Linux之旅吧。

     如果还需要更改内核中默认的根设备、视频模式、ramdisk的大小等,使用'rdev'程序(如果可能的话用使用lilo加载选项),而不必重新编译内核来改变这些参数。

如果出现了错误:

  - 如果问题看起来像是内核的bug,请检查MAINTAINERS来查看出错的部份是否有专门的
     人来维护,如果没有,请向torvalds@linux-foundation.org发邮件,如果可能的话,
     也可向相关的邮件列表发邮件。

  - 在报告bug时,请详细描述你所用的是什么内核、如何重现你所遇到的问题、你做了哪
     设置(你感觉会是什么问题)。如果是新问题,告诉我这些,如果是旧问题(该问题以前
     可能被讨论过), 请告诉我你是什么时候开始注意该问题的。

  - 如果bug产生的消息如下

unable to handle kernel paging request at address C0000010
Oops: 0002
EIP:    0010:XXXXXXXX
eax: xxxxxxxx    ebx: xxxxxxxx    ecx: xxxxxxxx    edx: xxxxxxxx
esi: xxxxxxxx    edi: xxxxxxxx    ebp: xxxxxxxx
ds: xxxx   es: xxxx   fs: xxxx   gs: xxxx
Pid: xx, process nr: xx
xx xx xx xx xx xx xx xx xx xx


     屏幕上或系统log里记录了类似上面的信息,请准确地将它们复制下来。这些可能看
     起来毫无意义,但其中却可能包含了用于调试该问题的信息。它上部的字符也很重要
     :它记录了内核崩溃代码(上面的例子里的错误代码表示出错的原因是错误的内核指
     针)。更多关于这类的信息可查看 Documentation/oops-tracing.txt。

  - If you compiled the kernel with CONFIG_KALLSYMS you can send the dump
     as is, otherwise you will have to use the "ksymoops" program to make
     sense of the dump (but compiling with CONFIG_KALLSYMS is usually preferred).
     This utility can be downloaded from
     ftp://ftp.<country>.kernel.org/pub/linux/utils/kernel/ksymoops/ .
     Alternately you can do the dump lookup by hand:

  - 在调试类似上面的出错信息时,如果能看懂EIP的意思,那帮助可就大了。这个十六进
     制值此时显得毫无用处,它的值取决于内核的具体设置。而我们应该做的就是将EIP这
     一行的这个十六进制值取出(不包括0010),然后在内核列表中查看哪个函数占用了这
     段内存地址。

     To find out the kernel function name, you'll need to find the system
     binary associated with the kernel that exhibited the symptom.
     这个文件是'linux/vmlinux'。提取名字列表,然后将其与崩溃内核的EIP相比较:

                         nm vmlinux | sort | less

     这将给出一个排序好了的内核地址列表,从该列表中就很容易找到出错的地址。注意
     :内核调试信息给出的地址并不与函数地址匹配(事实上也不太可能匹配),所以不能
     使用'grep'。尽管如此,这个列表给出了内核中每个函数的起始地址,所以只需要找
     到一个函数的起始地址小于EIP中给出的地址,但紧跟着的函数地址大于EIP中给出的
     址(那么就定位到了该地址是在哪个函数中地,即出错在哪个函数中)。事实上,在提
     交问题是给出一些"上下文"是非常不错的主意。

     如果因为某些原因不能按照上面所的来提交信息,那将你的设置步骤告诉我,越多越
     好。更多细节请阅读 REPORTING-BUGS 文档。

  - 另外,也可使用gdb来在运行中调试内核。(只读,不能改变变量的值,不能设置断点)
     编译时使用 -g 来编译内核;编辑 arch/i386/Makefile 文件,然后 "make clean"。
     当然还需要使能 CONFIG_PROC_FS 。

     重新启动新内核后,"gdb vmlinux /proc/kcore"。接着就可以使用一般的gdb命令了
     。查看系统崩溃处的命令是"l *0xXXXXXXXX"。(XXXes换成EIP的值)

     使用gdb调试一个不在运行的内核会失败,因为gdb忽视内核编译时指定的起始地址。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值