1、下载软件:
模拟软件:qemu
sudo apt-get install qemu//可以在此基础上使用qemu-按Tab键查找你想模拟的内核环境
qemu-system-aarch64 --version//查看你所下载的版本
交叉编译工具:下载对应环境的交叉编译环境
sudo apt install gcc-aarch64-linux-gnu//针对arm64的交叉编译工具
aarch-linux-gnu-gcc --version//查看版本
2、编译内核
下载内核:内核版本是linux -5.4.34
sudo apt install axel//安装下载内核的工具
axel -n 20 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.34.tar.xz//下载内核代码
xz -d linux-5.4.34.tar.xz
tar -xvf linux-5.4.34.tar#解压文件
配置内核
配置内核菜单要是出错的话,则是缺什么安装什么就好
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- O=build defconfig//O=build指定输出在build文件夹下,不跟源码混在一起,保证源码整洁性
make ARCH=arm64 Image -j8 CROSS_COMPILE=aarch64-linux-gnu- O=build//因为指定了配置文件的输出目录所以编译时要制定配置文件的目录
sudo apt-get install libncurses5-dev build-essential git bison flex libssl-dev//安装一些库依赖
3、制作根文件系统
initramfs 即 initram file system,翻译成中文意思就是 初始 ram 文件系统,基于 tmpfs,是一种大小灵活,直接作用在内存中的文件系统。initramfs 包含的工具和脚本,在正式的根文件系统的初始化脚本 init 启动之前,就被挂载。initramfs 是可选的,内核编译选项默认开启 initramfs(initrd)。
initrd 是一个内存中的磁盘结构(ramdisk),其中包含必要的工具和脚本,用于在将控制权交给根文件系统上的 init 应用程序之前挂载所需的文件系统。Linux 内核在此根磁盘上触发安装脚本(通常称为linuxrc,但该名称不是必需的),此脚本的工作是准备系统,切换到真正的根文件系统,然后调用 init。
3.1下载制作根文件系统的软件
wget https://busybox.net/downloads/busybox-1.35.0.tar.bz2//下载制作根文件系统的软件
tar -xf busybox-1.35.0.tar.bz2//解压
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-//更改编译器环境为arm
make menuconfig
# 修改配置,选中如下项目,静态编译
# Settings –> Build Options –> [*] Build static binary(no share libs)
# 反选如下项目,否则后续qemu执行会提示 /bin/sh:can't access tty;job control turned off
# Shells ---> [ ] Job control
#静态编译,避免库依赖
make -j `nproc`//编译
make install//安装
cd _install//默认安装打源码目录下_install
3.2制作根文件系统
创建虚拟rootfs中的inti启动脚本,并赋予可执行权限:
cd _install
mkdir proc sys dev tmp
touch init//创建启动脚本空文件
chmod +x init//设置启动脚本权限
启动脚本内容如下:
#!/bin/sh
# 挂载一些必要的文件系统
mount -t proc none /proc
mount -t sysfs none /sys
mount -t tmpfs none /tmp
mount -t devtmpfs none /dev
echo
echo "Hello 64-bit ARM Linux"
# 显示开机消耗时间
echo "This boot took $(cut -d' ' -f1 /proc/uptime) seconds"
echo
# 停留在控制台
exec /bin/sh
initramfs 和我们常见的文件系统类似,可能存在 /usr、/bin 等目录。里面包含着我们的工具和脚本。initramfs 需要使用 cpio 来归档,cpio 是一个有着古老历史的文件归档解决方案,类似于 linux 中常用的 tar,或者 windows 中的 zip,主要作用是将多个文件打包成一个文件(但是没有压缩)。使用 cpio,是因为其代码易于实现,而且能够兼容更多的设备。
归档之后,需要考虑 initramfs 文件的体积,要进一步压缩,减少内存或磁盘的占用。所有文件,工具,库,配置设置(如果适用)等都放入 cpio 归档后,使用 gzip 实用程序压缩 cipo 文件,并将其与linux 内核一起存储。引导加载程序(通常是 grub 或者 uboot)将在引导时将其提供给内核,以便内核知道需要一个 initramfs。
内核一旦检测到 initramfs,会创建一个 tmpfs 文件系统,提取 gzip 中存档的 initramfs,并存入 tmpfs 中,内核启动 tmpfs 文件系统中的 init 脚本。该脚本用于挂载实际的根文件系统,当完成根文件系统和其他的一些重要的文件系统的安装之后,init 脚本会切换至真实的根文件系统,并在系统上调用 / sbin / init 二进制文件,进行后续的启动过程。
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initramfs.cpio.gz//打包
4、启动内核
qemu-system-aarch64 -M virt -cpu cortex-a57 -smp 8 -m 512M -kernel ./linux-5.4.34/build/arch/arm64/boot/Image -initrd ./busybox-1.35.0/initramfs.cpio.gz -nographic -append "init=/init console=ttyAMA0"//注意内核镜像存放的目录,以及根文件系统镜像存放的目录