首页 > 其他 > 详细

从内核源码到qemu调试

时间:2020-11-30 21:47:15      阅读:34      评论:0      收藏:0      [点我收藏+]

        记得自己第一次编译内核代码的时候,很是傻逼,已经是4年前的事了,来到了新公司发现真的好久没有做内核方面的工作了,有点小小的忧伤,最近在看virio的一些文章,决定自己今后每周都要写一些关于内核的知识,作为对自己的鼓励吧。

目录结构:

    1:内核源码编译
    2:qemu 源码编译
3:构建initramfs根文件系统
4: 最基本的调试方法

 

一:内核源码:

           原理性的东西,网上一大堆,我这里只是讲一下从github上下载源码,打补丁,到编译vmlinx debug-info的过程。

     1:下载内核源码,我们以4.15为例:

                wget --no-check-certificate https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.14.105.tar.gz

     2:安装依赖的工具       

yum install -y openssl-devel bison flex bc elfutils-libelf-devel centos-release-scl
yum install -y devtoolset-7-gcc*
source /opt/rh/devtoolset-7/enable

      3: 打上自己的补丁: 解压linux-4.14.105.tar.gz 打上自己的补丁。            

$ tar xzvf linux-4.14.105.tar.gz
$ tar xzvf patches.tar.gz
$ cd linux-4.14.105/
$ ls -1 ../patches 
using below CMD.
$ patch -p1 < ../patches/"patch_name" 

 

      3: 生成config文件,修改文件

    这一步有很多的方法,但是我发现最简单的也最好用的方式,就是直接将出问题的环境上的config直接copy过来,进行就该就可以。

cp /boot/config-4.14.105-abcdef+ ./x86_64_defconfig
修改CONFIG_DEBUG_INFO=y 支持debug

    4:可以用rpm 工具编译成rpm包也可以直接生成vmlinux使用

$make x86_64_defconfig   #生成.config
1:直接编译 make  -j$(nproc) //for example: make -j60
2:或者编译成rpm包  $ make rpm-pkg -j$(nproc) 

[root@localhost linux-4.14.105]# file vmlinux
vmlinux: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=ee3e575977c8acafeacd3c2aac38bf7b096499ea, not stripped

二:编译可以调试的qemu

1:编译qemu

下载源码 下载地址
wget https://download.qemu.org/qemu-4.0.0.tar.xz
安装依赖包
yum -y install gcc gcc-c++ automake libtool zlib-devel glib2-devel bzip2-devel libuuid-devel spice-protocol spice-server-devel usbredir-devel libaio-devel SDL2-devel

编译安装
tar xvJf qemu-4.0.0.tar.xz
cd qemu-4.0.0
../configure --enable-kvm --enable-debug --enable-vnc --enable-werror --target-list="x86_64-softmmu"
make -j$(nproc)

默认安装在/usr/local/bin/ 编译完成之后 做链接
ln -s /usr/local/bin/qemu-system-x86_64 /usr/bin/qemu-kvm
ln -s /usr/local/bin/qemu-system-x86_64 /usr/libexec/qemu-kvm
ln -s /usr/local/bin/qemu-img /usr/bin/qemu-img
查看当前qemu版本
qemu-img --version
qemu-kvm --version

三、构建initramfs根文件系统

Linux系统启动阶段,boot loader加载完内核文件vmlinuz后,内核紧接着需要挂载磁盘根文件系统,但如果此时内核没有相应驱动,无法识别磁盘,就需要先加载驱动,而驱动又位于/lib/modules,得挂载根文件系统才能读取,这就陷入了一个两难境地,系统无法顺利启动。于是有了initramfs根文件系统,其中包含必要的设备驱动和工具,boot loader加载initramfs到内存中,内核会将其挂载到根目录/,然后运行/init脚本,挂载真正的磁盘根文件系统。

1:下载 busybox https://busybox.net/ 下载并解压源码
2:编译busybox源码
     2.1 make defconfig&&make menuconfig
     2.2 选择编译为静态库
       -> Build Options  

        [*] Build BusyBox as a static binary (no shared libs)
3:编译 
     make -j4 
4: 安装
    sudo make install
5:此时可以在busybox-1.32.0/中看到生成的_install目录。通过下面的命令可以验证busybox是否安装正确
    [root@localhost busybox-1.32.0]# ./busybox ls

6: 制作自己的initrd
       6.1:mkdir ramdisk && cd ramdisk && cp -r ../busybox-1.32.0/_install/*  .
       6.2:ln -s bin/busybox init
       6.3:mkdir -pv {bin,sbin,etc,proc,sys,usr/{bin,sbin},dev}  创建/ 目录下的文件夹
       6.4: 创建 inittab文件 chmod +x etc/inittab
            cat etc/inittab
            ::sysinit:/etc/init.d/rcS   
            ::askfirst:-/bin/sh    
            ::restart:/sbin/init
            ::ctrlaltdel:/sbin/reboot
            ::shutdown:/bin/umount -a -r
            ::shutdown:/sbin/swapoff -a
        6.5:创建/etc/init.d/rcS   文件
             mkdir init.d && cd init.d && vim rcS
             #!/bin/sh
                mount proc
                mount -o remount,rw /
                mount -a    
                clear                               
                echo "My Tiny Linux Start :D ......"
        6.6:创建 etc/fstab
        # /etc/fstab
            proc            /proc        proc    defaults          0       0
            sysfs           /sys         sysfs   defaults          0       0
            devtmpfs        /dev         devtmpfs  defaults          0       0
        6.7 生成 initrd
        cd ramdisk && find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initramfs.img

7: 验证一下:qemu-kvm -kernel /root/rpmbuild/BUILD/kernel-4.14.105/arch/x86_64/boot/bzImage -initrd initramfs.img  -smp 4 -m 4096 -enable-kvm -append "console=ttyS0" -nographic
技术分享图片

 


 

 

 

四: 最简单的基本的调试方式

        1:假设,你已经制作好了自己的qcow2文件,有一个可以启动的镜像文件(TODO:要写一个)

        qemu-kvm -kernel linux-4.14.105/arch/x86_64/boot/bzImage -initrd initramfs.img  -smp 4 -m 4096 -enable-kvm -append "console=ttyS0" -nographic  -S -s

         技术分享图片

 

         技术分享图片

 

       注意这个地方有两个点要关注   

1: -S 就是挂起gdbserver,让gdb remote connect it。
  -s 默认使用1234端口进行远程调试,和-gdb tcp::1234类似
2:hb xxxx 主要是设置硬件断点,普通的b xxx 有时 gdb 停不下来。

 

 说道这里,基本上已经可以做简单的内核的代码跟踪了,但是还是解决不了我们的 gdb virtio的问题。原因是这样的,我们启动的内核没有vitio的设备, 还有就是我们这样是没有vitio的驱动。所以还是不行。应该怎么做呢? 鉴于篇幅太长了,可能看着看着就烦了,所以我在下一篇文章中说明。

                                                                                                                               >>>>>>>>平常心,不在浮沙上筑高台,阳光总在风雨后<<<<<<<<

参考文章:https://blog.csdn.net/jasonLee_lijiaqi/article/details/80967912

从内核源码到qemu调试

原文:https://www.cnblogs.com/piaomiaofeixue/p/13975627.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!