借助Linux操作系统中已有的工具,比如mkinitramfs构建rootfs
前提条件
(0) arm64物理服务器或虚拟机
(1) qemu-2.11.1: qemu-system-aarch64
(2) busybox-1.31.1
(3) 内核版本为linux-4.12
由于qemu的编译过程中存在-CFLAGS=-O2-g将不允许debug信息的出现,因此需要在./configure的时候添加–enable-debug(或–enable-debug --enable-debug-info)选项.为方便以后调试Qemu源码,本次安装将开启debug模式,即在配置选项中增加–enable-debug和–enable-debug-info选项
# ./configure --target-list=aarch64-softmmu, aarch64-linux-user --enable-debug --enable-debug-info
BusyBox配置选项:
# make menuconfig
并有如下设置:
Busybox Settings —>
— Build Options
[*] Build BusyBox as a position independent executable
编译安装
# make -j$(nproc)
# make install -j$(nproc)
1. 利用Linux操作系统提供的工具mkinitramfs
# mkinitramfs -o initramdisk
产生制作完成的根文件系统initramdisk,但该文件相对来说还是大了些,接下来将使用自制initramfs的方式创建根文件系统initramfs。
2. 利用busybox制作根文件系统
前提是已经安装了busybox
# cat gen_initramfs.sh
#!/bin/bash
ROOTFS=rootfs
BUSYBOX=$(find busybox* -maxdepth 0 -type d)
SYSROOT=$(gcc --print-sysroot)
GLIBC_VERSION=$(ldd --version | head -1 | cut -d' ' -f5)
DYNAMIC_LIB_PATH_64=/lib/aarch64-linux-gnu
rm -rf $ROOTFS
mkdir -p ${ROOTFS}/{proc,sys,dev,etc,etc/init.d,lib,lib64,mnt,tmp,go}
cat > $ROOTFS/etc/init.d/rcS <<EOF
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s
ifconfig lo up
EOF
chmod +x $ROOTFS/etc/init.d/rcS
cat > $ROOTFS/etc/inittab <<EOF
# /etc/inittab
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
EOF
chmod +x $ROOTFS/etc/inittab
cp -rP ${BUSYBOX}/_install/* ${ROOTFS}
cp -rP ${DYNAMIC_LIB_PATH_64}/libc-${GLIBC_VERSION}.so ${ROOTFS}/lib64/
cp -rP ${DYNAMIC_LIB_PATH_64}/libc.so.6 ${ROOTFS}/lib64/
cp -rP ${DYNAMIC_LIB_PATH_64}/libm-${GLIBC_VERSION}.so ${ROOTFS}/lib64/
cp -rP ${DYNAMIC_LIB_PATH_64}/libm.so.6 ${ROOTFS}/lib64/
cp -rP ${DYNAMIC_LIB_PATH_64}/librt-${GLIBC_VERSION}.so ${ROOTFS}/lib64/
cp -rP ${DYNAMIC_LIB_PATH_64}/librt.so.1 ${ROOTFS}/lib64/
cp -rP ${DYNAMIC_LIB_PATH_64}/libpthread-${GLIBC_VERSION}.so ${ROOTFS}/lib64/
cp -rP ${DYNAMIC_LIB_PATH_64}/libpthread.so.0 ${ROOTFS}/lib64/
cp -rP ${DYNAMIC_LIB_PATH_64}/ld-${GLIBC_VERSION}.so ${ROOTFS}/lib64/
cp -rP ${DYNAMIC_LIB_PATH_64}/ld-linux-x86-64.so.1 ${ROOTFS}/lib64/
cd ${ROOTFS}
ln -sf linuxrc init
find . | cpio -o --format=newc > ../initramfs
# make menuconfig
# make –j$(nproc)
需要重点关注两个文件:vmlinux和Image,分别位于
(1) linux-4.12/vmlinux
(2) linux-4.12/arch/arm64/boot/Image
以根文件系统方式启动
# qemu-system-aarch64 -smp 4 -M virt -cpu cortex-a57 -nographic -m 2048M -kernel linux-4.12/arch/arm64/boot/Image -append "console=ttyAMA0" -initrd initramdisk
调试内核
1. 默认添加gdbserver tcp::1234,命令之后添加参数选项 ‘-s’
# qemu-system-aarch64 -nographic -m 2048M -smp 4 -M virt -cpu host -enable-kvm -kernel linux-4.12/arch/arm64/boot/Image -initrd initramfs -append "console=ttyAMA0 init=/linuxrc rw" -s
# gdb -tui linux-4.12/vmlinux
该方式采用参数选项“-s”,默认添加“gdbserver tcp::1234”的方式,相当于在执行命令时已经启动了gdbserver和监听端口1234,在使用gdb 调试vmlinux时,只需要在gdb中输入"target remote :1234",即可启动调试。
2. 额外添加gdbserver tcp::1234, 命令行之后添加参数选项 ‘-S’
# qemu-system-aarch64 -nographic -m 2048M -smp 4 -M virt -cpu host -enable-kvm -kernel linux-4.12/arch/arm64/boot/Image -initrd initramfs -append "console=ttyAMA0 init=/linuxrc rw" -S
需要执行两步:
(1) 执行该命令后,需要按组合键“Ctrl + A + C”切换到Monitor模式,并输入gdbserver tcp::1234,然后按Enter键,出现“Waiting for gdb connection on device ‘tcp::1234’”;
(2) 另开一个terminal,在该处执行如下命令
# gdb -tui linux-4.12/vmlinux
然后在加载完内核调试文件后,输入"target remote :1234",对应(1)中设置的端口1234。
两步骤设置完成后,接下来就可以根据需要调试代码。
感谢相关作者!!!
Linux aarch64 编译 & qemu 搭建实验平台.
Linux内存管理之—环境搭建(在QEMU上运行Linux 5.4.0)
ramdisk文件系统制作和移植