Copy from :https://blog.csdn.net/pi408637535/article/details/38438309
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源碼的目錄結構重定向到某個文件中,用戶可以隨時查看其目錄結構,非常方便*/
LD vmlinux
SYSMAP System.map
SYSMAP .tmp_System.map
OBJCOPY arch/arm/boot/Image
Kernel: arch/arm/boot/Image is ready
AS arch/arm/boot/compressed/head.o
GZIP arch/arm/boot/compressed/piggy.gz
AS arch/arm/boot/compressed/piggy.o
CC arch/arm/boot/compressed/misc.o
AS arch/arm/boot/compressed/head-xscale.o
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
vmlinux 是一個elf格式的文件
Image 是經過objcopy 處理了的只包含內核代碼,數據的一個文件, 已經不是elf格式的了。此時還沒有經過壓縮
arch/arm/boot/compressed/vmlinux 是經過壓縮的Image和加入了解壓頭的elf格式的文件
arch/arm/boot/zImage 是經過objcopy處理了的可以直接下到對應的地址執行的內核鏡像
objcopy:
GNU實用工具程序objcopy的作用是拷貝一個目標文件的內容到另一個目標文件中。 Objcopy使用GNU BFD庫去讀或寫目標文件。Objcopy可以使用不同於源目標文件的格式來寫目的目標文件(也即是說可以將一種格式的目標文件轉換成另一種格式的目標文 件)。通過以上命令行選項可以控制Objcopy的具體操作。
Objcopy在進行目標文件的轉換時,將生成一個臨時文件,轉換完成后就將這個臨時文件刪掉。Objcopy使用BFD做轉換工作。如果沒有明確 地格式要求,則Objcopy將訪問所有在BFD庫中已經描述了的並且它可以識別的格式,請參見《GNUpro Decelopment Tools》中“using ld”一章中“BFD庫”部分和“BFD庫中規范的目標文件格式”部分。
通過使用srec作為輸出目標(使用命令行選項-o srec),Objcopy可以產生S記錄格式文件。
通過使用binary作為輸出目標(使用命令行選項-o binary),Objcopy可以產生原始的二進制文件。使用Objcopy產生一個原始的二進制文件,實質上是進行了一回輸入目標文件內容的內存轉 儲。所有的符號和重定位信息都將被丟棄。內存轉儲起始於輸入目標文件中那些將要拷貝到輸出目標文件去的部分的最小虛地址處。
使用Objcopy生成S記錄格式文件或者原始的二進制文件的過程中,-S選項和-R選項可能會比較有用。-S選項是用來刪掉包含調試信息的部分,-R選項是用來刪掉包含了二進制文件不需要的內容的那些部分。
vmlinux,vmlinuz,uImage,zImage,bzImage之間的異同
編譯過RedHat Linux內核的人對其中的System.map、vmlinuz、initrd-2.4.7-10.img印象可能比較深刻,因為編譯內核過程中涉及到這些文件的建立等操作。那么這幾個文件是怎么產生的?又有什么作用呢?本文對此做些介紹。
此外,平時調試用uImage,不用去管調整了哪些東西;zImage則是一切OK后直接燒0X0。開機就運行。
在make install發生的事
在make install后, 會有三個文件被放到/boot下:
1. vmlinuz-2.6.x.y.z
2. System.map
3. config
4. 為什么我的gentoo沒有initrd.img的??
在/usr/src/linux下還有一個vmlinux的方件.
那么/boot下的vmlinux是哪個呢? 如下:
jessinio@niolaptop /usr/src/linux $ diff /usr/src/linux/arch/x86/boot/bzImage /usr/src/linux/vmlinux
Files /usr/src/linux/arch/x86/boot/bzImage and /usr/src/linux/vmlinux differ
jessinio@niolaptop /usr/src/linux $ diff /usr/src/linux/arch/x86/boot/bzImage /boot/vmlinuz
可以看出/boot下的vmlinux是/usr/src/linux/arch/x86/boot/bzImage
隨便提一下make內核時的過程:
就常使用的make也過程:
cd /usr/src/linux
make menuconfig
make
make modules_install
make install
注意到上面的一個make是不參數的, 這種情況實際如下:
Execute "make" or "make all" to build all targets marked with [*]
帶"*"號等於如下:
make vlinux modules bzImage
zImage / vmlinux / Image生成的流程圖
SRC_TREE :=./
HEADER_PATH :=arch/arm/boot/compressed
BOOT_PATH :=arch/arm/boot/
KERNEL_PATH :=arch/arm/kernel
-----------------------------------------------------------------------------------------------------------------------
1 SRC_TREE 目錄下的vmlinux經過objcoy后生成二進制文件Image,Image在經過gzip壓縮后生成piggy.o
piggy.o是真正的內核鏡像文件
2 HEADER_PATH/head.o ,head-xscal.o ,misc.o 的作用就是把piggy.o解壓到指定的位置,然后執行piggy.o解壓后的代碼
HEADER_PATH/zImage
^
|[objcopy]
|
HEADER_PATH/vmlinux
^
|[ld]
|
+-<--HEADER_PATH/head.o
|
+-<--HEADER_PATH/head-xscal.o
|
+-<--HEADER_PATH/misc.o
|
+-<--HEADER_PATH/piggy.o <-- HEADER_PATH/piggy.gz <--[gzip]-- BOOT_PATH/Image <--[objcopy]--SRC_TREE/vmlinux
-----------------------------------------------------------------------------------------------------------------------
SRC_TREE目錄下的vmlinux是由一下三部分組成的:
$(vmlinux-init)
$(vmlinux-main)
kallsyms.o
vmlinux
^
|
+-<--$(vmlinux-init)
| ^
| |
| +--<--KERNEL_PATH/head.S
| |
| +--<--KERNEL_PATH/init_task.o
| |
| +--<--SRC_TREE/init/build-in.o
|
+--< $(vmlinux-main)
| ^
| |$(cory-y)
| +--<--SRC_TREE/driver/built-in.o
| |
| +--<--SRC_TREE/mm/built-in.o
| |
| +--<--SRC_TREE/usr/built-in.o
| |
| +--<--SRC_TREE/kernel/built-in.o
| |
| +--<--SRC_TREE/mm/built-in.o
| |
| +--<--SRC_TREE/fs/built-in.o
| |
| +--<--SRC_TREE/ipc/built-in.o
| |
| +--<--SRC_TREE/securiy/built-in.o
| |
| +--<--SRC_TREE/crypto/built-in.o
| |
| +--<--SRC_TREE/block/built-in.o
| |
| +--<--arch/arm/kernel/built-in.o
| |
| +--<--arch/arm/mm/built-in.o
| |
| +--<--arch/arm/common/built-in.o
| |
| +--<--arch/arm/mach-pxa/built-in.o
| |
| +--<--arch/arm/nwfpe/buit-in.o
| |
| |$(lib-y)
| +--<--SRC_TREE/lib/built-in.o
| |
| +--<--arch/arm/lib/built-in.o
| |
| |$(drivers-y)
| +--<--SRC_TREE/drivers/buit-in.o
| |
| +--<--SRC_TREE/sound/buit-in.o
| |
| |$(net-y)
| +--<--SRC_TREE/net/buit-in.o
|
+--< kallsyms.o
