i.MX8 uuu

简介:

uuui.MX 8 Universal Update Utility的简称,这个是mfgtools的后续方案,俗称MFGtools v3。
wiki: https://github.com/NXPmicro/mfgtools/wiki
pdf: https://github.com/NXPmicro/mfgtools/releases

原先的MFGtools中,在下载模式下,PC使用USB HID与开发板进行通信,将firmware uboot/kernel/dtb/ramdiskload到DDR上,然后去启动小系统(小kernel),之后PC识别开发板为USB Mass Storage设备,可以通过PC将命令(使用uuc实现)发送给小系统(小kernel),从而实现烧写功能。
而目前的uuu,新增使用fastboot协议,就是在小u-boot中配置支持fastboot。在下载模式下,PC还是使用USB HID与开发板进行通信,将支持fastboot的小u-boot放到开发板上运行,之后PC与开发板使用fastboot协议与小u-boot进行通信,包括load kernel等操作,启动小系统,从而实现烧写功能。


编译/下载:

1
2
3
git clone https://github.com/NXPmicro/mfgtools
cmake .
make

定制和load小u-boot

1、按照UUU.pdfUboot config requirement章节的说明,需要配置小u-boot支持以下几种功能,编译生成flash.bin

  • USB Gadget;
  • USB UDC(USB Device Controller)
  • fastboot命令

最终小u-boot关于uuu的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CONFIG_CMD_FASTBOOT=y
CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DOWNLOAD=y
CONFIG_USB_GADGET_MANUFACTURER="FSL"
CONFIG_USB_GADGET_VENDOR_NUM=0x0525
CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
CONFIG_CI_UDC=y # UDC need change according system, -some system use CONFIG_USB_DWC3, some use CONFIG_USB_CDNS3
CONFIG_FSL_FASTBOOT=y
CONFIG_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x80280000
# Address need change according -system, generally it can be the same as ${LOADADDR}
CONFIG_FASTBOOT_BUF_SIZE=0x40000000
CONFIG_FASTBOOT_FLASH=y
CONFIG_FASTBOOT_FLASH_MMC_DEV=1
CONFIG_EFI_PARTITION=y
CONFIG_ANDROID_BOOT_IMAGE=y

2、将开发板设置为Serial Download模式,与PC机连接;
3、查看USB连接情况(不是必须);
在ubuntu下执行lsusb可以看到连接上了一个Bus 001 Device 048: ID 1fc9:012f NXP Semiconductors设备,可以进一步查看lsusb -v -d 1fc9:012f这个设备是一个Human Interface Device设备。
4、load 小u-boot
执行如下的uuu命令,load 小u-boot到开发板上的DDR并跑起来(目前i.MX8在u-boot运行之前会先跑scfw,已将DDR初始化完毕):

1
2
3
4
5
6
7
8
9
# ./uuu SDPS: boot -f flash.bin
uuu (Universal Update Utility) for nxp imx chips -- libuuu_1.2.91-3-g41a3d59

Success 0 Failure 0

1/ 0 [ ]
1:11 1/ 0 [============100%============]

Okay

可以通过串口查看u-boot有如下串口输出表示进入fastboot模式:

1
2
3
4
5
6
7
8
9
10
11
[  217.774] Detect USB boot. Will enter fastboot mode!
[ 217.779] Fastboot: Normal
[ 217.781] Boot from USB for mfgtools
[ 217.785] Use default environment for mfgtools
[ 217.791] Run bootcmd_mfg: run mfgtool_args;if iminfo ${initrd_addr};
then if test ${tee} = yes; then bootm ${tee_addr} ${initrd_addr} ${fdt_addr};
else booti ${loadaddr} ${initrd_addr} ${fdt_addr}; fi; els;
[ 217.821]
[ 217.823] ## Checking Image at 83100000 ...
[ 217.827] Unknown image format!
[ 217.830] Run fastboot ...

5、查看USB连接情况(不是必须);
在ubuntu下执行lsusb可以看到连接上了一个Bus 001 Device 049: ID 0525:a4a5 Netchip Technology, Inc. Pocketbook Pro 903设备,可以进一步查看lsusb -v -d 0525:a4a5这个设备是一个Android Fastboot设备。


使用FB命令:

FBAndroid fastboot protocol,支持如下命令:
图1

比如说./uuu FB: ucmd <any uboot cmd>中就可以通过uuu执行uboot命令,比如执行uboot help或者printenv命令:
./uuu FB: ucmd help./uuu FB: ucmd printenv

比如说./uuu FB: download -f <filename> 可以下载kernel、rootfs、dtb到DRM中,当然,load到DDR的那个地方,需要使用fastboot_buffer环境变量进行指定。

1
2
3
4
5
6
7
8
./uuu FB: ucmd setenv fastboot_buffer ${loadaddr}
./uuu FB: download -f Image
./uuu FB: ucmd setenv fastboot_buffer ${fdt_addr}
./uuu FB: download -f board.dtb
./uuu FB: ucmd setenv fastboot_buffer ${initrd_addr}
./uuu FB: download -f fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot
#FB: ucmd setenv bootargs console=${console},${baudrate} earlycon=${earlycon},${baudrate}
./uuu FB: acmd ${kboot} ${loadaddr} ${initrd_addr} ${fdt_addr}

我这边使用上述的命令无法执行成功,原因是没办法取得默认的环境变量${loadaddr}等,所以这里临时测试使用直接的地址进行测试,如下可以保证小kernel跑起来,当然,这里的小kernel小 rootfs必须重新定制一下。

1
2
3
4
5
6
7
./uuu FB: ucmd setenv -f fastboot_buffer 0x80280000
./uuu FB: download -f Image
./uuu FB: ucmd setenv -f fastboot_buffer 0x83000000
./uuu FB: download -f board.dtb
./uuu FB: ucmd setenv -f fastboot_buffer 0x83100000
./uuu FB: download -f fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot
./uuu FB: acmd booti 0x80280000 0x83100000 0x83000000

无法取得默认的环境变量${loadaddr}的解决方法是要给环境变量加上引号,如下:

1
2
3
4
5
6
7
8
./uuu FB: ucmd setenv fastboot_buffer '${loadaddr}'
./uuu FB: download -f Image
./uuu FB: ucmd setenv fastboot_buffer '${fdt_addr}'
./uuu FB: download -f board.dtb
./uuu FB: ucmd setenv fastboot_buffer '${initrd_addr}'
./uuu FB: download -f fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot
#FB: ucmd setenv bootargs console=${console},${baudrate} earlycon=${earlycon},${baudrate}
./uuu FB: acmd '${kboot}' '${loadaddr}' '${initrd_addr}' '${fdt_addr}'


定制和load小kernel

1、按照UUU.pdfkernel config requirement章节的说明,需要配置小kernel支持以下几种功能,编译生成Image

  • 配置 USB CONFIGFS
  • 配置USB UDC
  • 配置function fs
    图2

关于配置function fs需要配置如下几个宏:

1
2
3
4
5
6
CONFIG_USB_LIBCOMPOSITE=y
CONFIG_USB_F_MASS_STORAGE=y
CONFIG_USB_F_FS=y
CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_FS=y


定制小rootfs

小kernel小rootfs跑起来后,PC端查看lsusb发现一个USB设备为:Bus 001 Device 099: ID 066f:37ff SigmaTel, Inc.
按照uuu.pdf的说明,接下来可以使用FBK小kernel进行fastboot协议的通信。但是我这边执行./uuu FBK: ucmd ls命令就block住了,没有返回Okay或者失败啥的。
根据uuu.pdf的说明,FBK的实现依赖于initramfs,且FBK默认只支持066f:9afe066f:9bff的设备。
图3

解决FBK不能执行的两种方案如下:
方案1:重新编译initramfs,使用最新的yocto编译新的initramfs为:fsl-image-mfgtool-initramfs-imx8qxpmek.cpio.gz.u-boot,命令如下:

1
2
source setup-environment fsl-imx-wayland/
bitbake fsl-image-mfgtool-initramfs

可以看到在生成的rootfs中的linuxrc里面,已经设置新的PID和VID了。
tmp/work/imx8qxpmek-poky-linux/fsl-image-mfgtool-initramfs/1.0-r0/rootfs/linuxrc

1
2
3
4
5
6
7
8
9
10
11
12
13
function launch_uuc() {
echo $1 $2
mkdir /sys/kernel/config/usb_gadget/$1
cd /sys/kernel/config/usb_gadget/$1
echo 0x066F > idVendor

if [[ ${cmdline} == *nfsroot* ]]; then
echo 0x9CFF > idProduct
else
echo 0x9BFF > idProduct
fi

mkdir strings/0x409

将这个initramfs做为小rootfsload进去就可以使用FBK命令了。

方案2:根据uuu源代码中uuu/uuu.lst文件的说明,我们可以重新配置FBK支持的设备。

CFG: Config protocol of specific usb device vid/pid
SDPS|SDP|FB\Fastboot|FBK -chip-pid-vid[-bcdversion]

使用下面的命令进行配置:./uuu CFG: FBK: -pid 0x37ff -vid 0x066f
按照上述的步骤,小kernel与PC通信上了后接下来烧录的动作就可以使用FBK命令来完成了。


使用uuu实现工厂烧写

1、既然我们现在可以实现uuuFBFBK命令,那么我们就可以通过FB命令在u-boot中实现烧写fuse的动作,也就是烧写SRK fuse。可以在出厂的时候使用uuu对fuse进行烧写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FB: ucmd fuse prog 0 730 0x475e1dca
FB: ucmd fuse prog 0 731 0xec5c98d2
FB: ucmd fuse prog 0 732 0x6dd5b7ec
FB: ucmd fuse prog 0 733 0xda535b48
FB: ucmd fuse prog 0 734 0x5baa6f61
FB: ucmd fuse prog 0 735 0x9d788292
FB: ucmd fuse prog 0 736 0x27f53d5f
FB: ucmd fuse prog 0 737 0x1316752a
FB: ucmd fuse prog 0 738 0x01043451
FB: ucmd fuse prog 0 739 0x7578275d
FB: ucmd fuse prog 0 740 0xc5fcd1e1
FB: ucmd fuse prog 0 741 0x12bac3e2
FB: ucmd fuse prog 0 742 0xef6860a2
FB: ucmd fuse prog 0 743 0xa0a12501
FB: ucmd fuse prog 0 744 0xbc2b9c25
FB: ucmd fuse prog 0 745 0xcfeea329


遇到的问题:

1、sudo 问题
执行uuu的时候提示要执行sudo的问题,必须在ubuntu下新建sudo vi /etc/udev/rules.d/99-uuu.rules文件,内容如下,最后执行sudo udevadm control --reload-rules

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="012f", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="0129", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="0076", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="0054", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="0061", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="0063", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="0071", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="007d", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="0080", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="0128", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="0126", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="0135", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="0134", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="012b", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0525", ATTRS{idProduct}=="b4a4", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0525", ATTRS{idProduct}=="a4a5", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="066F", ATTRS{idProduct}=="9BFF", MODE="0666"

2、传输大文件问题
按照FBK命令的说明,可以使用ucp命令从PC拷贝文件到板子上,再使用ucmd进行操作,比如说烧写imx8的flash.bin

1
2
./uuu FBK: ucp file/imx8x/flash.bin t:/tmp
./uuu FBK: ucmd dd if=/tmp/flash.bin of=/dev/mmcblk0 bs=1024 seek=32

比如说有个bigdata.img的镜像,大小为256MB,按照这种做法去传输大文件会出问题,必须使用如下的方式:

1
2
sudo ./uuu FBK: acmd dd of=/dev/mmcblk0p3 bs=512
sudo ./uuu FBK: ucp file/imx8x/bigdata.img t:-

图4
其中,ucp命令使用的参数t:-表示这个文件是传输到stdio pipe上,在这里是stdinacmd命令表示不等待命令返回,这里面的dd命令的if=其实就是从stdin里面拿到的,以此实现大文件的传输。

3、如果出现1:11 1/ 0 [Failure open usb device,Try ]的错误,原因是没有执行sudo


参考资料

u-boot/doc/README.android-fastboot
https://chromium.googlesource.com/aosp/platform/system/core/+/upstream/fastboot/
https://android.googlesource.com/platform/system/core/+/android-sdk-4.4.2_r1/fastboot/fastboot_protocol.txt

Title:i.MX8 uuu

Author:Victor Huang

Time:2019-07-03 / 22:07

Link:http://wowothink.com/2e4a33d4/

License: Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)