IMX6Q的SD卡启动使用教程【超完整】(1):uboot与kernel编译移植

本文主要介绍的是NXP官方开发板imx6q-sabresdSD卡烧写启动教程。

前言

本文操作环境为ubutnu18,需要准备好交叉编译工具链(本文不讨论)。启动资源版本:

  • linux5.4
  • uboot2021

注:

本文中,参考了正点原子IMX6ULL的教程,有些步骤不再详细描述,有时间会修改文章,进行详细补充。

一、准备启动SD卡

在进行资源编译移植时,需要准备一卡能够启动的SD卡,进行合适的SD卡分区与格式化。其过程主要使用到linux在的fdiskmkfs工具。

本文不再介绍如何格式化SD卡,可参考大佬的教程:基于Ubuntu的linux环境制作嵌入式SD/TF启动卡

二、编译移植uboot

2.1 uboot下载

IMX6Q官方uboot地址为:https://source.codeaurora.org/external/imx/uboot-imx/

其中包括多个版本,供选下载,以下载最新的uboot2021为例:

下载命令为:

git clone https://source.codeaurora.org/external/imx/uboot-imx -b lf_v2021.04 --depth=1

下载结果为:

xxx@ubuntu:~/imx$ ls
uboot-imx
2.2 uboot编译
2.2.1 修改顶层Makefile

修改顶层Makefile,添加自己的交叉编译工具。如下图
IMX6Q的SD卡启动使用教程【超完整】(1):uboot与kernel编译移植_第1张图片

2.2.2 编译配置

执行编译配置命令

make mx6qsabresd_defconfig
2.2.3 编译

执行编译命令

make -j4

编译完成后,在uboot顶层目录生成uboot镜像u-boot-dtb.imx

2.3 uboot烧录

将生成的uboot镜像烧录至准备好的SD中,其命令为

sudo dd if=u-boot-dtb.imx of=/dev/sdb bs=512 seek=2 && sync

其中参数为含义为:

  • dd:烧写命令
  • if:需要烧录的文件(uboot镜像)
  • of:被烧录的设备(SD卡)
  • bs:扇区大小(一般默认都为512byte)
  • seek:烧录至哪个扇区(IMX6Q为第二个扇区)
  • sync:确保烧录完整

至此,将SD卡插入开发板,设置为SD启动,上电就能打印uboot的启动log。

三、编译移植kernel

3.1 kernel下载

IMX6Q官方linux地址为:https://source.codeaurora.org/external/imx/linux-imx/

其中包括多个版本,供选下载,以下载linux5.4为例,下载命令为

git clone https://source.codeaurora.org/external/imx/linux-imx  -b imx_5.4.70_2.3.0 --depth=1

下载结果为

xxx@ubuntu:~/imx$ ls
linux-imx  uboot-imx
3.2 kernel编译
3.2.1 编译方法

kernel编译使用脚本形式,在顶层目录下创建shell脚本文件

vim build.sh

build.sh脚本文件的内容为:

#!/bin/sh                                                                                                   

#编译配置,第一次编译时使用,其他时候需屏蔽
make ARCH=arm imx_v7_defconfig CROSS_COMPILE=arm-none-eabi-

#编译
make ARCH=arm CROSS_COMPILE=arm-none-eabi- -j4
3.2.2 编译后的产物

执行完编译命令后,会生设备树与kernel的镜像,其路径分别为

设备树:linux-imx/arch/arm/boot/dts/imx6q-sabresd.dtb

kernel:linux-imx/arch/arm/boot/zImage

四、kernel加载方法

编译完成的kernel镜像,需要加载至DDR中运行,此过程有uboot完成,作为开发者只需要在uboot中配置好加载方式,一般的加载方法有

  • TFTP加载(有网络)
  • SD卡加载(无网络)

无论是哪种方式,只需要设置好uboot的环境变量即可。

4.1 TFTP方式加载kernel

在uboot启动后,进入交互模式,修改化境变量。修改uboot环境变量的命令主要有setenvsaveenv

4.1.1 方法简述

IMX6Q uboot通过TFTP网络加载kernel,首先在虚拟机开启TFTP服务器,并创建TFTP文件夹,将kernel与设备树镜像拷贝至TFTP文件夹,此过程可参考正点原子教程。然后设置开发板的IP地址信息,最后使用ping命令,从虚拟机ping开发板。

其中设置虚拟机为TFTP服务器,并ping通开发板的步骤很重要,网上教程较多,限于文章篇幅,以后单独说明。

4.1.2 修改开发板IP

修改为自己环境的IP地址,命令为

#开发板IP,自己任意设置,但需要与主机同一网段
setenv ipaddr 169.254.xxx.xxx

setenv gatewayip 169.254.xxx.xxx

setenv netmask 255.255.255.0

#虚拟机即主机的IP,自己ifconfig参看
setenv serverip 169.254.xxx.xxx

#保存环境变量
saveenv

设置完IP后,重新启动,在虚拟机上ping开发板。能通,万事大吉!怎样都不通,不要放弃,参考SD加载kernel的方式,直接到4.2小节。

4.1.3 设置TFTP加载方式

修改环境变量,设置TFTP加载方式,涉及到的环境变量为bootcmd

#设置命令
setenv bootcmd 'tftpboot 0x15000000 zImage;tftpboot 0x14000000 imx6q-sabresd.dtb;bootz 0x15000000 - 0x14000000'

#保存环境变量
saveenv

上述内容中,主要分为三个步骤:

  1. tftpboot 0x15000000 zImage:从TFTP服务器加载内核镜像
  2. tftpboot 0x14000000 imx6q-sabresd.dtb:从TFTP服务器加载设备树
  3. bootz 0x15000000 - 0x14000000:启动内核

注:

上述三个步骤可通过执行boot命令名来代替。

boot命令种类与区别

命令 描述
bootz 用于启动 zImage 镜像文件
bootm 用于启动 uImage 镜像文件
boot 用来启动 Linux 系统的
4.2 SD卡加载kernel

在无网络的情况下,使用此方法,会减少开发难度。

SD卡分区且格式化完成后,将kernel与设备树镜像拷贝至分区中(任意分区,推荐第一个分区)即可。默认的bootcmd环境变量,检索mmc下是否存在指定名称的kernel与设备设备镜像。

bootcmd=run findfdt;run findtee;mmc dev ${mmcdev};if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi

注:

看!SD卡加载kernel镜像的方式是不是很简单,只需要把镜像拷贝至SD中即可。

其实其过程uboot帮我们完成了工作,uboot,牛!

五,根文件系统加载

嵌入式系统的三大件:ubootlinuxrootfs,我们已经完成两步,只差rootfs了。

5.1 制作根文件系统

ubootlinux都是从NXP官网获取得到,而rootfs,需要我们自己的制作。

制作rootfs的方法有很多,使用最多最简单的就是通过交叉编译busybox得到幸。幸运是此教程网上较多,不在本文讨论,后续会另更新文章描述。
IMX6Q的SD卡启动使用教程【超完整】(2):busybox交叉编译根文件系统
本节主要介绍的是根文件系统加载方法,主要有

  • NFS挂载(有网络)
  • SD加载(无网络)

在uboot启动后,进入交互模式,修改化境变量,设置启动方式。

5.2 NFS挂载根文件系统
5.2.1 方法简述

此方法的前提是,开发板能够与虚拟机ping通。

IMX6Q 通过NFS挂载根文件系统,首先要在虚拟机开启NFS功能,此过程可参考正点原子教程。然后创建NFS目录,并根文件系统复制到NFS目录中。

虚拟机开启NFS功能,设置NFS挂载环境,网上教程较多,本文不再描述,后续系列文章会补充。(如果时间)

5.2.2 修改uboot环境变量

主要修改的是bootargs环境变量,根据自己的开发环境设置,其内容为

#1.先修改bootargs
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=169.254.17.100:/home/xxx/nfs,proto=tcp rw ip=169.254.17.229:169.254.17.100:169.254.17.1:255.255.255.0::eth0:off'

#2. 保存环境变量
saveenv
  • console:串口参数
  • root:kernel以NFS形式加载文件系统
  • nfsroot:NFS参数,169.254.17.100为虚拟机地址,169.254.17.229为开发板地址

修改bootargs环境变量,并保存。重启开发板,成功加载根文件系统,进入shell交互,一顿ls操作,万事大吉!

5.3 SD加载根文件系统

如果网络不通,可使用SD加载根文件系统。修改uboot中的bootargsmmcargs环境变量

#1.先修改bootargs
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk2p2 rootwait rw'

#2.再修改mmcargs
setenv mmcargs 'console=ttymxc0,115200 root=/dev/mmcblk2p2 rootwait rw'

#3. 保存环境变量
saveenv

其中root=/dev/mmcblk2p2是文件系统存放的SD分区。本文将制作完成的rootfs拷贝到第二个SD分区中,因此设置为/dev/mmcblk2p2,根据个人情况设置。

总结

经过上述5个步骤,即可实现uboot引导linux,加载文件系统的工作。整个流程是一个linux嵌入式工程师必备技能,其中会遇到很多问题,需要自己一一解决并总结。幸运的是大部分问题网上都能找到解决方案,重要的是坚持!

后续会补充文中没有详细展开的内容,包括根文件系统制作、NFS\TFPT启动等。

还准备手把手教如何在IMX6Q上移植ubuntu20根文件系统并安装桌面,制作属于自己的嵌入式开发板环境。

你可能感兴趣的:(uboot,linux,IMX6Q,rootfs,uboot,嵌入式)