2.2【Linux系统移植之二】:移植Linux内核(制作zImage和.dtb设备树文件)

文章目录

  • 一、Linux内核源码编译
  • 二、修改源码添加自己的开发板
  • 三、系统无法启动,错误解决
    • 3.1 报错信息:not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
    • 3.2 如果使用nfs挂载文件系统,提示找不到系统,则可设置如下环境变量
  • 三、写在最后:答疑


  备注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?

    答:

你可能感兴趣的:(linux驱动学习,Linux内核移植)