YP.Lam | iMX6ULL SD卡系统制作与启动

iMX6ULL SD卡系统制作与启动

鉴于之前玩的 MT7688A 已经停产并且模块断货,最近把目光投向一款新芯片:iMX6ULL,因为其起点价格在接受范围,最低配置的核心板价格在百元以内,128M+128M 足够跑我的OpenThread网关,通用芯片该有的功能都有,按功能来算的话比 MT7688A 性价比还高。

拿到开发板,目标是跑 OpenWRT + OpenThread 网关,MQTT/MQTT-SN 或者 LWM2M 服务,把手上一堆传感器、控制器接上,不依赖外部服务运行。

原装系统运行在 nand 上,不方便折腾,于是准备用 SD 卡启动的方式,修改起来很简单,热风枪把一个配置电阻换个位置。

由于还不熟悉此板卡 uboot,内核的编译,暂时先用着随板带的固件。

写入uboot

uboot 固件使用 uboot-myimx6ek140-6y-256m-nand.imx,imx 文件格式在这里有个比较详细的介绍:https://www.cnblogs.com/Lioker/p/13219519.html。芯片启动时内部 ROM 程序会按 imx 文件格式从 SD 卡的 0x400 地址加载相关配置,并且启动。

所以我们要以以下命令将 uboot 写入sd卡:

sudo dd if=uboot-myimx6ek140-6y-256m-nand.imx of=/dev/sdx bs=1k seek=1 conv=fsync

上面的命令含义是以 1k 的块大小写入,并且跳过第一个块(第一个块一般为分区表);详细解说可以参考 i.MX_Linux_User’s_Guide.pdf 4.3 章节以及上面关于 imx 格式的文章。

顺便吐槽一下国内某些卖开发板的,文档就只是一堆关于软件使用,脚本运行,却完全不涉及这么操作的原理

SD卡分区,烧写文件

如果平时用的是 Linux 系统,SD 卡的分区就简单一点,分两个区,一个 fat32 格式用来放内核文件以及设备树(不确定为何要 fat32,看自带的 uboot 是已经支持 ext4 ),一个选一个你喜欢的格式,用来放根目录;可以按官方推荐的分区方式:

  • 前面 10MB 空出来,因为要留给 uboot
  • 10MB 开始,分 500MB 格式化成 FAT32 用来存放内核与设备树文件
  • 后面一个 ext3/ext4 用来做根文件

通过 fdisk 与 mkfs 指令完成,参考官方文档(需要注意sdx需要与你sd卡对应):

$ sudo fdisk /dev/sdx
Type the following parameters (each followed by <ENTER>):
p [lists the current partitions]
d [to delete existing partitions. Repeat this until no unnecessary partitions
are reported by the 'p' command to start fresh.]
n [create a new partition]
p [create a primary partition - use for both partitions]
1 [the first partition]
20480 [starting at offset sector]
1024000 [size for the first partition to be used for the boot images]
p [to check the partitions]
np2
1228800 [starting at offset sector, which leaves enough space for the kernel,
the bootloader and its configuration data]
<enter> [using the default value will create a partition that extends to
the last sector of the media]
p [to check the partitions]
w [this writes the partition table to the media and fdisk exits]

格式化:

sudo mkfs.fat -F32 -v -n "BOOT" /dev/sdx1
sudo mkfs.ext4 -F -L "rootfs" /dev/sdx2

然后将内核文件、dtb、rootfs分别拷贝过去。

uboot 启动

将 SD 卡换过去,加电,如无以外 uboot 应该是可以起来,内核起不来(如果内核也能起来的话可以uboot启动的时候按一下键盘暂停内核启动)

在 uboot 终端运行 printenv 命令,查看厂家预定义的一些参数根据自己的需要进行修改。

譬如在我的开发板上运行下面的指令就可以从 SD 卡启动:

fatload mmc 0:1 ${kernel_addr_r} zimage-myimx6a7
fatload mmc 0:1 ${fdt_addr_r} myimx6ek140-6y-256m-nand.dtb

setenv bootargs console=${console},${baudrate} root=/dev/mmcblk0p2
bootz ${kernel_addr_r} - ${fdt_addr_r}

上面指令依次从 SD 卡的第一个分区加载 zimage-myimx6a7 内核文件到内核启动的内存地址,myimx6ek140-6y-256m-nand.dtb 设备树文件到设备树内存地址,然后设置 bootargs (传递给内核的启动参数),然后启动。

参数化一下:

setenv my_load_ker fatload mmc 0:1 ${kernel_addr_r} zimage-myimx6a7
setenv my_load_dtb fatload mmc 0:1 ${fdt_addr_r} myimx6ek140-6y-256m-nand.dtb
setenv my_bootz bootz ${kernel_addr_r} - ${fdt_addr_r}
setenv bootargs console=${console},${baudrate} root=/dev/mmcblk0p2
saveenv

然后就可以用此单行指令启动:

run my_load_ker; run my_load_dtb; run my_bootz

更进一步:

setenv bootcmd_my "run my_load_ker; run my_load_dtb; run my_bootz"
setenv my_env_flag set
saveenv

或者直接改掉原开发板的 bootcmd

setenv bootcmd "run my_load_ker; run my_load_dtb; run my_bootz"
saveenv

重启,可以直接从SD卡启动

参考: