1. 程式人生 > >Linux內核鏡像格式

Linux內核鏡像格式

命令行 相同 微軟 內核代碼 uboot 位置 image鏡像文件 main.c 通過

<Linux內核鏡像格式>

??Linux內核有多種格式的鏡像,包括vmlinux、Image、zImage、bzImage、uImage、xipImage、bootpImage等.

?kernel鏡像格式vmlinux

??vmlinux是可引導的、未壓縮、可壓縮的內核鏡像,vm代表Virtual Memory。(表示Linux支持虛擬內存,因此得名vm)它是由用戶對內核源碼編譯得到,實質是elf格式的文件.也就是說vmlinux是編譯出來的最原始的內核文件,未壓縮.這種格式的鏡像文件多存放在PC機上.

技術分享

?elf格式文件 :

ELF(Executable and Linkable Format)可執行可鏈接格式,是UNIX實驗室作為應用程序二進制接口而發布的,擴展名為elf.可以簡單的認為,在elf格式的文件中,除二進制代 碼外,還包括該可執行文件的某些信息,比如符號表等。

??vmlinuz 是可執行 的Linux內核,它位於/boot/vmlinuz,它一般是一個軟鏈接,比如是 vmlinuz-3.13.0-32-generic 的軟鏈接。vmlinuz是vmlinux的壓縮文件。vmlinuz的建立有兩種方式。一是編譯內核時通過“make zImage”創建,二是內核編譯時通過命令make bzImage創建。

?kernel鏡像格式:Image

??Image是經過objcopy處理的只包含二進制數據的內核代碼,它已經不是elf格式了,但這種格式的內核鏡像還沒有經過壓縮.

?objcopy:

??GNU使用工具程序objcopy作用是拷貝一個目標文件的內容到另一個目標文件中,也就是說,可以將一種格式的目標文件轉換成另一種格式的目標文件. 通過使用binary作為輸出目標(-o binary),可產生一個原始的二進制文件

,實質上是將所有的符號和重定位信息都將被拋棄,只剩下二進制數據。

?kernel鏡像格式:zImage

??zImage是ARM linux常用的一種壓縮鏡像文件它是由vmlinux經過objcopy , objcopy實現由vmlinux的elf文件拷貝成純二進制數據文件加上解壓代碼經gzip壓縮而成,命令格式是#make zImage.這種格式的Linux鏡像文件多存放在NAND上. 適用於小內核的情況,它的存在是為了向後的兼容性。

技術分享

?kernel鏡像格式:bzImage

??bzImage不是用bzip2壓縮的,bz表示big zImage,其格式與zImage類似,但采用了不同的壓縮算法,註意,bzImage的壓縮率更高

,是壓縮的內核映像
??zImage/bzImage:它們不僅是一個壓縮文件,而且在這兩個文件的開頭部分內嵌有解壓縮代碼。兩者的不同之處在於,老的zImage解壓縮內核到低端內存(第一個 640K),bzImage解壓縮內核到高端內存(1M以上)。如果內核比較小,那麽可以采用zImage或bzImage之一,兩種方式引導的系統運行時是相同的。大的內核采用bzImage,不能采用zImage。

?kernel鏡像格式:uImage

??uImage是uboot專用的鏡像文件,它是在 zImage 之前加上一個長度為0x40的頭信息(tag)(也就是說uImage 是一個二進制文件),在頭信息內說明了該鏡像文件的類型、加載 位置、生成時間、大小等信息.換句話說,若直接從uImage的0x40位置開始執行,則zImage和uImage沒有任何區別.命令格式是#make uImage.這種格式的Linux鏡像文件多存放在NAND上.

技術分享

?怎麽生成uImage??

在uboot的/tools目錄下尋找mkimage文件,把其copy到系統/usr/local/bin目錄下,這樣就完成制作工具。然後在內核目錄下運行make uImage,如果成功,便可以在arch/arm/boot/目錄下發現uImage文件,其大小比zImage多64個字節。
??由於bootloader一般要占用0x0地址,所以,uImage相比zImage的好處就是可以和bootloader共存。其實就是一個自動跟手動的區別,有了uImage頭部的描述,u-boot就知道對應Image的信息,如果沒有頭部則需要自己手動去搞那些參數。

?kernel鏡像格式:xipImage

??這種格式的Linux鏡像文件多存放在NorFlash上,且運行時不需要拷貝到內存SDRAM中,可以直接在NorFlash中運行.

<Linux內核鏡像的產生過程>

??在嵌入式Linux中,內核的啟動過程分為兩個階段.其中,第一階段啟動代碼放在arch/arm/kernel/head.S文件中,該文件與體系結構相關,與開發板周邊硬件無關,主要是初始化ARM內核等.第二階段啟動代碼是init目錄下的main.c.現以執行命令#make zImage為例來說明,arm-linux內核鏡像的產生過程.

?當用戶對Linux內核源碼進行編譯時,kernel的第1/2階段代碼會生成可執行文件vmlinux,該文件是未被壓縮的鏡像文件,非常大,不能直接下載到NAND中,通常放在PC機上,這也是最原始的Linux鏡像文件.一般該文件約50M左右.

?鏡像文件vmlinux由於很大,肯定不能直接燒入NAND中,因此需要進行二進制化,即經過objcopy處理,使之只包含二進制數據的內核代 碼,去除不需要的文件信息等,這樣就制作成了image鏡像文件.該鏡像文件也是未壓縮,只是經過了二進制化而變小.該文件約5M左右.

? 一般來說,內存SDRAM中的內核鏡像是經過壓縮的,只是在運行時再將其解壓.所以,編譯時會先使用gzip將鏡像文件image進行壓縮(壓縮比約為 2:1),再將壓縮後的鏡像文件和源碼中的兩個文件arch/arm/boot/compressed/head.S、arch/arm/boot /compressed/misc.c一起鏈接生成壓縮後的鏡像文件compress/vmlinux.該文件約為2.5M左右。註意,這兩個源碼文件是解壓程序,用於將內存SDRAM中的壓縮鏡像zImage進行解壓.

?壓縮後的鏡像文件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鏡像文件大小相同.

<註意事項>

?網站:http://lxr.linux.no/該網站通過了Linux內核源碼,不用解壓,在線查詢,非常方便.

?生成的鏡像文件vmlinux放在源碼的頂層目錄下.

?生成的鏡像文件image、zImage均在arch/arm/boot目錄下.

?啟動開發板時,在超級終端內會有許多的提示信息,其中:

?booting linux … /表示正在將內核從NAND拷貝到內存中/

?unpressed… /表示正在解壓內核/

?只有當用戶輸入boot命令或在boot_delay延時時間後,vivi才將NANDFlash中的內核kernel拷貝到內存SDRAM中.也就是說,當vivi進入命令行模式時,在SDRAM中並沒有內核kernel.

?在kernel源碼目錄下執行命令:

?<1> #tree /打印出kernel源碼的目錄結構/

?<2> #tree -L 1 /打印出kernel源碼的第一級目錄結構/

?<3> #tree > /home/lishuai/linux.txt /將kernel源碼的目錄結構重定向到某個文件中,用戶可以隨時查看其目錄結構,非常方便/

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">



來自為知筆記(Wiz)



Linux內核鏡像格式