配置busybox
下载busybox
https://github.com/mirror/busybox/releases/tag/1_36_0
配置busybox编译参数
make defconfig ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
make menuconfig ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
勾选编译静态库
Settings --->
[*] Build static binary (no shared libs)
编译busybox
make -j4 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
make install
busybox快速构建_install脚本
构建完整的根文件系统需要在_install目录下创建各类文件,因此直接将这些重复的动作写成一个脚本。
#!/bin/bash
set -x
BUSYBOX_PATH=$PWD
BUSYBOX_INSTALL_PATH=$PWD/_install
function add_info_to_busybox_rcS() {
pushd $BUSYBOX_INSTALL_PATH
cat << EOF > ./etc/init.d/rcS
mkdir -p /sys
mkdir -p /tmp
mkdir -p /proc
mkdir -p /mnt
/bin/mount -a
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
EOF
popd
}
function copy_lib_to_busybox_lib() {
pushd $BUSYBOX_INSTALL_PATH
sudo cp -rf /usr/aarch64-linux-gnu/lib/* ./lib
sudo cp -rf /usr/aarch64-linux-gnu/lib64/* ./lib
popd
}
function mknod_for_busybox_lib() {
pushd $BUSYBOX_INSTALL_PATH
pushd ./dev
sudo mknod -m 664 tty1 c 4 1
sudo mknod -m 664 tty2 c 4 2
sudo mknod -m 664 tty3 c 4 3
sudo mknod -m 664 tty4 c 4 4
sudo mknod -m 664 console c 5 1
sudo mknod -m 664 null c 1 3
popd
popd
}
function add_info_to_profile() {
pushd $BUSYBOX_INSTALL_PATH
cat << EOF > ./etc/profile
#!/bin/sh
export HOSTNAME=idle
export USER=timelessxp
export HOME=/home
export PS1="[timelessxp@qemu_arm64 \W]# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH
EOF
popd
}
function add_info_to_inittab() {
pushd $BUSYBOX_INSTALL_PATH
cat << EOF > ./etc/inittab
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
EOF
popd
}
function add_info_to_fstab() {
pushd $BUSYBOX_INSTALL_PATH
cat << EOF > ./etc/fstab
#device mount-point type options dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
debugfs /sys/kernel/debug debugfs defaults 0 0
#kmod_mount /mnt 9p trans=virtio 0 0
EOF
popd
}
function init_base_dir() {
pushd $BUSYBOX_INSTALL_PATH
mkdir data dev etc home lib mnt proc root sys tmp var
mkdir -p ./etc/init.d
pushd ./etc
# 下面这句可能导致init卡住
touch fstab inittab profile
popd
pushd $BUSYBOX_INSTALL_PATH/etc/init.d
touch rcS
chmod a+x rcS
popd
}
function main_function() {
pushd $BUSYBOX_INSTALL_PATH
init_base_dir
add_info_to_busybox_rcS
copy_lib_to_busybox_lib
mknod_for_busybox_lib
add_info_to_fstab
add_info_to_inittab
add_info_to_profile
popd
}
main_function
busybox快速制作rootfs脚本
上述的文件目录搭建完成后,可以通过以下脚本完成rootfs镜像的生成,需要使用root权限。
#!/bin/bash
if [ -f rootfs_ext4.img ];then
rm rootfs_ext4.img
fi
# 拷贝ko文件到指定的目录下,方便驱动代码的验证。
find ./my_code/drv_code -name "*.ko" | xargs -I {} cp -vf {} _install/my_drv/
dd if=/dev/zero of=rootfs_ext4.img bs=1M count=256
mkfs.ext4 rootfs_ext4.img
mkdir -p tmpfs
mount -t ext4 rootfs_ext4.img tmpfs/ -o loop
cp -af _install/* tmpfs/
umount tmpfs
rm -rf tmpfs
chmod 777 rootfs_ext4.img
cp rootfs_ext4.img ../linux
配置kernel
sudo apt-get install build-essential zlib1g-dev pkg-config libglib2.0-dev binutils-dev libboost-all-dev autoconf libtool libssl-dev libpixman-1-dev libpython-dev python-pip python-capstone virtualenv
# 编译
make defconfig ARCH=arm64
make ARCH=arm64 Image -j8 CROSS_COMPILE=aarch64-linux-gnu-
qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine type=virt -m 512 -smp 1 -nographic -kernel arch/arm64/boot/Image -drive format=raw,file=../busybox-1.35.0/rootfs_ext4.img -append "noinitrd root=/dev/vda rw console=ttyAMA0 loglevel=8" -fsdev local,id=kmod_dev,path=$PWD/kmodules,security_model=none -device virtio-9p-device,fsdev=kmod_dev,mount_tag=kmod_mount
使用 echo +30 > /sys/class/rtc/rtc0/wakealarm 可以触发休眠唤醒 echo "mem" > /sys/power/state
使用gdb调试kernel
gdb-multiarch vmlinux
target remote localhost:1234
c
dump QEMU的设备树
qemu-system-aarch64 -machine virt,dumpdtb=file.dtb -cpu cortex-a57 -machine type=virt -m 1024 -smp 4 -nographic -kernel arch/arm64/boot/Image -drive format=raw,file=./rootfs_ext4.img -append "noinitrd root=/dev/vda rw console=ttyAMA0 loglevel=8 nokasrl" -fsdev local,id=kmod_dev,path=$PWD/kmodules,security_model=none -device virtio-9p-device,fsdev=kmod_dev,mount_tag=kmod_mount
在-machine选项后面加上dumpdtb=file.dtb,就可以把设备树文件dump到file.dtb中。
dtb转dts
dtc -I dtb file.dtb -O dts -o file.dts
dts转dtb,并指定
dtc -O dtb -I dts file.dts -o file.dtb
指定的方法为:在启动qemu的时候,添加上-dtb file.dtb即可。
qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine type=virt -m 1024 -smp 4 -nographic -kernel arch/arm64/boot/Image -dtb file.dtb -drive format=raw,file=../../busybox-1.36.1/rootfs
_ext4.img -append "noinitrd root=/dev/vda rw console=ttyAMA0 loglevel=8 nokasrl" -fsdev local,id=kmod_dev,path=$PWD/kmodules,security_model=none -device virtio-9p-device,fsdev=kmod_dev,mount_ta
g=kmod_mount
问题记录
-
报modprobe binfmt-464c cannot be processed, kmod busy with 50 threads for more than 5 seconds now错误 解决方案:lib库缺失导致,确保copy的lib文件成功。
-
gdb停不住的问题 解决方案1:在-append选项中加上nokaslr 解决方案2:更换gdb版本。
-
cannot create /proc/sys/kernel/hotplug: nonexistent directory make menuconfig的时候,打开以下选项。 Device Drivers > Generic Driver Options > Support for uevent helper