linux内核镜像格式
一、Linux内核镜像格式  
   Linux内核有多种格式的镜像,包括vmlinux、Image、zImage、bzImage、uImage、xipImage、bootpImage等.
(1)kernel镜像格式:vmlinux
   vmlinuz是可引导的、可压缩的内核镜像,vm代表Virtual Memory.Linux支持虚拟内存,因此得名vm.它是由用户对内核源码编译得到,实质是elf格式的文件.也就是说,vmlinux是编译出来的最原始的内核文件,未压缩.这种格式的镜像文件多存放在PC机上.
  【 attention】elf格式文件
      ELF,Executable and Linkable Format,可执行可链接格式,是UNIX实验室作为应用程序二进制接口而发布的,扩展名为elf.可以简单的认为,在elf格式的文件中,除二进制代码外,还包括该可执行文件的某些信息,比如符号表等.
(2)kernel镜像格式:Image
   Image是经过objcopy处理的只包含二进制数据的内核代码,它已经不是elf格式了,但这种格式的内核镜像还没有经过压缩.
  【 attention】objcopy
      GNU使用工具程序objcopy作用是拷贝一个目标文件的内容到另一个目标文件中,也就是说,可以将一种格式的目标文件转换成另一种格式的目标文件.通过使用binary作为输出目标(-o binary),可产生一个原始的二进制文件,实质上是将所有的符号和重定位信息都将被抛弃,只剩下二进制数据.
(3)kernel镜像格式:zImage
   zImage是ARM linux常用的一种压缩镜像文件,它是由vmlinux加上解压代码经gzip压缩而成,命令格式是#make zImage.这种格式的Linux镜像文件多存放在NAND上.
(4)kernel镜像格式:bzImage
   bz表示big zImage,其格式与zImage类似,但采用了不同的压缩算法,注意,bzImage的压缩率更高.
(5)kernel镜像格式:uImage
   uImage是uboot专用的镜像文件,它是在zImage之前加上一个长度为0x40的头信息(tag),在头信息内说明了该镜像文件的类型、加载位置、生成时间、大小等信息.换句话说,若直接从uImage的0x40位置开始执行,则zImage和uImage没有任何区别.命令格式是#make uImage.这种格式的Linux镜像文件多存放在NAND上.
(6)kernel镜像格式:xipImage
   这种格式的Linux镜像文件多存放在NorFlash上,且运行时不需要拷贝到内存SDRAM中,可以直接在NorFlash中运行.




二、Linux内核镜像的产生过程
  在嵌入式Linux中,内核的启动过程分为两个阶段.其中,第一阶段启动代码放在arch/arm/kernel/head.S文件中,该文件与体系结果相关,与用户的开发板无关,主要是初始化ARM内核等.第二阶段启动代码是init目录下的main.c.现以执行命令#make zImage为例来说明,arm-linux内核镜像的产生过程.
(1)当用户对Linux内核源码进行编译时,kernel的第1/2阶段代码会生成可执行文件vmlinux,该文件是未被压缩的镜像文件,非常大,不能直接下载到NAND中,通常放在PC机上,这也是最原始的Linux镜像文件.试验时该文件约50M.
(2)镜像文件vmlinux由于很大,肯定不能直接烧入NAND中,因此需要进行二进制化,即经过objcopy处理,使之只包含二进制数据的内核代码,去除不需要的文件信息等,这样就制作成了image镜像文件.该镜像文件也是未压缩,只是经过了二进制化而变小.试验时该文件约5M.
(3) 一般来说,内存SDRAM中的内核镜像是经过压缩的,只是在运行时再将其解压.所以,编译时会先使用gzip将镜像文件image进行压缩(压缩比约为 2:1),再将压缩后的镜像文件和源码中的两个文件arch/arm/boot/compressed/head.S、arch/arm/boot /compressed/misc.c一起链接生成压缩后的镜像文件compress/vmlinux.试验时该文件约为2.5M.注意,这两个源码文件是解压程序,用于将内存SDRAM中的压缩镜像zImage进行解压.
(4)压缩后的镜像文件compress/vmlinux经过二进制化,最终生成镜像文件zImage,试验时该文件约为2.5M.当然,在内存SDRAM中运行压缩镜像文件zImage时,会首先调用两个解压程序arch/arm /boot/compressed/head.S、arch/arm/boot/compressed/misc.c将自身解压,然后再执行kernel 的第一阶段启动代码arch/arm/kernel/head.S.简而言之,在内存中运行内核时,kernel先自身解压,再执行第一阶段启动代码.试验时运行在内存中的镜像文件约为5M,与image镜像文件大小相同.
【 attention】
(1) 网站:http://lxr.linux.no/
   该网站通过了Linux内核源码,不用解压,在线查询,非常方便.
(2)生成的镜像文件vmlinux放在源码的顶层目录下.
(3)生成的镜像文件image、zImage均在arch/arm/boot目录下.
(4)启动开发板时,在超级终端内会有许多的提示信息,其中:

booting linux ...  /*表示正在将内核从NAND拷贝到内存中*/
       unpressed...      /*表示正在解压内核*/


(5)只有当用户输入boot命令或在boot_delay延时时间后,vivi才将NANDFlash中的内核kernel拷贝到内存SDRAM中.也就是说,当vivi进入命令行模式时,在SDRAM中并没有内核kernel.
(6)在kernel源码目录下执行命令:

<1> #tree       /*打印出kernel源码的目录结构*/
   <2> #tree -L 1   /*打印出kernel源码的第一级目录结构*/
   <3> #tree > /home/lishuai/linux.txt   /*将kernel源码的目录结构重定向到某个文件中,用户可以随时查看其目录结构,非常方便*/


 /222  
 vmlinux,vmlinuz,uImage,zImage,bzImage之间的异同




在网络中,不少服务器采用的是Linux系统。为了进一步提高服务器的性能,可能需要根据特定的硬件及需求重新编译Linux内核。编译Linux 内核,需要根据规定的步骤进行,编译内核过程中涉及到几个重要的文件。比如对于RedHat Linux,在/boot目录下有一些与Linux内核有关的文件,进入/boot执行。 
  编译过RedHat Linux内核的人对其中的System.map、vmlinuz、initrd-2.4.7-10.img印象可能比较深刻,因为编译内核过程中涉及到这些文件的建立等操作。那么这几个文件是怎么产生的?又有什么作用呢?本文对此做些介绍。
  一、vmlinuz
  vmlinuz是可引导的、压缩的内核。“vm”代表“Virtual Memory”。Linux 支持虚拟内存,不像老的操作系统比如DOS有640KB内存的限制。Linux能够使用硬盘空间作为虚拟内存,因此得名“vm”。vmlinuz是可执行 的Linux内核,它位于/boot/vmlinuz,它一般是一个软链接,比如图中是vmlinuz-2.4.7-10的软链接。
  vmlinuz的建立有两种方式。一是编译内核时通过“make zImage”创建,手动拷贝到/boot目录下面。zImage适用于小内核的情况,它的存在是为了向后的兼容性。
  二是内核编译时通过命令make bzImage创建,然后手动拷贝至/boot目录下。bzImage是压缩的内核映像,需要注意,bzImage不是用bzip2压缩 的,bzImage中的bz容易引起误解,bz表示“big zImage”。 bzImage中的b是“big”意思。 zImage(vmlinuz)和bzImage(vmlinuz)都是用gzip压缩的。它们不仅是一个压缩文件,而且在这两个文件的开头部分内嵌有 gzip解压缩代码。所以你不能用gunzip 或 gzip –dc解包vmlinuz。
  内核文件中包含一个微型的gzip用于解压缩内核并引导它。两者的不同之处在于,老的zImage解压缩内核到低端内存(第一个 640K),bzImage解压缩内核到高端内存(1M以上)。如果内核比较小,那么可以采用zImage或bzImage之一,两种方式引导的系统运行 时是相同的。大的内核采用bzImage,不能采用zImage。vmlinux是未压缩的内核,vmlinuz是vmlinux的压缩文件。
  二、initrd-x.x.x.img
  initrd是“initial ramdisk”的简写。initrd一般被用来临时的引导硬件到实际内核vmlinuz能够接管并继续引导的状态。图中的initrd-2.4.7-10.img主要是用于加载ext3等文件系统及scsi设备的驱动。
  比如,使用的是scsi硬盘,而内核vmlinuz中并没有这个scsi硬件的驱动,那么在装入scsi模块之前,内核不能加载根文件系统,但 scsi模块存储在根文件系统的/lib/modules下。为了解决这个问题,可以引导一个能够读实际内核的initrd内核并用initrd修正 scsi引导问题。initrd-2.4.7-10.img是用gzip压缩的文件,initrd实现加载一些模块和安装文件系统等功能。
  initrd映象文件是使用mkinitrd创建的。mkinitrd实用程序能够创建initrd映象文件。这个命令是RedHat专有的(这也是为什么,在Linux内核包里/Documentation/Changes里面没有提到要将mkinitrd升级)。其它Linux发行版或许有相应的命令。这是个很方便的实用程序。具体情况请看帮助:man mkinitrd下面的命令创建initrd映象文件。
   三、uImage文件
  vmlinux是内核文件,zImage是一般情况下默认的压缩内核映像文件,压缩vmlinux,加上一段解压启动代码得到。而uImage 则是使用工具mkimage对普通的压缩内核映像文件(zImage)加工而得。它是uboot专用的映像文件,它是在zImage之前加上一个长度为 64字节的“头”,说明这个内核的版本、加载位置、生成时间、大小等信息;其0x40之后与zImage没区别。
其实就是一个自动跟手动的区别,有了uImage头部的描述,u-boot就知道对应Image的信息,如果没有头部则需要自己手动去搞那些参数。
如何生成 uImage文件?首先在uboot的/tools目录下寻找mkimage文件,把其copy到系统/usr/local/bin目录下,这样就完成制 作工具。然后在内核目录下运行make uImage,如果成功,便可以在arch/arm/boot/目录下发现uImage文件,其大小比 zImage多64个字节。
此外,平时调试用uImage,不用去管调整了哪些东西;zImage则是一切OK后直接烧0X0。开机就运行。