使用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