Uboot啟動內核命令詳解
接下來我們來看一下uboot中的核心功能,也就是說我們uboot最終目的是幹什麼的,就是啟動載入內核。那麼怎麼載入內核,其實我們的uboot給我們提供的兩種方案。第一種方案就是uboot本身自帶的叫做bootm的命令。這個叫做bootm的命令主要目的就是為了啟動,當然,等一下我們會簡單說一下bootm他啟動內核稍微要在內核里做一些手腳。然後還有一個命令叫做go命令,go命令顧名思義就是說把這個程序的PC指針指到一個地方,他就能運行起來,比如說我們之前假設有一款內核,然後把內核放到一個地方,然後我找到那個地方就讓PC直接從內核中開始運行,相當於吧uboot的主動權交到了內核空間,因為把PC已經指過去了。
那麼這樣是不是就可以啟動內核了?這些疑問我們一起來驗證一下。首先要想啟動內核還是要有一個內核的原文件。
如圖,這個原文件我們在這個地方已經給大家編譯好了叫「uImage」說到這,我們先簡單的提一下,因為我們會在後面單獨提內核是如何編譯的。內核中的名字,一般來說,主要分這麼幾個一個叫做uimage就是我們現在看到的,還有一個叫做zimge,還可能聽過image也還可能聽過bzimage。就說這些,不管是什麼樣的image最終來說就是內核給我們運行到開發板上的可執行文件。
這個文件主要的問題就是格式不一樣。內部來說,大量的代碼都是相同的,只是前面有些頭格式不太一致,其中在我們後面三個,zimge、image、bzimage這三個都可以稱之為內核的最原始的數據包,而這個uimage最特殊。是我們專門針對uboot在我們內核原始數據前提之下加了一個關於uboot的頭。
如何理解看下圖:
如圖,我們後面會看到一個具體腳本怎麼去製作這些東西,但是我們現在要有一個認識就是說image、bzimage其實都可以認為是一塊東西(如圖中內部的四邊形)只是說它可能數據壓縮的格式不太一致,最終反應就是內核,這些內核按理說直接跳過去就可以執行,但是在uboot中有一個新的用法也就是他們自己的規範,就是說一定要再這樣的數據中再加一個頭(如圖中的橢圓)而這個頭按照我們特殊的格式其實就是uboot中特定的格式(橢圓中的長方形)然後組合成的這樣一個大文件(圖中最大的四邊形)我們就把它稱之為叫uimage,所以說uimage是一個比較特殊的數據包,這個數據包既包含內核中真正數據包,同時又包含跟uboot之間銜接的一些小數據。
下面我們就來嘗試一下把這個uimage給下載下來。就下載我們的開發板上,然後去用go命令指過去運行看看行不行。
如圖,我們先輸入命令「tftp 2000080000 uImage」有些同學會說為什麼不先是8000而是20000,這個在我們之後看內核就會知道要有一個偏移,這個偏移其主要目的就是為了我們在內存管理中建立一定的內存單元管理的表。這個表一般來說都會預留這樣一段空間。所以這個空間我們在實際的物理內存中也應該預留出來,這樣在啟動的時候才不會出現一些特殊或者奇怪的問題。然後點擊回車鍵,這個時候已經下載完成。
我們輸入命令「go 2000080000」這個時候你就會發現,其實這個程序是死掉了,原因就是這個go命令只是把指針指到20008000,而真正的,一旦指下去就有幾個毛病,第一個uimage本身來說最開始並不是代碼,而是uboot中的一些數據信息,所以它不具備可執行能力,一旦執行肯定跑飛。第二個就是我們必須要用bootm命令去把前面的頭信息給解析出來然後再去啟動,所以這是我們要注意的go命令天生是啟動不了內核的。
原因就在於等一下我會重點給大家講的內核啟動條件,內核啟動,並不是大家所想像的直接啟動的可執行的東西。並不是你直接把PC指針一指過去它就開始運行的,內核啟動是需要一定的前提條件,要不然他要uboot幹什麼。
如圖,所以說這是我們需要關心的一個問題,那麼下面我們再來測試一下,在測試之前,我還要做一件事情就是我之前做實驗的時候因為懶得每次都敲所以已經把bootargs和bootcmd這兩個命令寫死了。那麼下面我們輸入命令「setenv bootargs」把這個環境變數刪掉,然後在把它保存一下。
如圖,我們就會發現其實已經沒有那個選項了。然後我們在輸入命令「tftp 20008000 uImage」下載下來。
如圖,因為剛才說了go命令不行那麼我們輸入命令「bootm 20008000」然後點擊回車鍵,我們會發現這個時候有一個新的問題,出來的代碼變得很奇怪,如果以後你用代碼去調然後你會發現還是在uboot中,內核還沒有真正起來。
所以總的來說,bootm和go命令只是啟動內核的一個條件而已,也就是說它只能把PC指過去讓他開始運行,真正想啟動內核我們還需要一個非常重要的條件就是剛才我們刪掉的環境變數叫bootargs,也就是說內核啟動條件中有一個非常重要的環境叫bootargs,這個環境變數來充當了uboot跟內核數據銜接的一個過程,怎麼理解這句話呢?讓我們來思考一下。
我們可以這樣想uboot是一個人內核也是一個人,這樣的話uboot最終要啟動內核的時候要告訴內核應該以什麼樣的方式啟動,我們這個開發板中我們什麼是輸出,這樣我們才能把相應的一些內核的啟動或者環境交給內核去處理。
所以說我們現在看不到任何列印信息的主要原因就是uboot並沒有告訴內核你該如何去工作。
因為之前uboot會有這樣一些信息,我們需要把這些信息通過bootargs這樣環境變數的參數告知給內核,這樣內核就可以根據這個參數知道它要做些什麼事情了。
原文鏈接:嵌入式系統移植
推薦閱讀:
※要認識嵌入式Linux,看這一篇就夠了
※物聯網嵌入式應用已經滲透到我們生活的方方面面
※RTOS移植與naked選項的使用-2_實際效果與擴展閱讀
※精簡封裝技巧6---- 『:』 關鍵詞的用法
※Linux 每個目錄用途說明