一、vmlinuz
vmlinuz是可引導的、壓縮的內核。“vm”代表“Virtual Memory”。Linux 支持虛擬內存,不像老的操作系統比如DOS有640KB內存的限制。Linux能夠使用硬盤空間作為虛擬內存,因此得名“vm”。
vmlinuz的建立有兩種方式。一是編譯內核時通過“make zImage”創建,然后通過:“cp /usr/src/linux-2.4/arch/i386/linux/boot/zImage/boot/vmlinuz”產生。zImage適用于小內核的情況,它的存在是為了向后的兼容性。
二是內核編譯時通過命令make bzImage創建,然后通過:“cp/usr/src/linux-2.4/arch/i386/linux/boot/bzImage /boot/vmlinuz”產生。bzImage是壓縮的內核映像,需要注意,bzImage不是用bzip2壓縮的,bzImage中的bz容易引起誤解,bz表示“big zImage”。 bzImage中的b是“big”意思。 zImage(vmlinuz)和bzImage(vmlinuz)都是用gzip壓縮的。它們不僅是一個壓縮文件,而且在這兩個文件的開頭部分內嵌有 gzip解壓縮代碼。所以你不能用gunzip 或 gzip –dc解包vmlinuz。?
二、initrd-x.x.x.img
initrd是“initial ramdisk”的簡寫。initrd一般被用來臨時的引導硬件到實際內核vmlinuz能夠接管并繼續引導的狀態。
initrd映象文件是使用mkinitrd創建的。mkinitrd實用程序能夠創建initrd映象文件。這個命令是RedHat專有的。其它Linux發行版或許有相應的命令。這是個很方便的實用程序。具體情況請看幫助:man mkinitrd下面的命令創建initrd映象文件。
?最后生成的內核鏡象有兩種zImage以及uImage。其中zImage下載到目標板中后,可以直接用uboot的命令go來進行直接跳轉。這時候內核直接解壓啟動。但是無法掛載文件系統,因為go命令沒有將內核需要的相關的啟動參數傳遞給內核。傳遞啟動參數我們必須使用命令bootm來進行跳轉。Bootm命令跳轉只處理uImage的鏡象。
uboot源代碼的tools/目錄下有mkimage工具,這個工具可以用來制作不壓縮或者壓縮的多種可啟動映象文件。
mkimage在制作映象文件的時候,是在原來的可執行映象文件的前面加上一個0x40字節的頭,記錄參數所指定的信息,這樣uboot才能識別這個映象是針對哪個CPU體系結構的,哪個OS的,哪種類型,加載內存中的哪個位置, 入口點在內存的那個位置以及映象名是什么
用法如下:
./mkimage -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image
-A ==> set architecture to 'arch'
-O ==> set operating system to 'os'
-T ==> set image type to 'type'
-C ==> set compression type 'comp'
-a ==> set load address to 'addr' (hex)
-e ==> set entry point to 'ep' (hex)
-n ==> set image name to 'name'
-d ==> use image data from 'datafile'
-x ==> set XIP (execute in place)
參數說明:
-A 指定CPU的體系結構:
取值 表示的體系結構
alpha Alpha?
arm A RM?
x86 Intel x86
ia64 IA64
mips MIPS
mips64 MIPS 64 Bit
ppc PowerPC
s390 IBM S390
sh SuperH
sparc SPARC
sparc64 SPARC 64 Bit
m68k MC68000
-O 指定操作系統類型,可以取以下值:
openbsd、netbsd、freebsd、4_4bsd、linux、svr4、esix、solaris、irix、sco、dell、ncr、lynxos、vxworks、psos、qnx、u-boot、rtems、artos
?-T 指定映象類型,可以取以下值:
standalone、kernel、ramdisk、multi、firmware、script、filesystem
-C 指定映象壓縮方式,可以取以下值:
none 不壓縮
gzip 用gzip的壓縮方式
bzip2 用bzip2的壓縮方式
?-a 指定映象在內存中的加載地址,映象下載到內存中時,要按照用mkimage制作映象時,這個參數所指定的地址值來下載
?-e 指定映象運行的入口點地址,這個地址就是-a參數指定的值加上0x40(因為前面有個mkimage添加的0x40個字節的頭)
-n 指定映象名
?
-d 指定制作映象的源文件
我在編譯時用到的命令如下:
# make zImage ? ? ?//生成zImage鏡象
#/usr/local/arm/k9uboot/tools/mkimage -n 'Linux 2.4.27' -A arm -O linux -T
kernel -C none -a 0x20007fc0 -e 0x20008000 -d zImage uImage
內核鏡象已經準備好了,這個時候我們就要來準備文件系統了。由于時間緣故,本人暫時采用的是其他人已經好的文件系統k9.img.gz。這個時候我們要做的是,自己寫一個簡單hello.c的程序,編譯通過后加入到該文件系統中,然后下載到目標板中運行。
先編寫hello.c;
編譯:
#/usr/local/arm/2.95.3/bin/arm-linux-gcc ?–o start-hello hello.c
編譯后生成可執行文件start-hello
下面我們就必須把該執行文件加入到文件系統中去,步驟如下:
#gunzip ?k9.img.gz ? ? ? ? ? ? ? ? ? ? //解壓縮
#mount –o loop k9.img ?/mnt/new_disk ? ?//掛載
#cp start-hello ?/mnt/new_disk ? ? ? ? ? //將文件拷貝到文件系統中
#cd ?/mnt/new_disk
#umount /mnt/new_disk ? ? ? ? ? ? ? ? //卸載
#gzip –c –v9 k9.img > k9.img.gz ? ? ? ? ?//壓縮 生成最終的文件系統
下面我們就要下載內核以及準備好文件系統了,這邊先說明我的內存分配情況如下:
Flash:
0x10000000 ――― 0x10020000 ? ? boot
0x10020000 ――― 0x10040000 ? ? uboot
0x10040000 ――― 0x10060000 ? ? uboot env
0x10060000 ――― 0x10200000 ? ? kernel
0x10200000 ――― 0x11000000 ? ? ramdisk
?
Sdram:
0x20007fc0 ――― 0x20a00000 ? ? kernel
0x20a00000 ――― ? ? ? ? ? ? ? ?ramdisk
?Loadb ?通過串口下載數據到ram中
cp.b ? ?拷貝ram中的數據到flash中。
?將kernel以及文件系統ramdisk下載完畢之后,我們還需要設置uboot的環境變量,這樣uboot才能夠在上電啟動的時候啟動內核等操作。環境變量設置如下:
Set cpfltoram cp.b 10200000 20a00000 18ffff ? ? ? ? ? ?//拷貝文件系統到ram中
Set boot bootm 20007fc0 ? ? ? ? ? ? ? ? ? ? ? ? ? ?//啟動kernel
Set bootcmd run cpfltoker\;run cpfltoram\;run boot ? ? ? //uboot復位的執行指令
?Set cpfltoker cp.b 10060000 20007fc0 f4fff ? ? ? ? ? ? //拷貝內核到ram中
Set bootargs root=/dev/ram rw initrd=0x20a00000,4M init=/linuxrc console=ttyS0,11520
0,mem=32m ? ?//uboot傳遞給內核的啟動參數
對于Linux內核,編譯可以生成不同格式的映像文件,例如:
# make zImage
# make uImage
? ? zImage是ARM Linux常用的一種壓縮映像文件,uImage是U-boot專用的映像文件,它是在zImage之前加上一個長度為0x40的“頭”,說明這個映像文件的類型、加載位置、生成時間、大小等信息。換句話說,如果直接從uImage的0x40位置開始執行,zImage和uImage沒有任何區別。另外,Linux2.4內核不支持uImage,Linux2.6內核加入了很多對嵌入式系統的支持,但是uImage的生成也需要設置。
vmlinux ?編譯出來的最原始的內核文件,未壓縮。
zImage ? 是vmlinux經過gzip壓縮后的文件。
bzImage bz表示“big zImage”,不是用bzip2壓縮的。兩者的不同之處在于,zImage解壓縮內核到低端內存(第一個640K),bzImage解壓縮內核到高端內存(1M以上)。如果內核比較小,那么采用zImage或bzImage都行,如果比較大應該用bzImage。
uImage ? U-boot專用的映像文件,它是在zImage之前加上一個長度為0x40的tag。
vmlinuz ?是bzImage/zImage文件的拷貝或指向bzImage/zImage的鏈接。
initrd ? 是“initial ramdisk”的簡寫。一般被用來臨時的引導硬件到實際內核vmlinuz能夠接管并繼續引導的狀態。
vmlinux是內核文件,
zImage是一般情況下默認的壓縮內核映像文件,壓縮vmlinux,加上一段解壓啟動代碼得到,只能從0X0地址運行。
bzImage在uClinux中很少見到。
uImage是u-boot使用bootm命令引導的Linux壓縮內核映像文件格式,
使用工具mkimage對普通的壓縮內核映像文件(zImage)加工而得。可以由bootm命令從任意地址解壓啟動內核。
由于bootloader一般要占用0X0地址,所以,uImage相比zImage的好處就是可以和bootloader共存。
制作uImage的mkimage軟件,如果uClinux-dist有的話,一般放在uClinux-dist的tools目錄中。