前言
-
开发板型号: 【正点原子】 的 RK3568 开发板
AtomPi-CA1
-
使用 VMware 虚拟机
ubuntu 20.04
编译 busybox,并制作 emmc 中的 ext4 根文件系统 rootfs
下载 busybox
-
可以在 https://busybox.net/downloads/snapshots/ 下载最新的 busybox,当前下载的是
busybox-20240427.tar.bz2
-
解压缩
busybox-20240427.tar.bz2
,可以新建一个 busybox 目录,然进入 busybox 目录下,tar -xjf /mnt/hgfs/kernel/busybox-20240427.tar.bz2 -C ./
,注意存放busybox-20240427.tar.bz2
路径
编译 busybox
-
进入 解压后的 busybox 目录下,然后设置一下交叉编译工具链的路径,这里使用与编译 RK3568 Linux kernel 一样的交叉编译工具链,当前使用
gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu
-
可以新建一个
env_aarch64.sh
的脚本,设置gcc交叉编译环境变量
#!/bin/bash
export PATH=$PATH:/home/zhangsz/tools/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin
- 可以新建一个 编译脚本
mk.sh
,用编译 busybox
#!/bin/bash
make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- $1 $2 $3 $4 $5 $6 $7 $8
-
使能环境变量,
chmod 777 env_aarch64.sh
source env_aarch64.sh
,如果 gcc 交叉编译工具链环境变量永久设置好了,可以不需要这个操作 -
确认 gcc 交叉编译工具链有效
aarch64-linux-gnu-gcc -v
,注意 rk3568 属于 ARM64 位架构,需要使用aarch64
的 gcc 交叉编译工具链
- 编译方法
mk.sh menuconfig
,然后退出【保存】默认配置
-
mk.sh -j16
编译 busybox -
mk.sh install
安装,默认安装到 busybox 当前目录的_install
目录下
zhangsz@zhangsz:~/rk3568/busybox/busybox$ ls _install/
bin linuxrc sbin usr
- 只有 busybox,还不能完全称之为 最小根文件系统
rootfs
制作根文件系统 rootfs 目录
- 这里使用脚本
rootfs_create.sh
,快速创建 rootfs 目录
#!/bin/bash
echo "------Create rootfs start...--------"
busybox_rootfs=_install
if [ $# -eq 0 ]; then
echo "No rootfs Directory provided, use rootfs_new default."
rootfs=rootfs_new
else
echo "Number of arguments: $#"
echo "Use rootfs Directory : $1"
rootfs=$1
fi
if [ -d ${rootfs} ]; then
echo "${rootfs} Directory exists."
rm -rf ${rootfs}
else
echo "${rootfs} : Directory does not exist."
fi
echo "-------rootfs dir : ${rootfs} -------"
# rootfs=$1
# rm -rf $rootfs
mkdir ${rootfs}
cd ${rootfs}
echo "--------Create root,dev....----------"
mkdir root dev etc boot tmp var sys proc lib lib64 mnt home usr
mkdir etc/init.d etc/rc.d
echo "make node in dev/console dev/null"
# sudo mknod -m 600 dev/console c 5 1
# sudo mknod -m 600 dev/null c 1 3
# create etc config /etc/inittab
echo -e "::sysinit:/etc/init.d/rcS " >etc/inittab
echo -e "::askfirst:-/bin/sh " >>etc/inittab
echo -e "::ctrlaltdel:/sbin/reboot " >>etc/inittab
echo -e "::shutdown:/bin/umount -a -r " >>etc/inittab
# create etc config /etc/init.d/rcs
echo -e "#! /bin/sh " >etc/init.d/rcS
echo -e "mount -t sysfs none /sys " >>etc/init.d/rcS
echo -e "mount -t proc none /proc " >>etc/init.d/rcS
echo -e "mount -t tmpfs tmpfs /tmp" >>etc/init.d/rcS
echo -e "mdev -s " >>etc/init.d/rcS
chmod +x etc/init.d/rcS
# create etc config /etc/fstab
echo -e "proc /proc proc defaults 0 0 " >etc/fstab
echo -e "sysfs /sys sysfs defaults 0 0 " >>etc/fstab
echo -e "devtmpfs /dev devtmpfs defaults 0 0 " >>etc/fstab
echo -e "tmpfs /tmp tmpfs defaults 0 0 " >>etc/fstab
echo -e "tmpfs /var tmpfs defaults 0 0 " >>etc/fstab
echo "-------make rootfs done---------"
cd ..
cp -r ${busybox_rootfs}/* ${rootfs}
-
脚本说明:
busybox_rootfs=_install
指向 busybox 编译后安装 install 的目录 -
制作 ext4 镜像时,可能
dev/console
与dev/null
提示异常,可以不生成,依旧能正常进入 Linux 控制台 -
运行
chmod 777 rootfs_create.sh
./rootfs_create.sh
即可生成 rootfs 目录
拷贝 lib
-
需要把 gcc 交叉编译工具链中的 libc 下的 lib 与 lib64 拷贝到 rootfs 目录下的 lib 与 lib64 目录,这些是一些 动态共享库
-
sudo cp -rf /home/zhangsz/tools/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/aarch64-linux-gnu/libc/lib/* rootfs_new/lib/
-
sudo cp -rf /home/zhangsz/tools/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/aarch64-linux-gnu/libc/lib64/* rootfs_new/lib64/
-
可以查看一下 拷贝的 lib 共享库, lib 下主要是
ld-linux-aarch64.so.1
,默认是一个 文件软链接,lib64 目录下文件较多
$ ls lib
ld-linux-aarch64.so.1
$ ls lib64/
ld-2.28.so libc.so.6 libnss_compat-2.28.so libnss_hesiod-2.28.so librt.so.1
libanl-2.28.so libdl-2.28.so libnss_compat.so.2 libnss_hesiod.so.2 libSegFault.so
libanl.so.1 libdl.so.2 libnss_db-2.28.so libpcprofile.so libthread_db-1.0.so
libBrokenLocale-2.28.so libm-2.28.so libnss_db.so.2 libpthread-2.28.so libthread_db.so.1
libBrokenLocale.so.1 libmemusage.so libnss_dns-2.28.so libpthread.so.0 libutil-2.28.so
libc-2.28.so libm.so.6 libnss_dns.so.2 libresolv-2.28.so libutil.so.1
libcrypt-2.28.so libnsl-2.28.so libnss_files-2.28.so libresolv.so.2
libcrypt.so.1 libnsl.so.1 libnss_files.so.2 librt-2.28.so
拷贝 Linux 内核编译的 ko
- 如果内核编译后,生成了 ko 目录,下面有个 lib 目录,需要把 ko 目录下的
lib
目录 拷贝到 rootfs/lib 目录下,如果不拷贝,一些依赖的 ko 可能无法正常加载,导致驱动无法正常工作
制作 ext4 文件系统镜像
-
这里使用
make_ext4fs
-
首先确认 ext4 mmc rootfs 分区的大小,可以在 u-boot 下 运行
mmc part
查看
=> mmc part
Partition Map for MMC device 0 -- Partition Type: EFI
Part Start LBA End LBA Name
Attributes
Type GUID
Partition GUID
1 0x00004000 0x00005fff "uboot"
attrs: 0x0000000000000000
type: 05660000-0000-4873-8000-5a20000035d8
guid: b4250000-0000-4628-8000-7544000002ba
2 0x00006000 0x00085fff "boot"
attrs: 0x0000000000000000
type: 7c180000-0000-4f18-8000-50a800001445
guid: 3b690000-0000-4079-8000-2a4a00007a87
3 0x00086000 0x0733bfbf "rootfs"
attrs: 0x0000000000000000
type: 0e110000-0000-461a-8000-5c66000022cd
guid: 614e0000-0000-4b53-8000-1d28000054a9
=>
-
这里 “rootfs” 分区
0x00086000 0x0733bfbf "rootfs"
大小为(0x0733bfbf - 0x00086000 + 1)* 512
字节 -
因此制作 ext4 镜像的命令
make_ext4fs -l 58731M -s rootfs.img rootfs_qemu/
,注意我当前的 rootfs 目录是 rootfs_qemu,58731M 是上面计算出来的 rootfs 分区大小 -
生成的镜像:
rootfs.img
,可以使用 RK 工具烧写到 rootfs 分区
烧写后运行
-
运行后,发现新制作的文件系统正常工作了
-
u-boot 启动参数
bootargs=console=ttyS2,1500000 earlycon=uart8250,mmio32,0xfe660000 root=/dev/mmcblk0p3 rootfstype=ext4 rw rootwait
bootcmd=ext4load mmc 0:2 0x280000 Image;ext4load mmc 0:2 0x8300000 rk3568-atk-atompi-ca1.dtb;booti 0x280000 - 0x8300000
- 自此,rk3568 开发板 最小 ext4 rootfs 根文件系统制作完成
小结
-
rk3568 属于 aarch64 (ARM 64位)平台,需要使用相应的 aarch64 gcc 交叉编译工具链 编译 busybox
-
基于 busybox 根文件系统的制作方法其实不难,当前后续可以继续完善,加入一些库与应用程序,让 Linux 内核功能丰富起来