3、Linux驅動開發之三:移植Linux內核(製作zImage和.dtb設備樹文件)


  備註1:本文以正點原子imx6ull芯片Alpha開發板爲例。參考《正點原子嵌入式linux驅動開發指南V1.4.pdf》整理的筆記。

  備註2:移植Linxu內核之前,需要安裝交叉編譯工具鏈,安裝方法見另一篇博客:1.1、Ubuntu18.04安裝交叉編譯工具鏈

一、Linux內核源碼編譯

  下載下載的源碼不做修改直接進行編譯,目的在於驗證下載的源碼可以正常編譯通過,包括自己Linux系統環境也可以進行驗證,免得後續出現各種問題懷疑源碼不對(事實上源碼一般不會編譯不通過,所以該步驟可以直接跳過,直接看下一小節)。

  1. 下載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中修改交叉編譯工具鏈
  2. 安裝依賴庫(否則會編譯失敗)

    sudo apt-get install lzop
    
  3. 修改頂層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-
    
  4. 配置編譯內核

    備註:編譯時需要使用板卡對應的默認配置文件(每個板卡都有),配置文件保存在arch/arm/config文件夾中,imx6ull開發板可以使用配置文件:imx_v7_defconfig和imx_v7_mfg_defconfig

    make clean                     #內核源碼頂層目錄下執行
    make imx_v7_mfg_defconfig      #配置Linux內核
    make -j16                      #編譯內核
    
  5. 編譯完成以後界面如下

    可以看到提示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
    
  6. 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/
    
  7. 下載zImage和imx6ull-14x14-evk.dtb到Flash中

    啓動U-Boot,倒數結束之前按任意鍵,進入U-Boot命令行界面,輸入如下命令:

    tftp 80800000 zImage
    tftp 83000000 imx6ull-14x14-evk.dtb
    bootz 80800000 - 83000000
    
  8. 此時就可以進入Linux系統了,如果系統報錯,無法啓動,大概率是因爲環境變量的問題,暫時不用理會,後面錯誤解決章節會記錄如何設置環境變量。

二、修改源碼添加自己的開發板

  上面步驟是將下載下來的源碼直接進行編譯,確保源碼可以編譯通過且環境沒有問題。此步驟是將Linux內核源碼進行修改,編譯生成自己板卡適用的zImage和設備樹文件。

  同上面一樣,還是先解壓一份正點原子提供的Linux內核源碼,然後按下面步驟逐步修改:

  1. 解壓源碼包

    tar -jxvf linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2
    
  2. 安裝依賴庫(如上面步驟已安裝,則此處可以跳過)

    sudo apt-get install lzop
    
  3. 修改頂層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
    
  4. 拷貝配置文件爲自己板卡的配置文件

    cd arch/arm/configs
    cp imx_v7_mfg_defconfig imx_alientek_emmc_defconfig
    

    後續就可以使用imx_alientek_emmc_defconfig文件配置對應開發板內核了:

    cd {內核源碼頂層目錄}
    make imx_alientek_emmc_defconfig
    
  5. 拷貝開發板設備樹文件

    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
    
  6. 編譯源碼測試

    創建編譯腳本

    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
    
  7. 編譯完成後終端顯示如下:

      ...
      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
    
  8. 將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/
    
  9. 下載zImage和imx6ull-14x14-evk.dtb到Flash中

    啓動U-Boot,倒數結束之前按任意鍵,進入U-Boot命令行界面,輸入如下命令:

    tftp 80800000 zImage
    tftp 83000000 imx6ull-alientek-emmc.dtb
    bootz 80800000 - 83000000
    
  10. 此時就可以進入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'

三、寫在最後:答疑

  1. 如何判斷每個板卡應該使用哪個默認的配置文件,比如如何判斷imx6ull EVK對應的配置文件就可以使用imx_v7_defconfig和imx_v7_mfg_defconfig?

    答:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章