双机调试Linux内核

文章目录
  1. 1. 利用KGDB双机调试内核
    1. 1.1. 环境
    2. 1.2. 配置内核编译环境
  2. 2. 参考

双机调试Linux内核环境配置。

利用KGDB双机调试内核

环境

  • centos 7
  • VMware
  • 全程使用root用户

配置内核编译环境

  • 这种方式调试内核需要两台机器,一台用来运行Linux内核,另一台对内核进行调试。一般有以下三种常用的方案,可以根据电脑的性能或资金状况来选择。可以开两个Linux系统的虚拟机;也可以在物理机系统是linux上面装虚拟机,然后虚拟机运行一个linux;再就是买开发板来调试内核。以下是在windows上开两个虚拟机的流程描述。
  • vmware先开启一个虚拟机,命名为client(cpu核数可以设置跟物理机相同,可以提高后续编译速度)。
  • 注:在之后的make操作时,如果缺失哪个组件,就安装完成后再执行命令。
  • https://www.kernel.org/ 下载想调试版本的内核代码(可以下载tarball格式)。

    1
    2
    3
    cd /usr/src/
    wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-xxx.tar.xz
    tar -xvf linux-xxx.tar
  • 进入目录,设置编译选项(选择将哪些功能编译进内核)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    cd linux-xxx
    make menuconfig
    等待一下会出现设置页面,寻找以下几项然后确认是选中的。
    Kernel hacking --->
    [*]Compile the kernel with frame pointers
    [*]Compile the kernel with debug info
    [*]KGDB: kernel debugging with remote gdb
    [*] KGDB: kernel debugger --->
    KGDB: use kgdb over the serial console
    确认以下一项没有选中。
    Kernel hacking --->
    Write protect kernel read-only data structures
  • 编译内核

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    make -j8 bzImage #-j8设置8个线程来编译,bzImage会降低编译后内核的大小。
    ... ...
    LD arch/x86/boot/setup.elf
    OBJCOPY arch/x86/boot/setup.bin
    BUILD arch/x86/boot/bzImage
    Setup is 16704 bytes (padded to 16896 bytes).
    System is 4642 kB
    CRC 4c29589a
    Kernel: arch/x86/boot/bzImage is ready (#1)

    make -j8 modules #编译内核模块
    # 这两步比较费时,我打开笔记本的高性能&虚拟机设置多核&多线程编译,将编译时间从一个小时降低到十几分钟了。
  • 用vmware克隆出server机(如果早已经克隆,只需拷贝linux-xxx文件夹到server即可。其实也可以在server编译内核,然后再把该目录拷贝到client)

    1
    scp -r linux-xxx root@172.21.66.111:/usr/src/
  • 在server安装内核模块&内核

    1
    2
    make -j8 modules_install
    make -j8 install
  • 在server的/usr/src/linux-xxx生成initrd.img文件(将下面的版本号都换成自己的)

    1
    2
    3
    4
    mkinitramfs -o initrd.img-xxx xxx
    # 以上命令一般在Ubuntu/Debian用,在fedroa或centos一般是mkinitrd,如下
    mkinitrd initrd.img-xxx xxx
    # xxx为版本号
  • 在server,拷贝几个文件到/boot下

    1
    2
    3
    4
    cd /usr/src/linux-xxx
    cp arch/x86_64/boot/bzImage /boot/vmlinuz-xxx-kgdb
    cp System.map /boot/System.map-xxx-kgdb
    cp initrd.img /boot/initrd.img-xxx-kgdb
  • 客户机修改设置开机启动项的grub配置文件,添加串口的设置

    黄框中的内容表示要串口连接,当然加在下面一项的”GRUB_COMLINE_LINUX”中也可以。
    配置完后需要更新一下grub,让配置生效:

    1
    2
    在ubuntu是用该命令更新: update-grub 
    centos使用: grub2-mkconfig -o /boot/grub2/grub.cfg

Grub更新配置后,会自动修改/boot/grub/grub.cfg文件,直接修改grub.cfg不是不行,而是如果/etc/default/grub更新后,如果运行update-grub就又会更新一下grub.cfg,导致直接在grub.cfg中的配置失效.

  • server机修改grub配置文件

    这里与客户机配置比多加了一个参数text,这个参数的意思是系统启动后以text界面而不是图形界面显示(当然这个不是必须的,但是作为目标机我们进入系统直接用text界面界面就可以了)。
    配置完后需要更新一下grub,让配置生效。
    再看看/boot/grub2/grub.cfg,应该是下图这样,kgdbwait参数就为了在系统刚启动时就可以进入调试模式,如果没有,自己再手动加上吧。
  • 给client机添加串行端口

    1
    2
    3
    4
    5
    6
    vmware关闭client,进入虚拟机设置,添加串行端口
    选中启动时连接
    选中使用命名的管道,并填入:
    \\.\pipe\com_1
    该端是客户端
    另一端是虚拟机
  • 给server添加串行端口

    1
    2
    3
    4
    5
    6
    vmware关闭client,进入虚拟机设置,添加串行端口
    选中启动时连接
    选中使用命名的管道,并填入:
    \\.\pipe\com_1
    该端是服务器
    另一端是虚拟机
  • client和server添加串行端口后,测试一下:

    1
    2
    3
    4
    在一端输入:cat /dev/ttyS1
    在另一端输入: echo helloworld > /dev/ttyS1
    观察前者是否能接收到数据。
    (我测试ttyS0不行,改成ttyS1可以了)

参考

欢迎与我分享你的看法。
转载请注明出处:http://taowusheng.cn/