通常,u-boot為kernel提供一些kernel無法知道的資訊,比如ramdisk在RAM中的地址。Kernel也必須為U-boot提供必要的資訊,如通過mkimage這個工具(在u-boot代碼的tools目錄中)可以給zImage添加一個header,也就是使得通常編譯的核心zImage添加一個資料頭,把添加頭後的image通常叫uImage,uImage是可以被U-boot直接引導的核心鏡像。那麼如何使用mkimage工具而產生uImage的呢?下面將具體介紹mkimage工具的使用:
1.首先查看mkimage的命令參數
[root@localhost tools]# ./mkimage
Usage: ./mkimage -l image
-l ==> list image header information
./mkimage [-x] -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' //用於指定CPU類型,比如ARM
-O ==> set operating system to 'os' //用於指定作業系統,比如Linux
-T ==> set image type to 'type' //用於指定image類型,比如Kernel
-C ==> set compression type 'comp' //指定壓縮類型
-a ==> set load address to 'addr' (hex) //指定image的載入地址
-e ==> set entry point to 'ep' (hex) //核心的入口地址,一般是:image的載入地址+0x40(資訊頭的大小)
-n ==> set image name to 'name' //image在頭結構中的命名
-d ==> use image data from 'datafile' //無頭資訊的image檔案名稱
-x ==> set XIP (execute in place) //設定執行位置
-a參數後是核心的運行地址,-e參數後是入口地址。
1)如果我們沒用mkimage對核心進行處理的話,那直接把核心下載到0x30008000再運行就行,核心會自解壓運行(不過核心運行需要一個tag來傳遞參數,而這個tag建議是由bootloader提供的,在u-boot下預設是由bootm命令建立的)。
2)如果使用mkimage產生核心鏡像檔案的話,會在核心的前頭加上了64byte的資訊,供建立tag之用。bootm命令會首先判斷bootm xxxx 這個指定的地址xxxx是否與-a指定的載入地址相同。
(1)如果不同的話會從這個地址開始提取出這個64byte的頭部,對其進行分析,然後把去迴轉部的核心複製到-a指定的load地址中去運行之
(2)如果相同的話那就讓其原封不同的放在那,但-e指定的入口地址會推後64byte,以跳過這64byte的頭部。
000000_u-boot-1.2.0/tools/ ./mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 30008000 -n linux-2.6.14.1_cs8900 -d /arm9/u-boot-1.2.0/tools/zImage /arm9/u-boot-1.2.0/tools/uImage
or :./mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 30008040 -n linux-2.6.13 -d zImage uImage
稍微總結了一下, 怕忘了, :
產生uImage的方法: 利用mkimage 命令 把zImage 封裝 ,
mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 30008000 -n linux-2.6.18.8 -d zImage uImage2.6.18.8
下面的總結都是 稍微調整一下上面的 -a -e -x 參數什麼的, 你會發現 這些參數不同, 就會導致你 tftp dowload的地址會有不同, 有的時候kernel會run不起來。
addr是地址 , 如果兩個地方都是addr ,說明是同一個地址, 否則 我會比如addr+0x40 的
具體為什麼 , 可以看我上面文章的分析:
1> mkimage -a addr -e addr
那麼tftp 下載kernel 就一定不能下載 addr處 , 否則,kernel不來。 因為u-boot並不搬運kernel 代碼, 也就是沒有把header去掉。 所以 只有入口是 addr+0x40才是kernel的入口。
當然也不能下到 < addr + 2M 的地方, 否則搬運的時候會有一些覆蓋, 導致搬運後的kernel不完整, bootm的時候,會RESET 的。
2> mkimage -a addr -e addr+0x40 或者 mkimage -a addr -x 兩個是一回事 。 -x的意思 是就在kernel所在地執行。 不必搬運(代碼裡面的條件是 tftp 下kernel的時候 就下到 addr處)
這種情況: tftp 就一定把kernel 下載到addr處 ,這樣u-boot 在bootm的時候 就不搬運了。
起始這種情況更多的用在flash裡面 。
比如 賣產品的時候 ,kernel肯定是燒寫在flash裡面, 記住這個flash地址, 然後 mkimage -a 這個flash地址 -x , 這樣bootm 也就不用搬運了, 直接在flash裡面運行kernel 。 其實我不曉得這樣可不可以, 按理說編譯 kernel的時候,link的時候 用的 vmlinux.lds 裡面的數值 都是 0x30008000 , mkimage 隨便指定一個flash 地址, 應該不行才對, 除非你把 kernel裡面的vmlinux.lds 也改掉和mkimage一致。
總之 , 一句話, u-boot 是為kernel服務, kernel裡面定義好的參數, u-boot 不能亂改 , 一定要一致 ,否則kernel肯定翹辮子才對。
通常,u-boot為kernel提供一些kernel無法知道的資訊,比如ramdisk在RAM中的地址。Kernel也必須為U-boot提供必要的資訊,如通過mkimage這個工具(在u-boot代碼的tools目錄中)可以給zImage添加一個header,也就是使得通常編譯的核心zImage添加一個資料頭,把添加頭後的image通常叫uImage,uImage是可以被U-boot直接引導的核心鏡像。那麼如何使用mkimage工具而產生uImage的呢?下面將具體介紹mkimage工具的使用:
1.首先查看mkimage的命令參數
[root@localhost tools]# ./mkimage
Usage: ./mkimage -l image
-l ==> list image header information
./mkimage [-x] -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' //用於指定CPU類型,比如ARM
-O ==> set operating system to 'os' //用於指定作業系統,比如Linux
-T ==> set image type to 'type' //用於指定image類型,比如Kernel
-C ==> set compression type 'comp' //指定壓縮類型
-a ==> set load address to 'addr' (hex) //指定image的載入地址
-e ==> set entry point to 'ep' (hex) //核心的入口地址,一般是:image的載入地址+0x40(資訊頭的大小)
-n ==> set image name to 'name' //image在頭結構中的命名
-d ==> use image data from 'datafile' //無頭資訊的image檔案名稱
-x ==> set XIP (execute in place) //設定執行位置
-a參數後是核心的運行地址,-e參數後是入口地址。
1)如果我們沒用mkimage對核心進行處理的話,那直接把核心下載到0x30008000再運行就行,核心會自解壓運行(不過核心運行需要一個tag來傳遞參數,而這個tag建議是由bootloader提供的,在u-boot下預設是由bootm命令建立的)。
2)如果使用mkimage產生核心鏡像檔案的話,會在核心的前頭加上了64byte的資訊,供建立tag之用。bootm命令會首先判斷bootm xxxx 這個指定的地址xxxx是否與-a指定的載入地址相同。
(1)如果不同的話會從這個地址開始提取出這個64byte的頭部,對其進行分析,然後把去迴轉部的核心複製到-a指定的load地址中去運行之
(2)如果相同的話那就讓其原封不同的放在那,但-e指定的入口地址會推後64byte,以跳過這64byte的頭部。
000000_u-boot-1.2.0/tools/ ./mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 30008000 -n linux-2.6.14.1_cs8900 -d /arm9/u-boot-1.2.0/tools/zImage /arm9/u-boot-1.2.0/tools/uImage
or :./mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 30008040 -n linux-2.6.13 -d zImage uImage
稍微總結了一下, 怕忘了, :
產生uImage的方法: 利用mkimage 命令 把zImage 封裝 ,
mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 30008000 -n linux-2.6.18.8 -d zImage uImage2.6.18.8
下面的總結都是 稍微調整一下上面的 -a -e -x 參數什麼的, 你會發現 這些參數不同, 就會導致你 tftp dowload的地址會有不同, 有的時候kernel會run不起來。
addr是地址 , 如果兩個地方都是addr ,說明是同一個地址, 否則 我會比如addr+0x40 的
具體為什麼 , 可以看我上面文章的分析:
1> mkimage -a addr -e addr
那麼tftp 下載kernel 就一定不能下載 addr處 , 否則,kernel不來。 因為u-boot並不搬運kernel 代碼, 也就是沒有把header去掉。 所以 只有入口是 addr+0x40才是kernel的入口。
當然也不能下到 < addr + 2M 的地方, 否則搬運的時候會有一些覆蓋, 導致搬運後的kernel不完整, bootm的時候,會RESET 的。
2> mkimage -a addr -e addr+0x40 或者 mkimage -a addr -x 兩個是一回事 。 -x的意思 是就在kernel所在地執行。 不必搬運(代碼裡面的條件是 tftp 下kernel的時候 就下到 addr處)
這種情況: tftp 就一定把kernel 下載到addr處 ,這樣u-boot 在bootm的時候 就不搬運了。
起始這種情況更多的用在flash裡面 。
比如 賣產品的時候 ,kernel肯定是燒寫在flash裡面, 記住這個flash地址, 然後 mkimage -a 這個flash地址 -x , 這樣bootm 也就不用搬運了, 直接在flash裡面運行kernel 。 其實我不曉得這樣可不可以, 按理說編譯 kernel的時候,link的時候 用的 vmlinux.lds 裡面的數值 都是 0x30008000 , mkimage 隨便指定一個flash 地址, 應該不行才對, 除非你把 kernel裡面的vmlinux.lds 也改掉和mkimage一致。
總之 , 一句話, u-boot 是為kernel服務, kernel裡面定義好的參數, u-boot 不能亂改 , 一定要一致 ,否則kernel肯定翹辮子才對。