前言
-
可以参考 ubuntu 20.04 qemu linux6.0.1 制作ext4根文件系统
-
因为需要验证 aarch64 平台下的 glib 库,所以重新搭建了 Linux qemu arm64 的 测试环境
-
这一篇,开始制作 rootfs 根文件系统,让qemu arm64 平台上的 Linux 系统跑起来
开发环境
-
win10 64位 VMware Workstation Pro 16
-
ubuntu 20.04
-
qemu (虚拟ARM开发板),virt arm64 平台
-
Linux 6.3.8
下载并解压busybox
-
当前使用 busybox,可以快速制作Linux 根文件系统需要的常用命令,所以这里使用当前最新版本的busybox:
busybox-1.36.1.tar.bz2
-
busybox 官方下载地址:
https://busybox.net/downloads/busybox-1.36.1.tar.bz2
,当前可以直接到官方https://busybox.net/downloads/
下载最新的版本 -
把下载好的 busybox 放在 ubuntu 中,解压缩
$ ls
busybox-1.36.1.tar.bz2
$ tar xjvf busybox-1.36.1.tar.bz2
编译busybox
-
这里强调一点,如果需要一次性编译通过,需要使用
linux gcc
交叉编译工具链,如:aarch64-linux-gnu-xxx
这样的工具链中,集成了依赖Linux 相关的头文件 -
编译
busybox-1.36.1
,推荐的linux gcc 为:gcc-linaro-12.2.1-2023.04-x86_64_aarch64-linux-gnu.tar.xz
-
这里是qemu 的模拟器,直接编译即可,暂时不需要 menuconfig 手动修改配置
-
编译命令如下:
/* menuconfig 配置,直接保存即可 */
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
/* 创建 busybox 输出的路径 */
$ mkdir /home/zhangsz/linux/rootfs/1016
/* 编译, install,这样就可以把 busybox 的编译产物放在CONFIG_PREFIX的路径下 */
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- CONFIG_PREFIX=/home/zhangsz/linux/rootfs/1016/ install
busybox 编译的产物:
$ cd /home/zhangsz/linux/rootfs/1016/
$ ls
bin linuxrc sbin usr
- 注意 busybox 直接编译的产物,还是缺少很多lib库与命令,需要不断的丰富,Linux 内核启动控制台相关的一些东西,需要再补充
完善 rootfs
-
首先创建 rootfs 目录,然后把 busybox 的产物,全部复制到 rootfs 下
-
首先在 rootfs 下新创建一个
lib
目,复制 gcc 交叉编译工具链libc/lib/
下的库文件到rootfs/lib
目录 -
sudo cp -rf ../../tools/gcc-linaro-12.2.1-2023.04-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/libc/lib/* rootfs/lib
-
在Linux 内核目录执行生成
modules_install
的命令: -
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=../_install modules_install
-
然后 把 Linux 的 模块目录
lib
下的所有文件 复制到rootfs/lib
下
制作根文件系统
-
制作Linux 根文件系统目录的过程,各个平台其实都是大同小异的,不同的平台,选择相应的编译器。
-
这里使用脚本,快速的制作一个根文件系统目录模板,然后再把 busybox 的编译产物、gcc 交叉编译环境下的 lib 拷贝过来,就可以打包成制定的文件系统镜像了
-
create_rootfs.sh
生成 rootfs 的各个目录结构
#!/bin/bash
echo "------Create rootfs start...--------"
rootfs=$1
sudo rm -rfv $rootfs
sudo mkdir -v $rootfs
cd $rootfs
echo "--------Create root,dev....----------"
sudo mkdir root dev etc boot tmp var sys proc lib mnt home usr
sudo 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
cd ..
echo "-------make rootfs done---------"
make_boot.sh
脚本:制作 rootfs ext4 镜像
#!/bin/bash
echo "---------- make boot.img ------------"
img_ext=".img"
img_mnt="_mnt"
boot_img=$1${img_ext}
boot_img_mnt=$1${img_mnt}
echo ${boot_img}
echo ${boot_img_mnt}
sudo rm -rf ${boot_img}
sudo rm -rf ${boot_img_mnt}
dd if=/dev/zero of=${boot_img} bs=1M count=1024
mkfs.ext4 ${boot_img}
sudo mkdir ${boot_img_mnt}
sudo mount ${boot_img} ${boot_img_mnt}
sudo cp -rv $1/* ${boot_img_mnt}
sudo cp -rv rootfs/* ${boot_img_mnt}
sudo umount ${boot_img_mnt}
echo "------------ make boot.img end ---------"
boot_qemu.sh
:通过qemu-system-aarch64
启动 qemu
#!/bin/bash
echo "---------- boot qemu ----------"
echo $1
sudo qemu-system-aarch64 \
-M virt \
-cpu cortex-a57 \
-smp 4 \
-m 4G \
-kernel Image.gz \
-drive format=raw,file=$1 \
-nographic \
-append "noinitrd root=/dev/vda rw console=ttyAMA0 init=/linuxrc ignore_loglevel" \
run.sh
: 运行 qemu,第一次运行sudo ./run.sh
即可,后面可以通过sudo ./boot_qemu.sh rootfs_qemu.img
启动
#!/bin/bash
source create_rootfs.sh rootfs_qemu
source make_boot.sh rootfs_qemu
source boot_qemu.sh rootfs_qemu.img
启动 qemu
-
把 Linux 内核,当前是
linux-6.3.8
的内核镜像文件:linux-6.3.8/arch/arm64/boot/Image.gz
复制到 qemu 的启动目录下 -
qemu 启动的目录如下:
- 上面的制作rootfs 与启动 qemu 的脚本, Linux 内核镜像
Image.gz
,以及上面创建的rootfs
,基于这个rootfs
去生成 qemu 需要的 ext4 镜像
-rwxr-xr-x 1 zhangsz zhangsz 292 6月 18 17:22 boot_qemu.sh
-rwxr-xr-x 1 zhangsz zhangsz 1335 6月 18 12:39 create_rootfs.sh
-rw-r--r-- 1 zhangsz zhangsz 13141574 6月 18 12:37 Image.gz
-rwxr-xr-x 1 zhangsz zhangsz 517 6月 18 12:39 make_boot.sh
-rw-r--r-- 1 zhangsz zhangsz 463 6月 18 18:05 readme.md
drwxr-xr-x 7 zhangsz zhangsz 4096 6月 18 18:00 rootfs
-rwxr-xr-x 1 zhangsz zhangsz 118 6月 18 12:39 run.sh
-
第一次运行:会根据 rootfs 制作镜像
rootfs_qemu.img
,并调用 qemu 启动脚本boot_qemu.sh
启动,执行命令为:sudo ./run.sh
-
启动信息如下:
- 进程 Linux shell 命令行, 基于 qemu arm64 平台的 Linux ext4 根文件系统, 正确运行起来了
小结
-
以上是 基于 linux6.3.8 qemu arm64 平台 制作ext4根文件系统,Linux 内核的编译,参考 ubuntu 20.04 qemu arm64 linux6.3.8 开发环境搭建
-
qemu 可以用于嵌入式Linux 系统的开发前期的一些技术评估、功能验证,尤其是一些硬件平台无关的软件的功能开发验证,使用 qemu 模拟运行,会大大提高开发的效率
-
当前 qemu 不仅可以运行 Linux,还可以运行在 rt-smart 等系统上