从这边篇开始我们一起研究ftrace的内核实现,我是基于较近长期维护版本linux 5.4,不过我们先不着急看代码,先把开发环境搭建一下。Qemu+arm64
安装必要软件
sudo apt install libncurses5-dev openssl libssl-dev \
build-essential pkg-config libc6-dev bison flex libelf-dev \
zlibc minizip libidn11-dev libidn11 qttools5-dev liblz4-tool \
gcc-arm-linux-gnueabi gcc-aarch64-linux-gnu
//安装qemu
sudo apt install qemu qemu-kvm qemu-system-arm virt-manager
下载代码
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.120.tar.gz
wget https://busybox.net/downloads/busybox-1.32.0.tar.bz2
或者可以使用加速软件
axel -n 10 -o ./ https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.120.tar.gz
axel -n 10 -o ./ https://busybox.net/downloads/busybox-1.32.0.tar.bz2
编译内核
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
make defconfig
make Image -j8
配置内核支持支持ftrace
配置编译busybox
make menuconfig
make && make install
至此,在busybox目录下生成了'_intall' 目录,将作为我们构建根文件系统的目录,在根文件系统目录下补充一些内容。
增加以下目录:
- etc :主要存放一些配置文件如:inittab(init进程会解析此文件,看进一步动作);fstab(主要包含一些挂载的文件系统,如sys proc) init.rd/rcS(可存放一些可执行脚本,配合inittab使用)
- proc : proc文件系统挂载点
- sys : sys文件系统挂载点
- tmp : tmp文件系统挂载点
- dev : 设备文件
- lib : 库文件目录(如果busybox采用动态链接库,则需要将交叉编译链的库文件拷这里)
mkdir -p /etc/init.d/ proc sys tmp dev lib dev mnt
a. dev目录下静态创建如下节点:
sudo mknod -m 666 tty1 c 4 1
sudo mknod -m 666 tty2 c 4 2
sudo mknod -m 666 tty3 c 4 3
sudo mknod -m 666 tty4 c 4 4
sudo mknod -m 666 console c 5 1
sudo mknod -m 666 null c 1 3
console 和 null 是必须的,如果没有则会报错。
b. etc/inittab 文件内容如下,可参考busyboxdir/examples/inittab编写:
::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restart:/sbin/init
tty2::askfirst:/bin/sh
tty3::askfirst:/bin/sh
tty4::askfirst:/bin/sh
c. etc/fstab 文件内容如下,主要目的是指明一些文件系统挂载点:
#device mount-point type option dump fsck order
proc /proc proc defaults 0 0
temps /tmp rpoc defaults 0 0
none /tmp ramfs defaults 0 0
sysfs /sys sysfs defaults 0 0
mdev /dev ramfs defaults 0 0
d.添加 init 文件
rm linuxrc
vim init
chmod a+x init
init 文件内容
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
mount -t debugfs nodev /sys/kernel/debug
exec /sbin/init
e. lib 文件拷贝
cp /usr/aarch64-linux-gnu/lib/* lib/
f.打包根文件系统
find . | cpio -o -H newc |gzip > /home/lucky/Project/qemu-aarch64/qemu/rootfs.cpio.gz
gdb运行
启动测试QEMU环境,通过gdb remote功能,链接QEMU并调试内核。有一点需要注意,由于我们调试的是ARM64模拟环境,需要使用"gdb-multiarch"而不是ubuntu自带的gdb工具,如果系统没有可以通过下面命令安装:
sudo apt-get install gdb-multiarch
启动参数
qemu-system-aarch64 \
-machine virt,virtualization=true,gic-version=3 \
-nographic \
-m size=1024M \
-cpu cortex-a57 \
-smp 2 \
-kernel Image \
-initrd rootfs.cpio.gz \
-S -gdb tcp::9000 \
--append "console=ttyAMA0 rdinit=/linuxrc"
-smp 核数目 -m 物理内存大小 -kernel 内核压缩镜像位置 -initrd rootfs位置 -nographic 不使用图形界面,不加可能会因为无法启动图形界面而失败 -append cmdline启动参数 -S 在入口处阻塞CPU -gdb tcp::xxxx 指定通信通道为 本地tcp通道(因为是在同一个机器上),端口号为xxxx,如果不需要指定端口号可以用-s 代替
# 新开一个窗口启动gdb并链接
gdb-multiarch vmlinux
(gdb)target remote :9000
(gdb)break start_kernel
(gdb)continue
(gdb)step
参考文章: