其實在上一篇隨筆以前,就是在啓動linux 內核的時候,出了點問題html
剛Starting kernel ...就出現了undefined instrction,這是什麼問題呢?linux
在網上也搜了很多資料,有兩篇頗有啓發spa
http://www.latelee.org/porting-uboot/u-boot-porting-booting-kernel.html.net
http://blog.csdn.net/liangkaiming/article/details/5986680htm
就是這兩篇。blog
咱們先來了解下mkimage這個命令,重要關注loadaddress和entry address圖片
./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)it
mkimage是將zImage以前加上64字節的鏡像頭io
因此若是使用mkimage生成內核鏡像文件的話,會在內核的前頭加上了64byte的信息,供創建tag之用。bootm命令會首先判斷bootm xxxx 這個指定的地址xxxx是否與-a指定的加載地址是否相同。
(1)若是不一樣的話會從這個地址開始提取出這個64byte的頭部,對其進行分析,而後把去掉頭部的內核複製到-a指定的load地址中去運行之
(2)若是相同的話那就讓其原封不一樣的放在那,但-e指定的入口地址會推後64byte,以跳過這64byte的頭部。class
咱們來看看這三個地址的不一樣狀況:
1> mkimage -A arm -O linux -T kernel -C none -a 30008000 -e
30008040 -n linux-2.6.18.8 -d zImage uImage2.6.18.8-8040
這種狀況 ,只能把 uImage download到 30008000的位置上,不然 從 30008040
是啓動不了的。
緣由:若是將uImage(加了頭的鏡像文件)下載到不一樣於指定加載地址的地方,則會進行上面的操做,將去掉頭部的內核拷貝到指定的加載地址,此時加載地址和入口地址須要是相同的,由於已經沒有鏡像頭了,因此此時入口地址也應該爲30008000,而不該該再加上64個字節
因此在構建鏡像頭部中的加載地址和入口地址時千萬要考慮下載的地址,不然將會啓動不了。
2> 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-8000
這種狀況download地址隨便。 仍是按上面說的,由於將加載地址和入口地址設置成一樣的地址,在下載到任意地址時,將去掉頭部的內核鏡像拷貝到指定加載地址後,能夠直接從加載地址開始啓動。可是要是下載地址和指定加載地址相同呢?也就是下面的:
若是 tftp 下載地址==0x30008000 , 此時由於下載地址和指定加載地址相同,因此就不會搬動,內核直接從指定加載地址自解壓啦,可是由於指定的入口地址也是0x30008000,仍是在鏡像頭處,能夠看到上面的代碼,若是相同沒有作任何事,只是打印了提示信息,因此還得將入口地址日後推後64個字節仍是從 0x30008040 啓動就確定OK 。
因此在製做鏡像頭以及下載地址就有兩種狀況:
1,mkimage -n 'linux-2.6.14' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage zImage.img
加載地址和入口地址相同
tftp 0x31000000 zImage.img
bootm 0x31000000
下載地址能夠任意放。
2,mkimage -n 'linux-2.6.14' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage zImage.img
入口地址在加載地址後面64個字節
tftp 0x30008000 zImage.img
bootm 0x30008000
下載地址必定要在指定的加載地址上。
因此,我在製做鏡像頭的時候沒有本身動手製做,而是make uImage ARCH=arm CROSS_COMPILE=arm-linux-直接一步到位,因此啓動的時候應該在0x30008040的位置啓動!
看到這個圖片仍是很高興的!!!