编译一个 AArch64 平台的最小 Linux 内核
总结一下最近折腾的事情,方便以后查阅。
所有内容都假设已经安装了必须的构建工具链,如果没有装,可以在报错的时候再根据提示安装。
编译 BusyBox
需要先编译一个 BusyBox 作准备,之后作为 rootfs 加载。
在 这里 下载适当版本的 BusyBox 源码并解压,然后运行:
cd busybox-1.32.0
mkdir build
make O=build ARCH=arm64 defconfig
make O=build ARCH=arm64 menuconfig
这会首先生成默认配置,然后开启一个配置菜单。在「Settings」里面修改下面几项配置:
[*] Don't use /usr
[*] Build static binary (no shared libs)
(aarch64-linux-gnu-) Cross compiler prefix
然后保存并退出。运行:
make O=build # -j8
make O=build install
cd build/_install
这会使用刚刚保存的配置进行编译,然后安装到 build/_install
目录,此时该目录如下:
$ tree -L 1 .
.
├── bin
├── linuxrc -> bin/busybox
└── sbin
2 directories, 1 file
接着创建一些空目录:
mkdir -pv {etc,proc,sys,usr/{bin,sbin}}
然后创建一个 init
文件,内容如下:
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
echo -e "\nBoot took $(cut -d' ' -f1 /proc/uptime) seconds\n"
exec /bin/sh
修改 init
文件为可执行:
chmod +x init
此时当前目录(build/_install
)内容如下:
$ tree -L 1 .
.
├── bin
├── etc
├── init
├── linuxrc -> bin/busybox
├── proc
├── sbin
├── sys
└── usr
6 directories, 2 files
把这些目录和文件打包:
find . -print0 | cpio --null -ov --format=newc | gzip > ../initramfs.cpio.gz
生成的 gzip 压缩后的 cpio 映像放在了 build/initramfs.cpio.gz
,此时 BusyBox ramdisk 就做好了,保存备用。
编译最小配置的 Linux 内核
在 这里 下载适当版本的内核源码并解压,然后运行:
cd linux-5.8.8
mkdir build
make O=build ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- allnoconfig
make O=build ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
这会首先初始化一个最小的配置(allnoconfig
),然后打开配置菜单。在配置菜单中做以下修改:
-> General setup
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
-> General setup
-> Configure standard kernel features
[*] Enable support for printk
-> Executable file formats / Emulations
[*] Kernel support for ELF binaries
[*] Kernel support for scripts starting with #!
-> Device Drivers
-> Generic Driver Options
[*] Maintain a devtmpfs filesystem to mount at /dev
[*] Automount devtmpfs at /dev, after the kernel mounted the rootfs
-> Device Drivers
-> Character devices
[*] Enable TTY
-> Device Drivers
-> Character devices
-> Serial drivers
[*] ARM AMBA PL010 serial port support
[*] Support for console on AMBA serial port
[*] ARM AMBA PL011 serial port support
[*] Support for console on AMBA serial port
-> File systems
-> Pseudo filesystems
[*] /proc file system support
[*] sysfs file system support
完成后保存并退出,再运行:
make O=build ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- # -j8
即可编译 Linux 内核,编译出来的两个东西比较有用,一个是 build/vmlinux
,另一个是 build/arch/arm64/boot/Image
,前者是 ELF 格式的内核,可以用来在 GDB 中加载调试信息,后者是可启动的内核映像文件。
编译 qemu-system-aarch64
这一步是可选的,直接使用包管理器安装 QEMU 也可以。
在 这里 下载适当版本的 QEMU 源码并解压,然后运行:
cd qemu-5.0.0
mkdir build
cd build
../configure --target-list=aarch64-softmmu
make # -j8
即可编译 AArch64 目标架构的 QEMU。
启动 Linux
为了清晰起见,回到上面三个源码目录的外层,即当前目录中内容如下:
$ tree -L 1 .
.
├── busybox-1.32.0
├── linux-5.8.8
└── qemu-5.0.0
3 directories, 0 files
然后使用 QEMU 启动刚刚编译的 Linux:
./qemu-5.0.0/build/aarch64-softmmu/qemu-system-aarch64 \
-machine virt -cpu cortex-a53 -smp 1 -m 2G \
-kernel ./linux-5.8.8/build/arch/arm64/boot/Image \
-append "console=ttyAMA0" \
-initrd ./busybox-1.32.0/build/initramfs.cpio.gz \
-nographic
这里使用了 QEMU 的 virt 平台。