• 内核调试环境:buildroot/debootstrap制作文件系统、编译内核、QEMU模拟


    编译内核

    # 安装常用工具和依赖,可能会多,懒得分了,全装了吧反正以后说不定还要用。。。
    sudo apt install curl wget gpg zsh tree git net-tools proxychains4 remmina vim tar strace llvm clang unzip gcc gcc-multilib build-essential flex bison cmake make gawk dkms autoconf ninja-build dpkg-dev libncurses-dev libssl-dev libelf-dev openssl libudev-dev libpci-dev libiberty-dev libdwarf-dev libdw-dev libcap-dev bpfcc-tools 
    # 安装pahole
    git clone --recursive https://github.com/acmel/dwarves
    cd dwarves
    mkdir build
    cd build
    cmake -D__LIB=lib ..
    make pahole
    sudo make install
    # 更新LD_LIBRARY,建议加进path里
    export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
    # 验证pahole,版本要求>=1.16
    pahole --version
    # 下载内核源码,从git.kernel.org下或者从github下咋都行
    # 在build目录下生成.config并编译生成vmlinux和bzImage
    make O=build menuconfig
    make O=build -j=$(nproc)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    使用debootstrap制作文件系统

    create-image.sh,DIR和PKGS、发行版架构可以自己选
    注意网卡名,如果qemu跑起来网卡名不一样,可以自己改,使用lshw命令方便看网卡名;注意如果不需要共享目录可以把hostshare那个挂载点那一行删了,不然默认启动挂载不上会进救援模式。

    #!/usr/bin/env bash
    set -eux
    
    DIR=rootfs
    
    PREINSTALL_PKGS=openssh-server,curl,wget,tar,gcc,gdb,zsh,tree,libc6-dev,time,strace,sudo,less,psmisc,selinux-utils,policycoreutils,checkpolicy,selinux-policy-default,firmware-atheros,debian-ports-archive-keyring
    
    ADD_PACKAGE="lshw,pciutils,make,sysbench,git,vim,tmux,usbutils,tcpdump,net-tools,ethtool"
    
    PREINSTALL_PKGS=$PREINSTALL_PKGS","$ADD_PACKAGE
    
    # ppc64le/aarch64/arm/x86_64
    ARCH=amd64
    
    RELEASE=stretch
    FEATURE=minimal
    SEEK=2047
    
    sudo rm -rf $DIR
    sudo mkdir -p $DIR
    sudo chmod 0755 $DIR
    
    # 1. debootstrap stage
    DEBOOTSTRAP_PARAMS="--foreign --arch=$ARCH --include=$PREINSTALL_PKGS --no-check-gpg --components=main,contrib,non-free $RELEASE $DIR https://mirrors.tuna.tsinghua.edu.cn/debian/"
    
    sudo debootstrap $DEBOOTSTRAP_PARAMS
    
    # 2. debootstrap stage: only necessary if target != host architecture
    
    # sudo cp $(which qemu-$ARCH-static) $DIR/$(which qemu-$ARCH-static)
    sudo chroot $DIR /bin/bash -c "/debootstrap/debootstrap --second-stage"
    
    # Set some defaults and enable promtless ssh to the machine for root.
    sudo sed -i '/^root/ { s/:x:/::/ }' $DIR/etc/passwd
    echo 'T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100' | sudo tee -a $DIR/etc/inittab
    printf '\nauto ens3\niface ens3 inet dhcp\n' | sudo tee -a $DIR/etc/network/interfaces
    echo '/dev/root / ext4 defaults 0 0' | sudo tee -a $DIR/etc/fstab
    echo 'debugfs /sys/kernel/debug debugfs defaults 0 0' | sudo tee -a $DIR/etc/fstab
    #echo 'securityfs /sys/kernel/security securityfs defaults 0 0' | sudo tee -a $DIR/etc/fstab
    #echo 'configfs /sys/kernel/config/ configfs defaults 0 0' | sudo tee -a $DIR/etc/fstab
    #echo 'binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0' | sudo tee -a $DIR/etc/fstab
    echo 'hostshare /data 9p trans=virtio,version=9p2000.L 0 0' | sudo tee -a $DIR/etc/fstab
    echo -en "127.0.0.1\tlocalhost\n" | sudo tee $DIR/etc/hosts
    echo "nameserver 223.5.5.5" | sudo tee -a $DIR/etc/resolve.conf
    echo "debian" | sudo tee $DIR/etc/hostname
    ssh-keygen -f $RELEASE.id_rsa -t rsa -N ''
    sudo mkdir -p $DIR/root/.ssh/
    cat $RELEASE.id_rsa.pub | sudo tee $DIR/root/.ssh/authorized_keys
    
    # Add udev rules for custom drivers.
    # Create a /dev/vim2m symlink for the device managed by the vim2m driver
    echo 'ATTR{name}=="vim2m", SYMLINK+="vim2m"' | sudo tee -a $DIR/etc/udev/rules.d/50-udev-default.rules
    
    # Build a disk image
    dd if=/dev/zero of=$RELEASE.img bs=1M seek=$SEEK count=1
    sudo mkfs.ext4 -F $RELEASE.img
    sudo mkdir -p /mnt/$DIR
    sudo mount -o loop $RELEASE.img /mnt/$DIR
    sudo cp -a $DIR/. /mnt/$DIR/.
    sudo umount /mnt/$DIR
    sudo chmod 666 $RELEASE.img
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    使用buildroot制作文件系统

    cd ~/buildroot-2022.02.4
    make list-defconfigs
    make qemu_x86_64_defconfig
    make menuconfig
    # 建议使用代理下载,proxychains 使用不再赘述
    proxychains make source
    export LD_LIBRARY_PATH=
    make V=1 j=1
    # 如果需要多线程编译j=$(nproc)
    # 需要在.config里设置BR2_PER_PACKAGE_DIRECTORIES=y
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    如果编译过程中host相关的出错了,可以考虑make clean以后重新j=1编译。

    config时几个分类的作用:

    • Target:配置目标的架构和文件格式
    • Build:配置构建时选项,例如文件存储位置,裁剪符号信息,下载源等
    • Toolchain:配置构建工具链,包括使用的C库、内核头、binutils、gcc版本等
    • System:配置构建的系统,host、password、网络接口名等
    • Kernel:构建的内核选项
    • Target packages:目标文件系统中需要的包
    • Filesystem:文件系统镜像选项,所需的格式、文件系统label等
    • Bootloader:构建的bootloader
    • Host:为主机host编译的工具

    编译后生成的几个目录作用:

    • images:存储内核、bootloader、文件系统镜像
    • build:host上所需的工具和为目标系统编译的包存储的位置(编译结果输出的目录)
    • host:包括host工具和目标工具链的sysroot(说白了就是可执行文件)
    • staging:host目录内目标工具链的sysroot符号链接
    • target:完整的文件系统,除了/dev/中的设备

    QEMU

    # 我常用的命令,分配2G内存1CPU,无显示输出
    # 挂载/pathto/stretch.img作为硬盘
    # kernel: /pathto/bzImage
    # 内核cmdline:"root=/dev/sda console=ttyS0 nokaslr"
    # 带一个9p共享目录,一个virtio网卡
    # 此处注意,建议使用root启动qemu,共享目录才可以写入
    # 共享目录在guest里的挂载方式下面有写
    qemu-system-x86_64 -m 2048 -smp 1 -display none -serial mon:stdio -no-reboot -enable-kvm -cpu host -hda /pathto/stretch.img -kernel /pathto/bzImage -append "root=/dev/sda console=ttyS0 nokaslr" -fsdev local,security_model=passthrough,id=fsdev0,path=/pathto/share/ -device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=hostshare -nic user,model=virtio
    
    # 硬件配置
    -cpu host -smp 1 -m 2048 -name test-pc
    -drive file=/home/susu/images/0817/stretch.img
    -hda /home/susu/images/0817/stretch.img
    -display none
    -nographic
    -enable-kvm     enable KVM full virtualization support
    -no-reboot      exit instead of rebooting
    
    #linux
    -kernel bzImage use 'bzImage' as kernel image
    -append cmdline use 'cmdline' as kernel command line
    -initrd file    use 'file' as initial ram disk
    -dtb    file    use 'file' as device tree image
    
    # 网络选项
    -nic user,model=virtio,ipv6=off,hostfwd=tcp::5555-:23 # 新选项,建议使用
    -net nic,model=virtio -net user
    
    # 共享目录
    -fsdev local,security_model=passthrough,id=fsdev0,path=/home/susu/share/ -device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=hostshare
    # 在guest的/etc/fstab写入如下行
    hostshare /data 9p trans=virtio,version=9p2000.L 0 0
    # 手动挂载
    mkdir /data
    mount -t 9p -o trans=virtio,version=9p2000.L hostshare /data
    # 编译内核时需要启用如下内核选项
    内核选项
    CONFIG_NET_9P=y
    CONFIG_9P_FS=y
    CONFIG_VIRTIO_PCI=y
    CONFIG_NET_9P_VIRTIO=y
    CONFIG_9P_FS_POSIX_ACL=y
    CONFIG_NET_9P_DEBUG=y (Optional可选)
    # gdb
    -gdb tcp::1358
    -S	# 会停在启动的位置
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    如果使用-serial mon:stdio,ctrl+c会被转发给客户机,不会在宿主机终端生效,结束qemu要么在guest里走正常的关机流程,buildroot的busybox是poweroff、debian是shutdown now,要么先按下ctrl+a,松开瞬间按下x退出qemu。

  • 相关阅读:
    Go语言---动态查询数据库
    nvm常用命令
    管理类联考——数学——汇总篇——知识点突破——数据分析——计数原理——排列组合——排队
    硬盘接口随机
    LeetCode 21. 合并两个有序链表
    Spark - 第15章 Spark如何在集群上运行
    Maven快速上手
    springboot基于微信小程序“智慧校园” 一体式的设计与实现毕业设计源码091634
    C语言【微项目19】—大整数字符串乘法器[纯字符串乘法][乘法表与加法表]【2022-11-27】
    【Python】如果修改了第三方库(包)的源代码,该怎么做才能还原呢
  • 原文地址:https://blog.csdn.net/weixin_49393427/article/details/126435589