文章目錄
備註1:本文以正點原子imx6ull芯片Alpha開發板爲例。參考《正點原子嵌入式linux驅動開發指南V1.4.pdf》整理的筆記。
備註2:移植Linxu內核之前,需要安裝交叉編譯工具鏈,安裝方法見另一篇博客:1.1、Ubuntu18.04安裝交叉編譯工具鏈。
一、Linux內核源碼編譯
下載下載的源碼不做修改直接進行編譯,目的在於驗證下載的源碼可以正常編譯通過,包括自己Linux系統環境也可以進行驗證,免得後續出現各種問題懷疑源碼不對(事實上源碼一般不會編譯不通過,所以該步驟可以直接跳過,直接看下一小節)。
-
下載Linux內核鏡像源碼,並解壓
備註:我這裏直接使用正點原子提供的內核源碼,路徑爲:
【正點原子】阿爾法Linux開發板(A盤)-基礎資料\1、例程源碼\4、NXP官方原版Uboot和Linux
tar -jxvf linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2
內核目錄常用目錄含義如下:
目錄 含義 arch 架構相關目錄 drivers 驅動相關目錄 fs 文件系統相關目錄 include 頭文件相關目錄 kernel 內核相關目錄 lib 庫相關目錄 .config Linux最終使用的配置文件(編譯生成) Kconfig 圖形化配置界面配置文件 Makefile 頂層Makefile,工程結構從此Makefile作爲入口
源碼剛下載下來第一步需要在該Makefile中修改交叉編譯工具鏈 -
安裝依賴庫(否則會編譯失敗)
sudo apt-get install lzop
-
修改頂層Makefile,配置交叉編譯工具鏈
cd linux-imx-rel_imx_4.1.15_2.1.0_ga vim Makefile
找到如下代碼(252,253行):
ARCH ?= $(SUBARCH) CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
修改爲:
ARCH ?= arm CROSS_COMPILE ?= arm-linux-gnueabihf-
-
配置編譯內核
備註:編譯時需要使用板卡對應的默認配置文件(每個板卡都有),配置文件保存在arch/arm/config文件夾中,imx6ull開發板可以使用配置文件:imx_v7_defconfig和imx_v7_mfg_defconfig
make clean #內核源碼頂層目錄下執行 make imx_v7_mfg_defconfig #配置Linux內核 make -j16 #編譯內核
-
編譯完成以後界面如下
可以看到提示Kernel: arch/arm/boot/zImage is ready,內核鏡像已經準備好了。
... LD [M] lib/crc7.ko LD [M] lib/libcrc32c.ko AS arch/arm/boot/compressed/piggy.lzo.o LD arch/arm/boot/compressed/vmlinux OBJCOPY arch/arm/boot/zImage Kernel: arch/arm/boot/zImage is ready
-
zImage鏡像和.dtb設備樹文件所在路徑
編譯完成之後會生成Linux內核鏡像文件zImage和設備樹文件xxx.dtb,後面需要將該兩個文件燒寫到emmc中。兩個文件所在目錄分別如下
文件 含義 所在目錄 zImage Linux內核鏡像文件 arch/arm/boot xxx.dtb 設備樹文件 arch/arm/boot/dts NXP官方I.MX6ULL EVK開發板對應設備樹文件爲:imx6ull-14x14-evk.dtb
將zImage和imx6ull-14x14-evk.dtb拷貝到tftp服務器目錄中:
cp arch/arm/boot/zImage ~/Tools/tftp/ cp arch/arm/boot/dts/imx6ull-14x14-evk.dtb ~/Tools/tftp/ ls ~/Tools/tftp/
-
下載zImage和imx6ull-14x14-evk.dtb到Flash中
啓動U-Boot,倒數結束之前按任意鍵,進入U-Boot命令行界面,輸入如下命令:
tftp 80800000 zImage tftp 83000000 imx6ull-14x14-evk.dtb bootz 80800000 - 83000000
-
此時就可以進入Linux系統了,如果系統報錯,無法啓動,大概率是因爲環境變量的問題,暫時不用理會,後面錯誤解決章節會記錄如何設置環境變量。
二、修改源碼添加自己的開發板
上面步驟是將下載下來的源碼直接進行編譯,確保源碼可以編譯通過且環境沒有問題。此步驟是將Linux內核源碼進行修改,編譯生成自己板卡適用的zImage和設備樹文件。
同上面一樣,還是先解壓一份正點原子提供的Linux內核源碼,然後按下面步驟逐步修改:
-
解壓源碼包
tar -jxvf linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2
-
安裝依賴庫(如上面步驟已安裝,則此處可以跳過)
sudo apt-get install lzop
-
修改頂層Makefile交叉編譯工具鏈
cd linux-imx-rel_imx_4.1.15_2.1.0_ga vim Makefile
找到如下代碼(252,253行):
ARCH ?= $(SUBARCH) CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
修改爲:
ARCH ?= arm CROSS_COMPILE ?= arm-linux-gnueabihf
-
拷貝配置文件爲自己板卡的配置文件
cd arch/arm/configs cp imx_v7_mfg_defconfig imx_alientek_emmc_defconfig
後續就可以使用imx_alientek_emmc_defconfig文件配置對應開發板內核了:
cd {內核源碼頂層目錄} make imx_alientek_emmc_defconfig
-
拷貝開發板設備樹文件
cd arch/arm/boot/dts cp imx6ull-14x14-evk.dts imx6ull-alientek-emmc.dts
在當前目錄下的Makefile中添加該設備樹文件
vim Makefile
找到CONFIG_SOC_IMX6ULL配置項(400行),在此配置項中加入“imx6ull-alientek-emmc.dtb” (我加在了末尾425行)
400 dtb-$(CONFIG_SOC_IMX6ULL) += \ 401 >---imx6ull-14x14-ddr3-arm2.dtb \ 402 >---imx6ull-14x14-ddr3-arm2-adc.dtb \ 403 >---imx6ull-14x14-ddr3-arm2-cs42888.dtb \ 404 >---imx6ull-14x14-ddr3-arm2-ecspi.dtb \ 405 >---imx6ull-14x14-ddr3-arm2-emmc.dtb \ 406 >---imx6ull-14x14-ddr3-arm2-epdc.dtb \ 407 >---imx6ull-14x14-ddr3-arm2-flexcan2.dtb \ 408 >---imx6ull-14x14-ddr3-arm2-gpmi-weim.dtb \ 409 >---imx6ull-14x14-ddr3-arm2-lcdif.dtb \ 410 >---imx6ull-14x14-ddr3-arm2-ldo.dtb \ 411 >---imx6ull-14x14-ddr3-arm2-qspi.dtb \ 412 >---imx6ull-14x14-ddr3-arm2-qspi-all.dtb \ 413 >---imx6ull-14x14-ddr3-arm2-tsc.dtb \ 414 >---imx6ull-14x14-ddr3-arm2-uart2.dtb \ 415 >---imx6ull-14x14-ddr3-arm2-usb.dtb \ 416 >---imx6ull-14x14-ddr3-arm2-wm8958.dtb \ 417 >---imx6ull-14x14-evk.dtb \ 418 >---imx6ull-14x14-evk-btwifi.dtb \ 419 >---imx6ull-14x14-evk-emmc.dtb \ 420 >---imx6ull-14x14-evk-gpmi-weim.dtb \ 421 >---imx6ull-14x14-evk-usb-certi.dtb \ 422 >---imx6ull-9x9-evk.dtb \ 423 >---imx6ull-9x9-evk-btwifi.dtb \ 424 >---imx6ull-9x9-evk-ldo.dtb \ 425 >---imx6ull-alientek-emmc.dtb
-
編譯源碼測試
創建編譯腳本
cd {內核源碼根目錄} vim imx6ull_alientek_emmc.sh
加入如下內容:(注意倒數第二行尾配置內核功能,如果不需要配置,在編譯的時候直接選擇EIXT退出即可)
#!/bin/sh make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_alientek_emmc_defconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16
修改權限,並執行腳本:
chmod 777 imx6ull_alientek_emmc.sh ./imx6ull_alientek_emmc.sh
-
編譯完成後終端顯示如下:
... LD [M] lib/crc7.ko AS arch/arm/boot/compressed/ashldi3.o LD [M] lib/crc-ccitt.ko AS arch/arm/boot/compressed/bswapsdi2.o AS arch/arm/boot/compressed/piggy.lzo.o LD arch/arm/boot/compressed/vmlinux OBJCOPY arch/arm/boot/zImage Kernel: arch/arm/boot/zImage is ready
-
將zImage和imx6ull-alientek-emmc.dtb拷貝到tftp服務器目錄中:
cp arch/arm/boot/zImage ~/Tools/tftp/ cp arch/arm/boot/dts/imx6ull-alientek-emmc.dtb ~/Tools/tftp/ ls ~/Tools/tftp/
-
下載zImage和imx6ull-14x14-evk.dtb到Flash中
啓動U-Boot,倒數結束之前按任意鍵,進入U-Boot命令行界面,輸入如下命令:
tftp 80800000 zImage tftp 83000000 imx6ull-alientek-emmc.dtb bootz 80800000 - 83000000
-
此時就可以進入Linux系統了。
三、系統無法啓動,錯誤解決
3.1 報錯信息:not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
如果啓動時碰到報錯信息如下:
[ 2.667765] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
[ 2.676044] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
則說明是因爲U-Boot環境變量未進行設置。在U-Boot中輸入如下命令設置環境變量,再重啓即可:
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
saveenv
如果想要再重新復現該錯誤,只需要刪掉剛設置的環境變量即可,在U-Boot中輸入如下代碼:
setenv bootargs 'console=ttymxc0,115200'
saveenv
重啓即可復現上步驟錯誤。
3.2 如果使用nfs掛載文件系統,提示找不到系統,則可設置如下環境變量
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.0.250:/home/lsy/Tools/nfs/rootfs ip=192.168.0.100:192.168.0.250:192.168.0.1:255.255.255.0::eth0:off'
三、寫在最後:答疑
-
如何判斷每個板卡應該使用哪個默認的配置文件,比如如何判斷imx6ull EVK對應的配置文件就可以使用imx_v7_defconfig和imx_v7_mfg_defconfig?
答: