使用qemu模拟X86处理器加载linux kernel+busybox文件系统并调试

使用qemu模拟X86处理器加载linux kernel+busybox文件系统并调试

make x86_64_defconfig
make menuconfig
make bzImage -j8

要用到ramdisk的启动方式,需要在kernel配置中支持
General setup  --->
     ----> [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support

Device Drivers  --->
     [*] Block devices  --->
             <*>   RAM block device support
             (65536) Default RAM disk size (kbytes)


config文件的主要改动
总结下来,共有以下几处关键改动:
Initial RAM filesystem and RAM disk支持要打开
RAM block device support要打开而且设置Default RAM disk size
VIRTIO驱动要选到Y而不是M
CONFIG_JFS_FS文件系统支持要打开

--- config-bk    2019-08-02 16:57:42.567592700 +0800
+++ config-new    2019-08-02 16:57:42.572105900 +0800
@@ -157,7 +157,14 @@
 # CONFIG_SCHED_AUTOGROUP is not set
 # CONFIG_SYSFS_DEPRECATED is not set
 CONFIG_RELAY=y
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+CONFIG_RD_LZ4=y
 CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
@@ -461,6 +468,7 @@
 CONFIG_ACPI_THERMAL=y
 CONFIG_ACPI_NUMA=y
 CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE=y
+CONFIG_ACPI_TABLE_UPGRADE=y
 # CONFIG_ACPI_DEBUG is not set
 # CONFIG_ACPI_PCI_SLOT is not set
 CONFIG_ACPI_CONTAINER=y
@@ -735,6 +743,7 @@
 
 CONFIG_BLOCK_COMPAT=y
 CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_MQ_VIRTIO=y
 CONFIG_BLK_PM=y
 
 #
@@ -789,6 +798,8 @@
 CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
 # CONFIG_MEMORY_HOTPLUG is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MEMORY_BALLOON=y
+CONFIG_BALLOON_COMPACTION=y
 CONFIG_COMPACTION=y
 CONFIG_MIGRATION=y
 CONFIG_PHYS_ADDR_T_64BIT=y
@@ -1331,9 +1342,13 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SKD is not set
 # CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65536
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+CONFIG_VIRTIO_BLK=y
+CONFIG_VIRTIO_BLK_SCSI=y
 # CONFIG_BLK_DEV_RBD is not set
 # CONFIG_BLK_DEV_RSXX is not set
 
@@ -1647,6 +1662,7 @@
 # CONFIG_TUN is not set
 # CONFIG_TUN_VNET_CROSS_LE is not set
 # CONFIG_VETH is not set
+# CONFIG_VIRTIO_NET is not set
 # CONFIG_NLMON is not set
 # CONFIG_ARCNET is not set
 
@@ -2293,12 +2309,14 @@
 # end of Serial drivers
 
 # CONFIG_SERIAL_DEV_BUS is not set
+# CONFIG_VIRTIO_CONSOLE is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
 # CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_HW_RANDOM_INTEL is not set
 # CONFIG_HW_RANDOM_AMD is not set
 CONFIG_HW_RANDOM_VIA=y
+# CONFIG_HW_RANDOM_VIRTIO is not set
 CONFIG_NVRAM=y
 # CONFIG_APPLICOM is not set
 
@@ -2842,6 +2860,7 @@
 # CONFIG_DRM_CIRRUS_QEMU is not set
 # CONFIG_DRM_QXL is not set
 # CONFIG_DRM_BOCHS is not set
+# CONFIG_DRM_VIRTIO_GPU is not set
 CONFIG_DRM_PANEL=y
 
 #
@@ -3591,9 +3610,14 @@
 # CONFIG_UIO is not set
 # CONFIG_VFIO is not set
 # CONFIG_VIRT_DRIVERS is not set
+CONFIG_VIRTIO=y
 CONFIG_VIRTIO_MENU=y
-# CONFIG_VIRTIO_PCI is not set
-# CONFIG_VIRTIO_MMIO is not set
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_PCI_LEGACY=y
+CONFIG_VIRTIO_BALLOON=y
+CONFIG_VIRTIO_INPUT=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
 
 #
 # Microsoft Hyper-V guest support
@@ -3834,7 +3858,9 @@
 # CONFIG_VALIDATE_FS_PARSER is not set
 CONFIG_FS_IOMAP=y
 # CONFIG_EXT2_FS is not set
-# CONFIG_EXT3_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_USE_FOR_EXT2=y
 CONFIG_EXT4_FS_POSIX_ACL=y
@@ -3844,7 +3870,11 @@
 # CONFIG_JBD2_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
+CONFIG_JFS_FS=y
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+CONFIG_JFS_DEBUG=y
+CONFIG_JFS_STATISTICS=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
@@ -3853,7 +3883,7 @@
 # CONFIG_FS_DAX is not set
 CONFIG_FS_POSIX_ACL=y
 CONFIG_EXPORTFS=y
-# CONFIG_EXPORTFS_BLOCK_OPS is not set
+CONFIG_EXPORTFS_BLOCK_OPS=y
 CONFIG_FILE_LOCKING=y
 CONFIG_MANDATORY_FILE_LOCKING=y
 # CONFIG_FS_ENCRYPTION is not set
@@ -3873,7 +3903,12 @@
 CONFIG_AUTOFS4_FS=y
 CONFIG_AUTOFS_FS=y
 # CONFIG_FUSE_FS is not set
-# CONFIG_OVERLAY_FS is not set
+CONFIG_OVERLAY_FS=y
+# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set
+CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y
+# CONFIG_OVERLAY_FS_INDEX is not set
+# CONFIG_OVERLAY_FS_XINO_AUTO is not set
+# CONFIG_OVERLAY_FS_METACOPY is not set
 
 #
 # Caches
@@ -4113,6 +4148,7 @@
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=y
 # CONFIG_CRYPTO_TEST is not set
+CONFIG_CRYPTO_ENGINE=m
 
 #
 # Public-key cryptography
@@ -4271,6 +4307,7 @@
 # CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set
 # CONFIG_CRYPTO_DEV_QAT_C62XVF is not set
 # CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set
+CONFIG_CRYPTO_DEV_VIRTIO=m
 CONFIG_ASYMMETRIC_KEY_TYPE=y
 CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
 CONFIG_X509_CERTIFICATE_PARSER=y
@@ -4319,13 +4356,14 @@
 # CONFIG_CRC64 is not set
 # CONFIG_CRC4 is not set
 # CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=y
 # CONFIG_CRC8 is not set
 # CONFIG_RANDOM32_SELFTEST is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_LZO_COMPRESS=y
 CONFIG_LZO_DECOMPRESS=y
+CONFIG_LZ4_DECOMPRESS=y
 CONFIG_XZ_DEC=y
 CONFIG_XZ_DEC_X86=y
 CONFIG_XZ_DEC_POWERPC=y
@@ -4335,6 +4373,12 @@
 CONFIG_XZ_DEC_SPARC=y
 CONFIG_XZ_DEC_BCJ=y
 # CONFIG_XZ_DEC_TEST is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_XZ=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_DECOMPRESS_LZ4=y
 CONFIG_GENERIC_ALLOCATOR=y
 CONFIG_INTERVAL_TREE=y
 CONFIG_ASSOCIATIVE_ARRAY=y


使用meke menuconfig调整选项后重新使用make命令编译出bzImage并调试;


启动过程中报错及解决方法
VFS: Cannot open root device "LABEL=/" or unknown-block(0,0) 错误的解决方法
注意内核编译以下选项:
https://stackoverflow.com/questions/17242403/linux-running-self-compiled-kernel-in-qemu-vfs-unable-to-mount-root-fs-on-unk

linux: running self compiled kernel in qemu: VFS: Unable to mount root fs on unknown wn-block(0,0)

CONFIG_EXT4_FS=y
CONFIG_IA32_EMULATION=y
CONFIG_VIRTIO_PCI=y (Virtualization -> PCI driver for virtio devices)
CONFIG_VIRTIO_BALLOON=y (Virtualization -> Virtio balloon driver)
CONFIG_VIRTIO_BLK=y (Device Drivers -> Block -> Virtio block driver)
CONFIG_VIRTIO_NET=y (Device Drivers -> Network device support -> Virtio network driver)
CONFIG_VIRTIO=y (automatically selected)
CONFIG_VIRTIO_RING=y (automatically selected)

1、磁盘驱动没编译进内核
Device Drivers

2、文件系统驱动没编译进内核
linux下有ext2 和 ext3 ext4 文件系统,看你当前的文件系统是哪种(mount命令可以查看),并把相应的驱动编译进内核。

制作busybox rootfs镜像
解压busybox源码
make menuconfig
勾选Build BusyBox as a static binary (no shared libs)
勾选Installation Options Settings下面的选项Don't use /usr
$ make
$ make install
然后编译好后在busybox目录下生成子目录_install

然后使用以下脚本制作rootfs_ramdisk.gz
#! /bin/bash

####################################################
# Author      : longbin
# Created date: 2019-08-02 10:20:14
####################################################

busybox_folder=.
rootfs=rootfs

function _create_rootfs_dir()
{
    local install_dir=${busybox_folder}/_install
    if [ ! -d ${install_dir} ] ;then
        echo "ERROR: ${install_dir}: No such directory."
        echo "Please execute 'make install' in busybox source directory first."
        exit 1
    fi
    if [ -d ${rootfs} ]; then
        sudo rm -rf ${rootfs}
    fi
    mkdir -p ${rootfs}

    cp -rfd ${install_dir}/*  ${rootfs}/
    pushd ${rootfs}
    for dir in proc sys dev etc tmp mnt lib lib64 etc/init.d etc/sysconfig home root var var/log
    do
        if [ ! -d ${dir} ] ;then
            echo "mkdir ${dir}"
            mkdir -p ${dir}
        fi
    done
    popd
}

function _create_etc_fstab()
{
    local fstab_file=${rootfs}/etc/fstab
    sudo touch /etc/fstab
    echo "#device        mount-point    type    options        dump    fsck order" >> ${fstab_file}
    # echo "proc        /proc        proc    defaults        0    0" >> ${fstab_file}
    echo "tmpfs        /tmp        tmpfs    defaults        0    0" >> ${fstab_file}
    # echo "sysfs        /sys        sysfs    defaults        0    0" >> ${fstab_file}
    echo "tmpfs        /dev        tmpfs    defaults        0    0" >> ${fstab_file}
    echo "var        /dev        tmpfs    defaults        0    0" >> ${fstab_file}
    echo "ramfs        /dev        ramfs    defaults        0    0" >> ${fstab_file}
    echo "debugfs        /sys/kernel/debug    debugfs        defaults    0    0" >> ${fstab_file}
}
 
function _create_etc_inittab()
{
    local inittab_file=${rootfs}/etc/inittab
    if [ -f ${inittab_file} ] ;then
        rm ${inittab_file}
    fi
    echo "# /etc/inittab" > ${inittab_file}
    echo "::sysinit:/etc/init.d/rcS" >> ${inittab_file}
    echo "console::askfirst:-/bin/sh" >> ${inittab_file}
    echo "::ctrlaltdel:/sbin/reboot" >> ${inittab_file}
    echo "::shutdown:/sbin/swapoff -a" >> ${inittab_file}
    echo "::shutdown:/bin/umount -a -r" >> ${inittab_file}
    echo "::restart:/sbin/init" >> ${inittab_file}
}

function _create_etc_initd_rcS()
{
    local rcS_file=${rootfs}/etc/init.d/rcS
    if [ -f ${rcS_file} ]; then
        rm ${rcS_file}
    fi
    echo "#! /bin/sh" > ${rcS_file}
    echo "PATH=/sbin:/bin:/usr/sbin:/usr/bin" >> ${rcS_file}
    echo "runlevel=S" >> ${rcS_file}
    echo "prevlevel=N" >> ${rcS_file}
    echo "umask 022" >> ${rcS_file}
    echo "export PATH runlevel prevlevel" >> ${rcS_file}
    echo "mount -a" >> ${rcS_file}
    echo "mkdir -p /dev/pts" >> ${rcS_file}
    echo "mount -t devpts devpts /dev/pts" >> ${rcS_file}
    echo "#mount -n -t usbfs none /proc/bus/usb" >> ${rcS_file}
    echo "echo /sbin/mdev > /proc/sys/kernel/hotplug" >> ${rcS_file}
    echo "mdev -s" >> ${rcS_file}
    echo "mkdir -p /var/lock" >> ${rcS_file}
    echo "ifconfig lo 127.0.0.1" >> ${rcS_file}
    echo "ifconfig eth0 192.168.1.20" >> ${rcS_file}
    echo "/bin/hostname -F /etc/sysconfig/HOSTNAME" >> ${rcS_file}
    echo "mount -t proc none /proc" >> ${rcS_file}
    echo "mount -t sysfs none /sys" >> ${rcS_file}
    echo "/sbin/mdev -s" >> ${rcS_file}
    echo "/sbin/syslogd &" >> ${rcS_file}
    echo "sleep 1"         >> ${rcS_file}
    echo "logger '##############init rcS ok##################'" >> ${rcS_file}
    chmod +x ${rcS_file}
}

function _create_etc_profile()
{
    local profile=${rootfs}/etc/profile
    echo 'USER="root"' >> ${profile}
    echo 'LOGNAME=$USER' >> ${profile}
    echo 'export HOSTNAME=`/bin/hostname`' >> ${profile}
    echo 'export USER=root' >> ${profile}
    echo 'export HOME=/root' >> ${profile}
    # echo 'export PS1="[$USER@$HOSTNAME \W]\# "' >> ${profile}
    echo 'export PS1="[$USER:\w]\# "' >> ${profile}
    echo 'PATH=/bin:/sbin:/usr/bin:/usr/sbin' >> ${profile}
    echo 'LD_LIBRARY_PATH=/lib64:/usr/lib64:$LD_LIBRARY_PATH' >> ${profile}
    echo 'export PATH LD_LIBRARY_PATH' >> ${profile}
    echo "logger '##############load profile ok###################'" >> ${profile}
}

function _create_etc_sysconfig_hostname()
{
    local hostname=${rootfs}/etc/sysconfig/HOSTNAME
    echo "x86_64" > ${hostname}
}

function _create_lib_dir()
{
    sudo cp -arf /lib/x86_64-linux-gnu/* ${rootfs}/lib64/
    sudo rm ${rootfs}/lib/*.a
    sudo strip ${rootfs}/lib/*
}

function _create_dev_node()
{
    mkdir -p ${rootfs}/dev/
    sudo mknod ${rootfs}/dev/tty1 c 4 1
    sudo mknod ${rootfs}/dev/tty2 c 4 2
    sudo mknod ${rootfs}/dev/tty3 c 4 3
    sudo mknod ${rootfs}/dev/tty4 c 4 4
    sudo mknod ${rootfs}/dev/console c 5 1
    sudo mknod ${rootfs}/dev/null c 1 3
}

function _create_rootfs_img()
{
    local rootfs_img=${busybox_folder}/rootfs.img
    if [ -f ${rootfs_img} ]; then
        rm ${rootfs_img}
    fi
    
    find . | cpio -o --format=newc > ${rootfs_img}
    echo "rootfs cpio img: ${rootfs_img}"
}

function _create_rootfs_ramdisk()
{
    local ramfs=${busybox_folder}/rootfs_ramdisk.gz
    echo "create ramdisk ..."
    sudo dd if=/dev/zero of=ramdisk bs=1M count=32
    sudo mkfs.ext4 ramdisk
    sudo mkdir -p tmpfs
    sudo mount -t ext4 -o loop ramdisk ./tmpfs/
    sudo cp -raf ${rootfs}/*  tmpfs/
    sudo umount tmpfs
    sudo gzip --best -c ramdisk > ${ramfs}
    sudo rm -f ramdisk
    sudo rm -r tmpfs
    echo "ramdisk: ${ramfs}"
}

function _usage()
{
    local info="
    Usage:\n
        please execute below comand in busybox directory.\n\t
        bash $0
    "
    echo -e ${info}
    exit 0
}

if [ "${1,,}" = "-h" -o "${1,,}" = "--help" ] ;then
    _usage
fi
_create_rootfs_dir
_create_etc_fstab
_create_etc_inittab
_create_etc_initd_rcS
_create_etc_profile
_create_etc_sysconfig_hostname
_create_lib_dir
_create_dev_node
_create_rootfs_img
_create_rootfs_ramdisk

 

安装qemu

sudo apt install qemu
使用以下命令启动

#! /bin/bash

####################################################
# Author      : longbin
# Created date: 2019-08-02 13:10:38
####################################################

sudo qemu-system-x86_64 \
    -m 512M \
    -smp 4 \
    -nographic \
    -kernel ./kernel/linux-5.2/arch/x86_64/boot/bzImage \
      -initrd rootfs_ramdisk.gz \
    -append "root=/dev/ram0 rw rootfstype=ext4 console=ttyS0 init=/linuxrc"

./kernel/linux-5.2/arch/x86_64/boot/bzImage 为编译的kernel image
rootfs_ramdisk.gz 为打包的busybox文件系统;

参考资料
https://www.cnblogs.com/pengdonglin137/p/6442624.html
https://www.cnblogs.com/hellogc/p/7482066.html
 

你可能感兴趣的:(#,14busybox,#,15kernel)