「正點原子Linux連載」第三十九章系統燒寫

2020-12-06 正點原子

前面我們已經移植好了uboot和linuxkernle,製作好了根文件系統。但是我們移植都是通過網絡來測試的,在實際的產品開發中肯定不可能通過網絡來運行,否則沒網的時候產品豈不是就歇菜了。因此我們需要將uboot、linuxkernel、.dtb(設備樹)和rootfs這四個文件燒寫到板子上的EMMC、NAND或QSPI Flash等其他存儲設備上,這樣不管有沒有網絡我們的產品都可以正常運行。本章我們就來學習一下如何使用NXP官方提供的MfgTool工具通過USB OTG口來燒寫系統。

39.1 MfgTool工具簡介

MfgTool工具是NXP提供的專門用於給I.MX系列CPU燒寫系統的軟體,可以在NXP官網下載到。此工具已經放到了開發板光碟中,路勁為:5、開發工具->3、NXP官方原版MFG_TOOL燒寫工具->L4.1.15_2.0.0-ga_mfg-tools.tar.gz。此軟體在Windows下使用,對於我們來說太友好了。將此壓縮包進行解壓,解壓完成以後會出現一個名為L4.1.15_2.0.0-ga_mfg-tools的文件夾,進入此文件夾,此文件夾的內容如圖39.1.1所示:

圖39.1.1 mfg_tools工具目錄

從圖39.1.1可以看出,有兩個.txt文件和兩個.gz壓縮包。.txt文檔就不去看了,重點是這兩個.gz壓縮包,這兩個壓縮包的區別在名字上已經寫的很詳細了。"without-rootfs"和"with-rootfs",一個是帶rootfs和一個是不帶rootfs。mfg_tools這個工具本意是給NXP自己的開發板設計的燒寫軟體,所以肯定帶有自家開發板對應的uboot、linuxkernel和rootfs的文件。我們肯定是要燒寫文件系統的,所以選擇mfgtools-with-rootfs.tar.gz這個壓縮包,繼續對其解壓,解壓出一個名為mfgtools-with-rootfs的文件夾,此文件夾就包含有我們需要的燒寫工具。

進入目錄mfgtools-with-rootfs\mfgtools中,在此目錄下有幾個文件夾和很多的.vbs文件,如圖39.1.2所示:

圖39.1.2 mfgtools目錄內容

我們只關心圖39.1.2中Profiles這個文件夾,因為後面要燒寫文件就放到這個文件夾中。MfgTool2.exe就是燒寫軟體,但是我們不會直接打開這個軟體燒寫,mfg_tools不僅能燒寫I.MX6U,而且也能給I.MX7、I.MX6Q等晶片燒寫,所以在燒寫之前必須要進行配置,指定燒寫的是什麼晶片,燒寫到哪裡去?下面的這些眾多的.vbs文件就是配置腳本,燒寫的時候通過雙擊這些.vbs文件來打開燒寫工具。這些.vbs燒寫腳本既可以根據處理器的不同,由用戶選擇向I.MX6D、I.MX6Q、I.MX6S、I.MX7、I.MX6UL和I.MX6ULL等的哪一款晶片燒寫系統。也可以根據存儲晶片的不同,選擇向EMMC、NAND或QSPI Flash等的哪一種存儲設備燒寫,功能非常強大!!我們現在需要向I.MX6U燒寫系統,因此需要參考表39.1.1所示的5個燒寫腳本:

表39.1.1 I.MX6U使用的燒寫腳本

其他的.vbs燒寫腳本用不到,因此可以刪除掉,防止幹擾我們的視線。本書用的是正點原子的EMMC版核心板,因此只會用到mfgtool2-yocto-mx-evk-emmc.vbs這個燒寫腳本,如果用其他的核心板請參考相應的燒寫腳本。

39.2 MfgTool工作原理簡介

MfgTool只是個工具,具體的原理不需要去深入研究,大概來了解一下其工作原理就行了,知道它的工作流程就行了。

39.2.1 燒寫方式

1、連接USB線

MfgTool是通過USB OTG接口將系統燒寫進EMMC中的,正點原子I.MX6U-ALPHA開發板上的USB OTG口如圖39.2.1.1所示:

圖39.2.2.1 USB OTG1接口

在燒寫之前,需要先用USB線將圖39.2.2.1中的USB_OTG1接口與電腦連接起來。

2、撥碼開關撥到USB下載模式

將圖39.2.2.1中的撥碼開關撥到"USB"模式,如圖39.2.2.2所示:

圖39.2.2.2 USB下載模式

如果插了TF卡,請彈出TF卡,否則電腦不能識別USB!等識別出來以後再插上TF卡!

如果插了TF卡,請彈出TF卡,否則電腦不能識別USB!等識別出來以後再插上TF卡!

如果插了TF卡,請彈出TF卡,否則電腦不能識別USB!等識別出來以後再插上TF卡!

一切準備就緒以後,按一下開發板的復位鍵,此時就會進入到USB模式,如果是第一次進入USB模式的話可能會久一點,這個是免驅的,因此不需要安裝驅動。第一次進入USB模式會在電腦右下角有如圖39.2.2.3所示提示:

圖39.2.2.3 第一次進入USB模式

一旦第一次設置好設備以後,後面每次連接都不會有任何提示了。到這裡,我們的開發板已經和電腦連接好了,可以開始燒寫系統了。

39.2.2 系統燒寫原理

開發板連接電腦以後雙擊"mfgtool2-yocto-mx-evk-emmc.vbs",打開下載對話框,如圖39.2.2.1所示:

圖39.2.2.1 MfgTool工具界面

如果出現"符合 HID 標準的供應商定義設備"就說明連接正常,可以進行燒寫,如果出現其他的字符那麼就要檢查連接是否正確。點擊"Start"按鈕即可開始燒寫,燒寫什麼東西呢?肯定是燒寫uboot、Linuxkernel、.dtb和rootfs,那麼這四個應該放到哪裡MfgTool才能訪問到呢?進入如下目錄中:

L4.1.15_2.0.0-ga_mfg-tools/mfgtools-with-rootfs/mfgtools/Profiles/Linux/OS Firmware

此目錄中的文件如圖39.2.2.2所示:

圖39.2.2.2 OS Firmware文件夾內容

文件夾"OS Firmware"看名字就知道是存放系統固件的,我們重點關注files、firmware這兩個文件夾,以及ucl2.xml這個文件。在具體看這三個文件和文件夾之前,我們先來簡單了解一下MfgTool燒寫的原理,MfgTool其實是先通過USB OTG先將uboot、kernel和.dtb(設備樹)這是三個文件下載到開發板的DDR中,注意不需要下載rootfs。就相當於直接在開發板的DDR上啟動Linux系統,等Linux系統啟動以後再向EMMC中燒寫完整的系統,包括uboot、linuxkernel、.dtb(設備樹)和rootfs,因此MfgTool工作過程主要分兩個階段:

①、將firmware目錄中的uboot、linuxkernel和.dtb(設備樹),然後通過USB OTG將這個文件下載到開發板的DDR中,目的就是在DDR中啟動Linux系統,為後面的燒寫做準備。

②、經過第①步的操作,此時Linux系統已經運行起來了,系統運行起來以後就可以很方便的完成對EMMC的格式化、分區等操作。EMMC分區建立好以後就可以從firmware中讀取要燒寫的uboot、linux kernel、.dtb(設備樹)和rootfs這4個文件,然後將其燒寫到EMMC中,這個就是MfgTool的大概工作流程。

1、firmeare文件夾

打開firmware文件夾,裡面有很多的.imx結尾的uboot文件、一個zImage鏡像文件、很多.dtb結尾的設備樹文件。這些文件都是NXP官方開發板使用的,不同的板子使用不同的文件,其中我們需要關心的只有表39.2.2.1中的這三個文件:

表39.2.2.1 I.MX6ULL EVK開發板使用的系統文件

表39.2.2.1中的這三個文件就是I.MX6ULL EVK開發板燒寫系統的時候第一階段所需的文件。如果要燒寫我們的系統,就需要用我們編譯出來的zImage、u-boot.imx和imx6ull-alientek-emmc.dtb這三個文件替換掉表39.2.2.1中這三個文件。但是名字要和表39.2.2.1中的一致,因此需要將u-boot.imx重命名為u-boot-imx6ull14x14evk_emmc.imx,將imx6ull-alientek-emmc.dtb重命名為zImage-imx6ull-14x14-evk-emmc.dtb。

2、files文件夾

將表39.2.2.1中的這三個文件下載到開發板的DDR上以後燒寫的第一階段就完成了,第二階段就是從files目錄中讀取整個系統文件,並將其燒寫到EMMC中。files目錄中的文件和firmware目錄中的基本差不多,都是不同板子對應的uboot、設備樹文件,同樣,我們只關心表39.2.2.2中的四個文件:

表39.2.2.2 I.MX6ULL EVK開發板燒寫文件

如果要燒寫我們自己編譯出來的系統,就需要用我們編譯出來的zImage、u-boot.imx和imx6ull-alientek-emmc.dtb和rootfs這四個文件替換掉表39.2.2.2中這四個文件。

3、ucl2.xml文件

files和firmware目錄下有眾多的uboot和設備樹,那麼燒寫的時候究竟選擇哪一個呢?這個工作就是由ucl2.xml文件來完成的。ucl2.xml以"<UCL>"開始,以"</UCL>"結束。"<CFG>"和"</CFG>"之間是配置相關內容,主要是判斷當前是給I.MX系列的哪個晶片燒寫系統。"<LIST>"和"</LIST>"之間的是針對不同存儲晶片的燒寫命令。整體框架如下:

示例代碼39.2.2.1 ucl2.xml框架

<UCL>

<CFG>

......

<!-- 判斷向I.MX系列的哪個晶片燒寫系統 -->

......

</CFG>

<LISTname="SDCard"desc="Choose SD Card as media">

<!-- 向SD卡燒寫Linux系統 -->

</LIST>

<LISTname="eMMC"desc="Choose eMMC as media">

<!-- 向EMMC燒寫Linux系統 -->

</LIST>

<LISTname="Nor Flash"desc="Choose Nor flash as media">

<!-- 向Nor Flash燒寫Linux系統 -->

</LIST>

<LISTname="Quad Nor Flash"desc="Choose Quad Nor flash as media">

<!-- 向Quad Nor Flash燒寫Linux系統 -->

</LIST>

<LISTname="NAND Flash"desc="Choose NAND as media">

<!-- 向NAND Flash燒寫Linux系統 -->

</LIST>

<LISTname="SDCard-Android"desc="Choose SD Card as media">

<!-- 向SD卡燒寫Android系統 -->

</LIST>

<LISTname="eMMC-Android"desc="Choose eMMC as media">

<!-- 向EMMC燒寫Android系統 -->

</LIST>

<LISTname="Nand-Android"desc="Choose NAND as media">

<!-- 向NAND Flash燒寫Android系統 -->

</LIST>

<LISTname="SDCard-Brillo"desc="Choose SD Card as media">

<!-- 向SD卡燒寫Brillo系統 -->

</LIST>

</UCL>

ucl2.xml首先會判斷當前要向I.MX系列的哪個晶片燒寫系統,代碼如下:

示例代碼39.2.2.2 判斷要燒寫的處理器型號

21<CFG>

22<STATEname="BootStrap"dev="MX6SL"vid="15A2"pid="0063"/>

23<STATEname="BootStrap"dev="MX6D"vid="15A2"pid="0061"/>

24<STATEname="BootStrap"dev="MX6Q"vid="15A2"pid="0054"/>

25<STATEname="BootStrap"dev="MX6SX"vid="15A2"pid="0071"/>

26<STATEname="BootStrap"dev="MX6UL"vid="15A2"pid="007D"/>

27<STATEname="BootStrap"dev="MX7D"vid="15A2"pid="0076"/>

28<STATEname="BootStrap"dev="MX6ULL"vid="15A2"pid="0080"/>

29<STATEname="Updater"dev="MSC"vid="066F"pid="37FF"/>

30</CFG>

通過讀取晶片的VID和PID即可判斷出當前要燒寫什麼處理器的系統,如果VID=0X15A2,PID=0080,那麼就表示要給I.MX6ULL燒寫系統。確定了處理器以後就要確定向什麼存儲設備燒寫系統,這個時候就要有請mfgtool2-yocto-mx-evk-emmc.vbs再次登場,此文件內容如下:

示例代碼39.2.2.3 mfgtool2-yocto-mx-evk-emmc.vbs文件內容

Set wshShell =CreateObject("WScript.shell")

wshShell.run "mfgtool2.exe -c ""linux"" -l ""eMMC"" -s ""board=sabresd"" -s ""mmc=1"" -s ""6uluboot=14x14evk"" -s ""6uldtb=14x14-evk"""

Set wshShell =Nothing

重點是"wshShell.run"這一行,這裡一行調用了mfgtool2.exe這個軟體,並且還給出了一堆的參數,其中就有"eMMC"字樣,說明是向EMMC燒寫系統,要燒寫的存儲設備就這樣確定下來了。"wshShell.run"後面還有一堆的其他參數,這些參數都有對應的值,如下所示:

board=sabresd

mmc=1

6uluboot=14x14evk

6uldtb=14x14-evk

我們繼續回到ucl2.xml中,既然現在已經知道了是向I.MX6ULL的EMMC中燒寫系統,那麼直接在ucl2.xml中找到相應的燒寫命令就行了,因為相應的命令太長,為了縮小篇幅,我們就以uboot的燒寫為例講解一下。前面說了燒寫分兩個階段,第一步是通過USB OTG向DDR中下載系統,第二步才是正常的燒寫。通過USB OTG向DDR下載uboot的命令如下:

示例代碼39.2.2.4 通過USB OTG下載uboot

<CMDstate="BootStrap"type="boot"body="BootStrap"file ="firmware/u-boot-imx6ul%lite%%6uluboot%_emmc.imx"ifdev="MX6ULL">Loading U-boot

</CMD>

上面的命令就是BootStrap階段,也就是第一階段,"file"表示要下載的文件位置,在firmware目錄下,文件名字為

u-boot-imx6ul%lite%%6uluboot%_emmc.imx

在L4.1.15_2.0.0-ga_mfg-tools\mfgtools-with-rootfs\mfgtools-with-rootfs\mfgtools下找到cfg.ini文件,該文件裡包含了開發板的一些信息,查看cfg.ini文件可得lite=l以及一些字符串代表的值。

"%lite%"和"%6uluboot%"分別表示取lite和6uluboot的值,而lite=l,6uluboot=14x14evk,因此將這來個值帶進去以後就是:

u-boot-imx6ull14x14evk _emmc.imx

所以,這裡向DDR中下載的是firmware/ u-boot-imx6ull14x14evk _emmc.imx這個uboot文件。同樣的方法將.dtb(設備樹)和zImage都下載到DDR中以後就會跳轉去運行OS,這個時候會在MfgTool工具中會有"Jumpingto OS image"提示語句,ucl2.xml中的跳轉命令如下:

示例代碼39.2.2.5 跳轉到OS

<CMDstate="BootStrap"type="jump">Jumping to OS image. </CMD>

啟動Linux系統以後就可以在EMMC上創建分區,然後燒寫uboot、zImage、.dtb(設備樹)和根文件系統。

這個就是MfgTool的整個燒寫原理,弄懂了燒寫原理以後就可以開始試著先將NXP官方的系統燒寫到正點原子的I.MX6U-ALPHA開發板中。

39.3 燒寫NXP官方系統

我們先試著將NXP官方的系統燒寫到正點原子的I.MX6U-ALPHA開發板中,主要是先熟悉一下燒寫過程。因為正點原子的EMMC核心版用的也是512MB的DDR3加4G的EMMC,因此燒寫NXP官方的系統是沒有任何問題的。燒寫步驟如下:

①、連接好USB,撥碼開關撥到USB下載模式。

②、彈出TF卡,然後按下開發板復位按鍵。

③、打開SecureCRT。

③、雙擊"mfgtool2-yocto-mx-evk-emmc.vbs",打開下載軟體,如果出現"符合 HID 標準的供應商定義設備"等字樣就說明下載軟體已經準備就緒。點擊"Start"按鈕開發燒寫NXP官方系統,燒寫過程如圖39.3.1所示:

圖39.3.1 燒寫過程

這個時候可以在SecurCRT上看到具體的燒寫過程,如圖39.3.2所示:

圖39.3.2 正在燒寫的文件

等待燒寫完成,因為NXP官方的根文件系統比較大,因此燒寫的時候耗時會久一點。燒寫完成以後MfgTool軟體如圖39.3.3所示:

圖39.3.2 燒寫完成

燒寫完成以後點擊"Stop"按鈕停止燒寫,然後點擊"Exit"鍵退出。拔出USB線,將開發板上的撥碼開關撥到EMMC啟動模式,然後重啟開發板,此時就會從EMMC啟動。只是啟動以後的系統是NXP官方給I.MX6ULL EVK開發板製作的,這個系統需要輸入用戶名,用戶名為"root",沒有密碼,如圖39.3.3所示:

圖39.3.3 NXP官方根文件系統

在"imx6ul7d login:"後面輸入"root"用戶名,然後點擊回車鍵即可進入系統中,進入系統以後就可以進行其他操作了。所以說,NXP官方的系統其實是可以在正點原子的EMMC版核心板上運行的。

39.4 燒寫自製的系統

39.4.1 系統燒寫

上一小節我們試著將NXP官方提供的系統燒寫到正點原子的I.MX6U-ALPHA開發板好中,目的是體驗一下通過MfgTool燒寫系統的過程。本小節我們就來學習如何將我們做好的系統燒寫到開發板中,首先是準備好要燒寫的原材料:

①、自己移植編譯出來的uboot可執行文件:u-boot.imx。

②、自己移植編譯出來的zImage鏡像文件和開發板對應的.dtb(設備樹),對於I.MX6U-ALPHA開發板來說就是imx6ull-alientek-emmc.dtb。

③、自己構建的根文件系統rootfs,這裡我們需要對rootfs進行打包,進入到Ubuntu中的rootfs目錄中,然後使用tar命令對其進行打包,命令如下:

cdrootfs/

tar -vcjf rootfs.tar.bz2 *

完成以後會在rootfs目錄下生成一個名為rootfs.tar.bz2的壓縮包,將rootfs.tar.bz2發送到windows系統中。

將上面提到的這4個"原材料"都發送到Windows系統中,如圖39.4.1所示:

圖39.4.1 燒寫原材料

材料準備好以後還不能直接進行燒寫,必須對其進行重命名,否則的話ucl2.xml是識別不出來的,前面講解ucl2.xml語法的時候已經說過了,圖39.4.1中的這四個文件重命名見表39.4.1:

表39.4.1 文件重命名表

完成以後如圖39.4.2所示:

圖39.4.2 重命名以後的文件

接下來就是用我們的文件替換掉NXP官方的文件,先將圖39.4.2中的zImage、u-boot-imx6ull14x14evk_emmc.imx和zImage-imx6ull-14x14-evk-emmc.dtb這三個文件拷貝到mfgtools-with-rootfs/mfgtools/Profiles/Linux/OS Firmware/firmware目錄中,替換掉原來的文件。然後將圖39.4.2中的所有4個文件都拷貝到mfgtools-with-rootfs/mfgtools/Profiles/Linux/OS Firmware/files目錄中,這兩個操作完成以後我們就可以進行燒寫了。

雙擊"mfgtool2-yocto-mx-evk-emmc.vbs",打開燒寫軟體,點擊"Start"按鈕開始燒寫,由於我們自己製作的rootfs比較小,因此燒寫相對來說會快一點。燒寫完成以後設置開發板從EMMC啟動,啟動我們剛剛燒寫進去的系統,測試有沒有問題,一般肯定沒問題,因為這些都是我們已經測試好的。

39.4.2 網絡開機自啟動設置

大家在測試網絡的時候可能會發現網絡不能用,這並不是因為我們將系統燒寫到EMMC中以後網絡壞了。僅僅是因為網絡沒有打開,我們用NFS掛載根文件系統的時候因為要使用NFS服務,因此Linux內核會打開eth0這個網卡,現在我們不使用NFS掛載根文件系統,因此Linux內核也就不會自動打開eth0網卡了。我們可以手動打開網卡,首先輸入"ifconfig-a"命令查看一下eth0和eth1是否都存在,結果如圖39.4.3所示:

圖39.4.3 查看網絡

可以看出eth0好eth1都存在,既然存在我們就打開,以打開eth0網卡為例,輸入如下命令打開eth0:

ifconfig eth0 up

打開網卡的時候會有如圖39.4.4所示的提示信息:

圖39.4.5 打開eth0網卡

打開的時候會提示使用LAN8710/LAN8720的網絡晶片,eth0連接成功,並且是100Mpbs全雙工,eth0連結準備就緒。這個時候輸入"ifconfig"命令就會看到eth0這個網卡,如圖39.4.6所示:

圖39.4.6 當前工作的網卡

接下來就是個eth0設置IP位址,如果你的開發板連接的路由器,那麼可以通過路由器自動分配IP位址,命令如下:

udhcpc -i eth0 //通過路由器分配IP位址

如果你的開發板連接著電腦,那麼就可以手動設置IP位址,比如設置為192.168.1.251,命令如下:

ifconfig eth0 192.168.1.251 netmask 255.255.255.0 //設置IP位址和子網掩碼

routeadddefaultgw 192.168.1.1 //添加默認網關

推薦大家將開發板連接到路由器上,設置好IP位址以後就可以測試網絡了,比如ping一下電腦IP位址,或者ping一下百度官網。

每次開機以後都要自己手動打開網卡,然後手動設置IP位址也太麻煩了,有沒有開機以後自動啟動網卡並且設置IP位址的方法呢?肯定有的,我們將打開網卡,設置網卡IP位址的命令添加到/etc/init.d/rcS文件中就行了,完成以後的rcS文件內容如下所示:

//示例代碼39.4.2.1 網絡開機自啟動

1 #!/bin/sh

2

3 PATH=/sbin:/bin:/usr/sbin:/usr/bin

4 LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib

5 export PATH LD_LIBRARY_PATH runlevel

6

7 #網絡開機自啟動設置

8 ifconfig eth0 up

9 #udhcpc-i eth0

10 ifconfig eth0 192.168.1.251 netmask 255.255.255.0

11 route add defaultgw 192.168.1.1

......

12 #cd /drivers

13 #./hello &

14 #cd /

第8行,打開eth0網卡

第9行,通過路由器自動獲取IP位址。

第10行,手動設置eth0的IP位址和子網掩碼。

第11行,添加默認網關。

修改好rcS文件以後保存並退出,重啟開發板,這個時候eth0網卡就會在開機的時候自動啟動了,我們也就不用手動添加相關設置了。

39.5 改造我們自己的燒寫工具

39.5.1 改造MfgTool

在上一小節中我們已經實現了將自己的系統燒寫到開發板中,但是使用的是"借雞生蛋"的方法。我們通過將NXP官方的系統更換成我們自己製作的系統來完成系統燒寫,本節我們就來學習一下如何將MfgTool這個工具改造成我們自己的工具,讓其支持我們自己的開發板。要改造MfgTool,重點是三方面:

①、針對不同的核心版,確定系統文件相關名字。

②、新建我們自己的.vbs文件。

③、修改ucl2.xml文件。

1、確定系統文件名字

確定系統文件名字完全是為了兼容不同的產品,比如某個產品有NAND和EMMC兩個版本,那麼EMMC和NAND這兩個版本的uboot、zImage、.dtb和rootfs有可能不同。為了在MfgTool工具中同時支持EMMC和NAND這兩個版本的核心板,EMMC版本的系統文件命名如圖39.5.1.1所示:

圖39.5.1.1 系統文件名

2、新建.vbs文件

直接複製mfgtool2-yocto-mx-evk-emmc.vbs文件即可,將新複製的文件重命名為mfgtool2-alientek-alpha-emmc.vbs,文件內容不要做任何修改,.vbs文件我們就新建好了。

3、修改ucl2.xml文件

在修改ucl2.xml文件之前,先保存一份原始的ucl2.xml。將ucl2.xml文件改為如下所示內容:

<!-- 正點原子修改後的ucl2.xml文件 -->

<UCL>

<CFG>

<STATEname="BootStrap"dev="MX6UL"vid="15A2"pid="007D"/>

<STATEname="BootStrap"dev="MX6ULL"vid="15A2"pid="0080"/>

<STATEname="Updater"dev="MSC"vid="066F"pid="37FF"/>

</CFG>

<!-- 向EMMC燒寫系統 -->

<LISTname="eMMC"desc="Choose eMMC as media">

<CMDstate="BootStrap"type="boot"body="BootStrap"file ="firmware/u-boot-alientek-emmc.imx"ifdev="MX6ULL">Loading U-boot</CMD>

<CMDstate="BootStrap"type="load"file="firmware/zImage-alientek-emmc"address="0x80800000"

loadSection="OTH"setSection="OTH"HasFlashHeader="FALSE"ifdev="MX6SL MX6SX MX7D MX6UL MX6ULL">Loading Kernel.</CMD>

<CMDstate="BootStrap"type="load"file="firmware/%initramfs%"address="0x83800000"

loadSection="OTH"setSection="OTH"HasFlashHeader="FALSE"ifdev="MX6SL MX6SX MX7D MX6UL MX6ULL">Loading Initramfs.</CMD>

<CMDstate="BootStrap"type="load"file="firmware/imx6ull-alientek-emmc.dtb"address="0x83000000"

loadSection="OTH"setSection="OTH"HasFlashHeader="FALSE"ifdev="MX6ULL">Loading device tree.</CMD>

<CMDstate="BootStrap"type="jump">Jumping to OS image. </CMD>

<!-- create partition -->

<CMDstate="Updater"type="push"body="send"file="mksdcard.sh.tar">Sending partition shell</CMD>

<CMDstate="Updater"type="push"body="$ tar xf $FILE ">Partitioning...</CMD>

<CMDstate="Updater"type="push"body="$ sh mksdcard.sh /dev/mmcblk%mmc%">Partitioning...</CMD>

<!-- burn uboot -->

<CMDstate="Updater"type="push"body="$ dd if=/dev/zero of=/dev/mmcblk%mmc% bs=1k seek=768 conv=fsync count=8">clear u-boot arg</CMD>

<!-- access boot partition -->

<CMDstate="Updater"type="push"body="$ echo 0 > /sys/block/mmcblk%mmc%boot0/force_ro">access boot partition 1</CMD>

<CMDstate="Updater"type="push"body="send"file="files/u-boot-alientek-emmc.imx"ifdev="MX6ULL">Sending u-boot.bin</CMD>

<CMDstate="Updater"type="push"body="$ dd if=$FILE of=/dev/mmcblk%mmc%boot0 bs=512 seek=2">write U-Boot to sd card</CMD>

<CMDstate="Updater"type="push"body="$ echo 1 > /sys/block/mmcblk%mmc%boot0/force_ro">re-enable read-only access </CMD>

<CMDstate="Updater"type="push"body="$ mmc bootpart enable 1 1 /dev/mmcblk%mmc%">enable boot partion 1 to boot</CMD>

<!-- create fat partition -->

<CMDstate="Updater"type="push"body="$ while [ ! -e /dev/mmcblk%mmc%p1 ]; do sleep 1; echo \"waiting...\"; done ">Waiting for the partition ready</CMD>

<CMDstate="Updater"type="push"body="$ mkfs.vfat /dev/mmcblk%mmc%p1">Formatting rootfs partition</CMD>

<CMDstate="Updater"type="push"body="$ mkdir -p /mnt/mmcblk%mmc%p1"/>

<CMDstate="Updater"type="push"body="$ mount -t vfat /dev/mmcblk%mmc%p1 /mnt/mmcblk%mmc%p1"/>

<!-- burn zImage -->

<CMDstate="Updater"type="push"body="send"file="files/zImage-alientek-emmc">Sending kernel zImage</CMD>

<CMDstate="Updater"type="push"body="$ cp $FILE /mnt/mmcblk%mmc%p1/zImage">write kernel image to sd card</CMD>

<!-- burn dtb -->

<CMDstate="Updater"type="push"body="send"file="files/imx6ull-alientek-emmc.dtb"ifdev="MX6ULL">Sending Device Tree file</CMD>

<CMDstate="Updater"type="push"body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx6ull-alientek-emmc.dtb"ifdev="MX6ULL">write device tree to sd card</CMD>

<CMDstate="Updater"type="push"body="$ umount /mnt/mmcblk%mmc%p1">Unmounting vfat partition</CMD>

<!-- burn rootfs -->

<CMDstate="Updater"type="push"body="$ mkfs.ext3 -F -E nodiscard /dev/mmcblk%mmc%p2">Formatting rootfs partition</CMD>

<CMDstate="Updater"type="push"body="$ mkdir -p /mnt/mmcblk%mmc%p2"/>

<CMDstate="Updater"type="push"body="$ mount -t ext3 /dev/mmcblk%mmc%p2 /mnt/mmcblk%mmc%p2"/>

<CMDstate="Updater"type="push"body="pipe tar -jxv -C /mnt/mmcblk%mmc%p2"file="files/rootfs-alientek-emmc.tar.bz2"ifdev="MX6UL MX7D MX6ULL">Sending and writting rootfs</CMD>

<CMDstate="Updater"type="push"body="frf">Finishing rootfs write</CMD>

<CMDstate="Updater"type="push"body="$ umount /mnt/mmcblk%mmc%p2">Unmounting rootfs partition</CMD>

<CMDstate="Updater"type="push"body="$ echo Update Complete!">Done</CMD>

</LIST>

</UCL>

ucl2.xml文件我們僅僅保留了給EMMC燒寫系統,如果要支持NAND的話可以自行參考原版的ucl2.xml文件,添加相關的內容。

39.5.2 燒寫測試

MfgTool工具修改好以後就可以進行燒寫測試了,將imx6ull-alientek-emmc.dtb、u-boot-alientek-emmc.imx和zImage-alientek-emmc這三個文件複製到mfgtools-with-rootfs/mfgtools/Profiles/Linux/OS Firmware/firmware目錄中。將imx6ull-alientek-emmc.dtb、u-boot-alientek-emmc.imx、zImage-alientek-emmc和 rootfs-alientek-emmc.tar.bz2這四個文件複製到mfgtools-with-rootfs/mfgtools/Profiles/Linux/OS Firmware/files目錄中。

點擊"mfgtool2-alientek-alpha-emmc.vbs"打開MfgTool燒寫系統,等待燒寫完成,然後設置撥碼開關為EMMC啟動,重啟開發板,系統啟動信息如圖39.5.2.1所示:

圖39.5.2.1 系統啟動log信息

從圖39.5.2.1可以看出,出現"Starting kernel ..."以後就再也沒有任何信息輸出了,說明Linux內核啟動失敗了。接下來就是解決為何Linux內核啟動失敗這個問題。

39.5.3 解決Linux內核啟動失敗

上一小節我們啟動系統以後發現輸出"Starting kernel ..."以後就再也沒有任何信息了,難道是系統燒寫錯誤了?可以確定的是uboot啟動正常,就是在啟動Linux的時候出問題了,仔細觀察uboot輸出的log信息,會發現如圖39.5.3.1所示兩行信息:

圖39.5.3.1 讀取設備樹出錯

從圖39.5.3.1可以看出,在讀取"imx6ull-14x14-evk.dtb"這個設備樹文件的時候出錯了。重啟uboot,進入到命令行模式,輸入如下命令查看EMMC的分區1裡面有沒有設備樹文件:

mmcdev 1 //切換到EMMC

lsmmc 1:1 //輸出EMMC1分區1中的所有文件

結果如圖39.5.3.2所示:

圖39.5.3.2 EMMC分區1文件

從圖39.5.3.2可以看出,此時EMMC的分區1中是存在設備樹文件的,只是文件名字為:imx6ull-alientek-emmc.dtb,因此讀取imx6ull-14x14-evk.dtb肯定會出錯的,因為根本就不存在這個文件。之所以出現這個錯誤的原因是因為uboot裡面默認的設備樹名字就是imx6ull-14x14-evk.dtb,這個我們在講解uboot的時候就已經說過了。解決方法很簡單,有兩種方法:

1、重新設置bootcmd環境變量值

進入uboot的命令行,重新設置bootcmd和bootargs這兩個環境變量的值,這裡要注意的是bootargs的值也要重新設置一下,命令如下:

setenv bootcmd 'mmc dev 1;fatload mmc 1:1 80800000 zImage;fatload mmc 1:1 83000000 imx6ull-alientek-emmc.dtb;bootz 80800000 - 83000000'

setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'

saveenv

設置好bootcmd和bootargs這兩個環境變量以後重啟開發板,Linux系統就可以正常啟動。

2、修改uboot源碼

第1種方法每次重新燒寫系統以後都要先手動設置一下bootcmd的值,這樣有點麻煩,有沒有一勞永逸的方法呢?肯定是有的,就是直接修改uboot源碼。打開uboot源碼中的文件include/configs/mx6ull_alientek_emmc.h,在宏CONFIG_EXTRA_ENV_SETTINGS中找到如下所示內容:

示例代碼39.5.3.1 查找設備樹文件

194"findfdt="\

195"if test $fdt_file = undefined; then " \

196"if test $board_name = EVK && test $board_rev = 9X9; then " \

197"setenv fdt_file imx6ull-9x9-evk.dtb; fi; " \

198"if test $board_name = EVK && test $board_rev = 14X14; then " \

199"setenv fdt_file imx6ull-14x14-evk.dtb; fi; " \

200"if test $fdt_file = undefined; then " \

201"echo WARNING: Could not determine dtb to use; fi; " \

202"fi;\0" \

findfdt就是用於確定設備樹文件名字的環境變量,fdt_file環境變量保存著設備樹文件名。第196行和197行用於判斷設備樹文件名字是否為imx6ull-9x9-evk.dtb,第198行和199行用於判斷設備樹文件名字是否為imx6ull-14x14-evk.dtb。這兩個設備樹都是NXP官方開發板使用的,I.MX6U-ALPHA開發板用不到,因此直接將示例代碼39.5.3.1中findfdt的值改為如下內容:

示例代碼39.5.3.1 查找設備樹文件

194"findfdt="\

195"if test $fdt_file = undefined; then " \

196"setenv fdt_file imx6ull-alientek-emmc.dtb; " \

197"fi;\0" \

第196行,如果fdt_file未定義的話,直接設置fdt_file= imx6ull-alientek-emmc.dtb,簡單直接,不需要任何的判斷語句。修改後以後重新編譯uboot,然後用將新的uboot燒寫到開發板中,燒寫完成以後重啟測試,Linux內核啟動正常。

關於系統燒寫就講解到這裡,本章我們使用NXP提供的MfgTool工具通過USB OTG口向開發板的EMMC中燒寫uboot、Linuxkernel、.dtb(設備樹)和rootfs這四個文件。在本章我們主要做了五個工作:

①、理解MfgTool工具的工作原理。

②、使用MfgTool工具將NXP官方系統燒寫到I.MX6U-ALPHA開發板中,主要是為了體驗一下MfgTool軟體的工作流程以及燒寫方法。

③、使用MfgTool工具將我們自己編譯出來的系統燒寫到I.MX6U-ALPHA開發板中。

④、修改MfgTool工具,使其支持我們所使用的硬體平臺。

⑤、修改相應的錯誤。

關於系統燒寫的方法就講解到這裡,本章內容不僅僅是為了講解如何向I.MX6ULL晶片中燒寫系統,更重要的是向大家詳細的講解了MfgTool的工作原理。如果大家在後續的工作或學習中使用I.MX7或者I.MX8等晶片,本章同樣適用。

隨著本章的結束,也宣告著本書第三篇的內容也正式結束了,第三篇是系統移植篇,重點就是uboot、Linuxkernel和rootfs的移植,看似簡簡單單的"移植"兩個字,引出的卻是一篇300多頁的"愛恨情仇"。授人以魚不如授人以漁,本可以簡簡單單的教大家修改哪些文件、添加哪些內容,怎麼去編譯,然後得到哪些文件。但是這樣只能看到表象,並不能深入的了解其原理,為了讓大家能夠詳細的了解整個流程,筆者義無反顧的選擇了這條最難走的路,不管是uboot還是Linuxkernel,從Makefile到啟動流程,都儘自己最大的努力去闡述清楚。奈何,筆者水平有限,還是有很多的細節沒有處理好,大家有疑問的地方可以到正點原子論壇上發帖留言,大家一起討論學習。

第四篇 ARM Linux驅動開發篇

前面3篇,我們學習Ubuntu作業系統、學習ARM裸機、學習系統移植,其目的就是為了本篇做準備。本篇應該是大家最期待的內容了,畢竟大部分學習者的最初目的就是學習Linux驅動開發。本篇我們將會詳細講解Linux中的三大類驅動:字符設備驅動、塊設備驅動和網絡設備驅動。其中字符設備驅動是佔用篇幅最大的一類驅動,因為字符設備最多,從最簡單的點燈到I2C、SPI、音頻等都屬於字符設備驅動的類型。塊設備和網絡設備驅動要比字符設備驅動複雜,就是因為其複雜所以半導體廠商一般都給我們編寫好了,大多數情況下都是直接可以使用的。所謂的塊設備驅動就是存儲器設備的驅動,比如EMMC、NAND、SD卡和U盤等存儲設備,因為這些存儲設備的特點是以存儲塊為基礎,因此叫做塊設備。網絡設備驅動就更好理解了,就是網絡驅動,不管是有線的還是無線的,都屬於網絡設備驅動的範疇。一個設備可以屬於多種設備驅動類型,比如USB WIFI,其使用USB接口,所以屬於字符設備,但是其又能上網,所以也屬於網絡設備驅動。本篇我們就圍繞著三大設備驅動類型展開,儘可能詳細的講解每種設備驅動的開發方式。

本書使用的Linux內核版本為4.1.15,其支持設備樹(Device tree),所以本篇所有例程均採用設備樹。設備樹將是本篇的重點!從設備樹的基本原理到設備樹驅動的開發方式,從最簡單的點燈到複雜的網絡驅動開發,本篇均有詳細的講解,是學習設備樹的不二之選。

最後,祝大家學習愉快!

相關焦點

  • 「正點原子FPGA連載」第十八章Linux內核移植
    1)摘自【正點原子】領航者 ZYNQ 之linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?內核的啟動流程,本章我們就來學習一下如何將Xilinx官方提供的Linux內核移植到正點原子的領航者開發板上。
  • 「正點原子FPGA連載」第七章使用XSDK開發Linux應用
    1)摘自【正點原子】領航者 ZYNQ 之Linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?&id=6061601087614)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)對正點原子FPGA感興趣的同學可以加群討論:8767449006)關注正點原子公眾號,獲取最新資料
  • 「正點原子FPGA連載」第二十八章Linux蜂鳴器驅動實驗
    1)摘自【正點原子】領航者 ZYNQ 之linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?&id=6061601087614)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)對正點原子FPGA感興趣的同學可以加群討論:8767449006)關注正點原子公眾號,獲取最新資料
  • 「正點原子Linux連載」第七十一章Linux 4G通信實驗
    正點原子的I.MX6U-ALPHA開發板也有一個MiniPCIE形式的4G模塊接口,雖然外形是MiniPCIE的,但是內心卻是USB的。理論上所有的MiniPCIE接口的4G模塊都可以連接到正點原子的I.MX6U-ALPHA開發板上,因為這些4G模塊都遵循同樣的接口標準,但是大家在使用的時候還是要詳細的看一下4G模塊的接口引腳描述。
  • 「正點原子FPGA連載」第三十一章Linux按鍵輸入實驗
    1)摘自【正點原子】領航者 ZYNQ 之Linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?&id=6061601087614)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)對正點原子FPGA感興趣的同學可以加群討論:8767449006)關注正點原子公眾號,獲取最新資料
  • 「正點原子Linux連載」第三十七章Linux內核移植
    第三十七章Linux內核移植前兩章我們簡單了解了一下Linux內核頂層Makefile和Linux內核的啟動流程,本章我們就來學習一下如何將NXP官方提供的Linux內核移植到正點原子的I.MX6U-ALPHA開發板上。通過本章的學習,我們將掌握如何將半導體廠商提供的Linux BSP包移植到我們自己的平臺上。
  • 「正點原子FPGA連載」第八章Linux基礎外設的使用
    1)摘自【正點原子】領航者 ZYNQ 之linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?&id=6061601087614)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)對正點原子FPGA感興趣的同學可以加群討論:8767449006)關注正點原子公眾號,獲取最新資料
  • 「正點原子FPGA連載」第九章Linux顯示設備的使用
    1)摘自【正點原子】領航者 ZYNQ 之Linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?&id=6061601087614)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)對正點原子FPGA感興趣的同學可以加群討論:8767449006)關注正點原子公眾號,獲取最新資料
  • 「正點原子FPGA連載」第十九章根文件系統構建
    1)摘自【正點原子】領航者 ZYNQ 之linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?&id=6061601087614)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)對正點原子FPGA感興趣的同學可以加群討論:8767449006)關注正點原子公眾號,獲取最新資料
  • 「正點原子FPGA連載」第三十章Linux並發與競爭實驗
    1)摘自【正點原子】領航者 ZYNQ 之linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?&id=6061601087614)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)對正點原子FPGA感興趣的同學可以加群討論:8767449006)關注正點原子公眾號,獲取最新資料
  • 「正點原子FPGA連載」第二十二章Linux LED驅動開發
    1)摘自【正點原子】領航者 ZYNQ 之linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?&id=6061601087614)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)對正點原子FPGA感興趣的同學可以加群討論:8767449006)關注正點原子公眾號,獲取最新資料
  • 「正點原子FPGA連載」第十六章Linux內核頂層詳解
    1)摘自【正點原子】領航者 ZYNQ 之linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?&id=6061601087614)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)對正點原子FPGA感興趣的同學可以加群討論:8767449006)關注正點原子公眾號,獲取最新資料
  • 「正點原子FPGA連載」第三十二章Linux內核定時器實驗
    1)摘自【正點原子】領航者 ZYNQ 之linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?&id=6061601087614)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)對正點原子FPGA感興趣的同學可以加群討論:8767449006)關注正點原子公眾號,獲取最新資料
  • 「正點原子FPGA連載」第十章Linux圖形界面的使用
    1)摘自【正點原子】領航者 ZYNQ 之Linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?&id=6061601087614)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)對正點原子FPGA感興趣的同學可以加群討論:8767449006)關注正點原子公眾號,獲取最新資料
  • 「正點原子FPGA連載」第二十五章設備樹下的LED驅動實驗
    1)摘自【正點原子】領航者 ZYNQ 之linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?&id=6061601087614)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)對正點原子FPGA感興趣的同學可以加群討論:8767449006)關注正點原子公眾號,獲取最新資料
  • 「正點原子FPGA連載」第二十七章gpio子系統下的驅動實驗
    1)摘自【正點原子】領航者 ZYNQ 之linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?&id=6061601087614)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)對正點原子FPGA感興趣的同學可以加群討論:8767449006)關注正點原子公眾號,獲取最新資料
  • 「正點原子FPGA連載」第十七章Linux內核啟動流程
    1)摘自【正點原子】領航者 ZYNQ 之linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?&id=6061601087614)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)對正點原子FPGA感興趣的同學可以加群討論:8767449006)關注正點原子公眾號,獲取最新資料
  • 「正點原子Linux連載」第七十章Linux WIFI驅動實驗
    第七十章Linux WIFI驅動實驗WIFI的使用已經很常見了,手機、平板、汽車等等,雖然可以使用有線網絡,但是有時候很多設備存在布線困難的情況,此時WIFI就是一個不錯的選擇。正點原子I.MX6U-ALPHA開發板支持USB和SDIO這兩種接口的WIFI,本章我們就來學習一下如何在I.MX6U-ALPHA開發板上使用USB和SDIO這兩種WIFI。
  • 「正點原子Linux連載」第六十三章Linux RS232/485/GPS驅動實驗
    不管是什麼樣的接口電平,其驅動程序都是一樣的,通過外接RS485這樣的晶片就可以將串口轉換為RS485信號,正點原子的I.MX6U-ALPHA開發板就是這麼做的。對於正點原子的I.MX6U-ALPHA開發板而言, RS232、RS485以及GPS模塊接口通通連接到了I.MX6U的UART3接口上,因此這些外設最終都歸結為UART3的串口驅動。
  • 「正點原子FPGA連載」第二十三章新字符設備驅動實驗
    1)摘自【正點原子】領航者 ZYNQ 之linux驅動開發指南2)實驗平臺:正點原子領航者ZYNQ開發板3)平臺購買地址:https://item.taobao.com/item.htm?&id=6061601087614)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)對正點原子FPGA感興趣的同學可以加群討論:8767449006)關注正點原子公眾號,獲取最新資料