Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LS104x] 使用FIT的kernel格式和initramfs #192

Open
carloscn opened this issue Sep 21, 2023 · 0 comments
Open

[LS104x] 使用FIT的kernel格式和initramfs #192

carloscn opened this issue Sep 21, 2023 · 0 comments

Comments

@carloscn
Copy link
Owner

carloscn commented Sep 21, 2023

在NXP的官方手册中,并没有给出如何使用initramfs。本文基于NXP的LS1046a的平台,对kernel、设备树以及initramfs进行FIT格式的打包,接着介绍如何启动initramfs以及如何从initramfs切换到真正的rootfs。LS1046a的分区已经FIT image的格式如下:

1. initramfs制作

1.1 导出initramfs

我们需要准备正确的initramfs的系统。通常initramfs系统有一些对于硬件的初始化的操作,所以对于不同嵌入式的平台,initramfs是不能够通用的。我们需要使用芯片原厂提供的initramfs。在NXP的bsp包中并没有给出initramfs的源文件,我们需要借助yocto工程中导出initramfs。

可以按照我下面的配置,也可以在initramfs的官方文档中使用他们的配置:

IMAGE_FSTYPES += "ext4 ext4.gz "
INITRAMFS_IMAGE = "core-image-base"
INITRAMFS_IMAGE_BUNDLE = "1"
IMAGE_FSTYPES = "ext4.gz"

initramfs的配置可以参考官方文档:https://docs.yoctoproject.org/ref-manual/variables.html#term-INITRAMFS_IMAGE

  • 如果你写的是core-image-base使用bitbake core-image-base
  • 如果你写的是core-image-minimal-initramfs 使用bitbake core-image-minimal-initramfs

输出的cpio.gz的文件就是initramfs的源文件。

1.2 修改initramfs

cpio.gz文件是一个gzip过的cpio文件。首先要解压:

gzip core-image-minimal-initramfs-ls1046ardb-20230920085754.cpio.gz

然后创建一个文件夹:

mkdir ramdisk && cd ramdisk && cp -r ../core-image-minimal-initramfs-ls1046ardb-20230920085754.cpio .

解cpio:

cpio -idmv < core-image-minimal-initramfs-ls1046ardb-20230920085754.cpio

开始修改文件(我目前的修改是改的rootfs的函数,主要意思就是把SD卡的mmcblk0p3分区挂载在/rootfs上)该脚本会自动switch_root到/rootfs

打包这里需要使用脚本操作(因为必须是root权限)

# /bin/bash

cd ramdisk
sudo find . | sudo cpio -H newc -o | gzip -9 > new_initramfs.cpio.gz

rm -rf ../new_initramfs.cpio.gz
mv new_initramfs.cpio.gz ../

这个脚本一定要sudo运行,否则会出现:https://wowothink.com/866559ba/ 提到的only root can use问题:

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!

参考:https://www.linuxquestions.org/questions/linux-software-2/nfs-rootfs-mount-only-root-can-mount-proc-on-proc-4175595326/

也就是说,之所以出现这种错误,是UID不匹配,我的.cpio.gz.u-boot文件中的文件UID是为1000,但是在mfgtools中执行的UID是为0(root用户),导致出现了问题。

此时,我们拿到了我们修改过的new_initramfs.cpio.gz 文件,一会,这部分要放入到FIT image中。

2. FIT image制作

这部分和一般的FIT image制作没有什么区别,我们需要准备:

  • Image.gz或者Image文件
  • 设备树二进制文件
  • initramfs.cpio.gz文件

撰写its脚本,命名为ls1046a_fit.its

/dts-v1/;

/ {
        description = "kernel+dtb/fdt fit image";
        #address-cells = <1>;

        images {
                kernel {
                        description = "kernel image";
                        data = /incbin/("Image.gz");
                        type = "kernel";
                        arch = "arm64";
                        os = "linux";
                        compression = "gzip";
			load = <0x94200000>;
			entry = <0x94200000>;
			kernel-version = <1>;
                        hash {
                                algo = "sha256";
                        };
                };

		initrd {
			description = "initrd for arm64";
			data = /incbin/("new_initramfs.cpio.gz");
			type = "ramdisk";
			arch = "arm64";
			os = "linux";
			compression = "gzip";
			load = <0x80000000>;
			entry = <0x80000000>;
			hash {
				algo = "sha256";
			};
		};

                fdt {
                        description = "dtb blob";
                        data = /incbin/("fsl-ok1046a-1133-5a59-c2.dtb");
                        type = "flat_dt";
                        arch = "arm64";
                        compression = "none";
                        load = <0xA0000000>;
                        fdt-version = <1>;
                        hash {
                                algo = "sha256";
                        };
                };
        };
        configurations {
                default = "standard";
                standard {
                        description = "Standard Boot";
                        kernel = "kernel";
                        fdt = "fdt";
                        ramdisk = "initrd";
                        hash {
                                algo = "sha256";
                        };
                };
        };
};

需要注意的是地址问题,注意load的地址和uboot的加载FIT image的地址不要重叠,否则无法启动

生成FIT image的命令是,如果找不到这个工具可以安装sudo apt install u-boot-tools

mkimage -f ls1046a_fit.its image.ub

最后我们得到一个image.ub文件。

3. uboot脚本

除此之外,还需要修改uboot脚本,让uboot去读取我们的FIT的image,并且从FIT格式的image启动。

3.1 bootargs

setenv bootargs 'console=ttyS0,115200 root=/dev/mmcblk0p3 rw rootwait earlycon=uart8250,mmio,0x21c0500; '

注意:root=/dev/mmcblk0p3 或者 /dev/ram0 这个都无所谓了,因为FIT格式会强制从initramfs启动,而且真正的rootfs也是由initramfs的脚本控制切换。

3.2 bootcmd

setenv bootcmd 'mmc dev 0; fatload mmc 0:2 0xb0000000 image.ub; bootm 0xb0000000'

我这部分是放在了/dev/mmcblk0p2中,因此从这里读取image.ub。

uboot阶段:

initramfs和rootfs阶段:

程序放在:https://github.com/carloscn/ls104x-bsp/tree/master/initramfs

End

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant