fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot注入程序

需求

NXP release出来的mfgtools默认自带fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot文件,这个文件是mfgtools的uramdisk.img,里面自带uuc应用程序,用于进行UTP传输,可以接收ucl2.xml中指定的命令并执行。
我们需要在mfgtools烧录过程中执行某个动作,有对应的应用程序,现需要将这个应用程序打包进fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot中,以下列出2种实现方案。


方案1:解压再打包进去

我的想法是将fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot文件解压出来,然后将应用程序拷贝进去,再原模原样的打包。以下为步骤:

  • 1.查看原文件
    1
    2
    # file fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot
    fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot: u-boot legacy uImage, fsl-image-mfgtool-initramfs-imx8\037\213\010, Linux/ RAMDisk Image (Not compressed), 9406408 bytes, Thu Jun 28 09:30:50 2018, Load Address: 0x00000000, Entry Point: 0x00000000, Header CRC: 0x473F16A9, Data CRC: 0x69DB3466

发现这个文件的头64字节为u-boot头信息,u-boot的头信息格式如下,我们可以通过mkimage产生u-boot头信息。:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef struct image_header {
uint32_t ih_magic; /* Image Header Magic Number */
uint32_t ih_hcrc; /* Image Header CRC Checksum */
uint32_t ih_time; /* Image Creation Timestamp */
uint32_t ih_size; /* Image Data Size */
uint32_t ih_load; /* Data Load Address */
uint32_t ih_ep; /* Entry Point Address */
uint32_t ih_dcrc; /* Image Data CRC Checksum */
uint8_t ih_os; /* Operating System */
uint8_t ih_arch; /* CPU architecture */
uint8_t ih_type; /* Image Type */
uint8_t ih_comp; /* Compression Type */
uint8_t ih_name[IH_NMLEN]; /* Image Name */
} image_header_t;

  • 2.舍弃前64字节的u-boot头信息
    这一步是将.cpio.gz.u-boot变成.cpio.gz文件,查看.cpio.gz文件类型:

    1
    2
    3
    4
    5
    6
    7
    # dd if=fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot of=fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz bs=1 skip=64
    记录了9451495+0 的读入
    记录了9451495+0 的写出
    9451495字节(9.5 MB)已复制,9.37393 秒,1.0 MB/秒

    # file fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz
    fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz: gzip compressed data, from Unix, last modified: Fri Oct 26 17:31:38 2018
  • 3.解压.cpio.gz文件
    这一步是将.cpio.gz文件解压为.cpio文件:

    1
    2
    3
    # gunzip fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz 
    # file fsl-image-mfgtool-initramfs-imx_mfgtools.cpio
    fsl-image-mfgtool-initramfs-imx_mfgtools.cpio: ASCII cpio archive (SVR4 with no CRC)
  • 4.解压.cpio文件

    1
    2
    3
    # mkdir rootfs
    # cd rootfs /
    # cpio -i -F ../fsl-image-mfgtool-initramfs-imx_mfgtools.cpio

解压.cpio文件后,可以在rootfs/目录下查看fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot文件的原始目录结构。
目录结构为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
总用量 1096
drwxr-xr-x 17 root root 4096 10月 29 18:03 ./
drwxrwxr-x 3 root root 4096 10月 29 17:56 ../
drwxr-xr-x 2 root root 4096 10月 29 17:56 bin/
drwxr-xr-x 2 root root 4096 10月 29 17:55 boot/
drwxr-xr-x 2 root root 4096 10月 29 17:55 dev/
drwxr-xr-x 10 root root 4096 10月 29 17:55 etc/
-rw-r--r-- 1 root root 1048576 10月 29 17:55 fat
drwxr-xr-x 3 root root 4096 10月 29 17:55 home/
-rw-r--r-- 1 root root 0 10月 29 17:55 init
drwxr-xr-x 3 root root 4096 10月 29 17:55 lib/
-rwxr-xr-x 1 root root 1450 10月 29 18:03 linuxrc*
drwxr-xr-x 2 root root 4096 10月 29 17:55 media/
drwxr-xr-x 2 root root 4096 10月 29 17:55 mnt/
drwxr-xr-x 2 root root 4096 10月 29 17:55 proc/
drwxr-xr-x 2 root root 4096 10月 29 17:55 run/
drwxr-xr-x 2 root root 4096 10月 29 17:55 sbin/
drwxr-xr-x 2 root root 4096 10月 29 17:55 sys/
drwxrwxrwt 2 root root 4096 10月 29 17:55 tmp/
drwxr-xr-x 9 root root 4096 10月 29 17:55 usr/
drwxr-xr-x 8 root root 4096 10月 29 17:55 var/

  • 5.注入应用程序
    实际上就是拷贝:# cp -rf ~/app ./bin/

  • 6.原样打包文件

    1
    # find . |cpio -ov -H newc | gzip -f -9 -n -c > ../fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz
  • 7.添加u-boot头信息
    将打包生成的fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz文件拷贝到u-boot源码目录下,用u-boot源码中的mkimage工具添加u-boot头信息。
    这一步将.cpio.gz文件进一步打包成.cpio.gz.u-boot文件,生成的.cpio.gz.u-boot文件中u-boot的头信息基本与原先的文件一致(crc和size大小有差异)。

    1
    2
    3
    4
    5
    6
    7
    # ./tools/mkimage -A arm64 -O linux -T ramdisk -C none -n fsl-image-mfgtool-initramfs-imx8 -d fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot
    Image Name: fsl-image-mfgtool-initramfs-imx8
    Created: Mon Oct 29 20:20:17 2018
    Image Type: AArch64 Linux RAMDisk Image (uncompressed)
    Data Size: 9447708 Bytes = 9226.28 KiB = 9.01 MiB
    Load Address: 00000000
    Entry Point: 00000000

mkimage工具的使用参照:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/tools/mkimage: invalid option -- '-'
Error: Invalid option
Usage: ./tools/mkimage -l image
-l ==> list image header information
./tools/mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image
-A ==> set architecture to 'arch'
-O ==> set operating system to 'os'
-T ==> set image type to 'type'
-C ==> set compression type 'comp'
-a ==> set load address to 'addr' (hex)
-e ==> set entry point to 'ep' (hex)
-n ==> set image name to 'name'
-d ==> use image data from 'datafile'
-x ==> set XIP (execute in place)
./tools/mkimage [-D dtc_options] [-f fit-image.its|-f auto|-F] [-b <dtb> [-b <dtb>]] [-i <ramdisk.cpio.gz>] fit-image
<dtb> file is used with -f auto, it may occur multiple times.
-D => set all options for device tree compiler
-f => input filename for FIT source
-i => input filename for ramdisk file
Signing / verified boot not supported (CONFIG_FIT_SIGNATURE undefined)
./tools/mkimage -V ==> print version information and exit
Use -T to see a list of available image types


使用方案1有可能出现的问题

使用打包的方法,最终mfgtools烧录mini kernel起来后加载rootfs有可能会出现以下的错误:

1
2
3
4
5
6
7
mount: only root can use "--types" option (effective UID is 1000)
mount: only root can use "--types" option (effective UID is 1000)
mount: only root can use "--types" option (effective UID is 1000)
mount: only root can use "--types" option (effective UID is 1000)

ls: cannot access '/sys/class/udc': No such file or directory
No udc Available!

因为在fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot中的linuxrc文件的开头会去挂载sysfs/proc等文件。如下:

1
2
3
4
5
6
7
#!/bin/sh
export PATH=/sbin:/bin:/usr/sbin:/usr/bin

mount -t sysfs none /sys
mount -t proc none /proc
mount -t devtmpfs none /dev
mount -t configfs none /sys/kernel/config

根据 https://www.linuxquestions.org/questions/linux-software-2/nfs-rootfs-mount-only-root-can-mount-proc-on-proc-4175595326/ 文章的说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
"effective UID is 1000" - It thinks you are NOT root which is UID 0. 
Did you login as something else then su to root?

On NFS server side, I'm using the Yocto to generate the target rootfs.
The UID and GID for my PC account is 1000, thus the UID and GID for all of
the files of target rootfs generated by Yocto is 1000,
including bin/mount binary. Also, bin/mount has SUID bit set.

So, what happen is that target boots, NFS mount is done successfully,
and mounted rootfs contains bin/mount whose UID and GID are 1000 and SUID set.
Thus, bin/mount is executed as non-root user because of SUID,
and resulted in the mount error.
Confirmed either changing SUID of bin/mount to disable or
changing UID and GID of roofs to root resolved this issue.

But, I'm curious how the people using Yocto avoid this issue...
I would not like to manually change the UID and GID,
or SUID every time whenever build the rootfs.
I also would not like to use root account to generate target rootfs.

也就是说,之所以出现这种错误,是UID不匹配,我的.cpio.gz.u-boot文件中的文件UID是为1000,但是在mfgtools中执行的UID是为0(root用户),导致出现了问题。
解决办法是将上述所有的步骤按照root权限去操作。


方案2:使用yocto编译出fsl-image-mfgtool-initramfs

编译fsl-image-mfgtool-initramfs-v的选项输出编译log。

1
2
# bitbake -f -c compile fsl-image-mfgtool-initramfs
# bitbake -v fsl-image-mfgtool-initramfs

目前这个方案还没实现成功,不清楚需要将应用程序拷贝到哪个目录进行编译打包。

Title:fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot注入程序

Author:Victor Huang

Time:2019-07-03 / 21:07

Link:http://wowothink.com/866559ba/

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