zoukankan      html  css  js  c++  java
  • 【MenuOS】可gdb调试内核代码的MenuOS搭建

    可gdb调试内核代码的MenuOS搭建

    实验环境:Ubuntu18.04.1, qemu

    1. 尝试升级当前系统内核

    1.1 查看当前系统内核

    当前内核为5.0.0-23-generic

    $ uname -a
    Linux ubuntu 5.0.0-23-generic #24~18.04.1-Ubuntu SMP Mon Jul 29 16:12:28 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
    

    1.2 下载Linux内核源代码

    # 创建目录,下载最新内核
    ~$ mkdir ~/LinuxKernel
    ~$ cd ~/LinuxKernel/
    ~/LinuxKernel$ wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.4.2.tar.xz
    

    1.3 下载过程如下

    linux-5.4.2.tar.xz 100%[============================================>] 104.37M 275KB/s 用时 3m 9s   
    2019-12-10 19:37:51 (566 KB/s) - 已保存 “linux-5.4.2.tar.xz” [109441848/109441848])
    

    1.4 解压并编译内核

    # 解压xz压缩文件
    ~/LinuxKernel$ xz -d linux-5.4.2.tar.xz 
    # 提取tar归档文件
    ~/LinuxKernel$ tar -xvf linux-5.4.2.tar
    
    # 安装编译依赖
    ~/LinuxKernel$ sudo apt install build-essential flex bison libssl-dev libelf-dev libncurses-dev
    
    # 编译内核
    ~/LinuxKernel$ cd linux-5.4.2/
    ~/LinuxKernel/linux-5.4.2$ make i386_defconfig # 按照默认值生成32位x86配置文件
    ~/LinuxKernel/linux-5.4.2$ make
    

    编译完成

    1.5 尝试升级当前系统内核

    最后失败了,不想对系统内核尝试升级的/或者不是在虚拟机上进行的,这部分可以跳过。

    1.5.1 系统快照

    防止升级当前系统内核后无法启动,创建系统快照

    1.5.2 升级内核

    ~/LinuxKernel/linux-5.4.2$ sudo make modules install
    

    ~/LinuxKernel/linux-5.4.2$ sudo make install
    

    ~/LinuxKernel/linux-5.4.2$ sudo update-grub
    # 接着重启系统
    ~/LinuxKernel/linux-5.4.2$ reboot
    

    重启后发现,系统起不来了,还好进行了快照备份。。。

    快照恢复,算了不折腾当前系统内核了

    2. QEMU虚拟机

    2.1 下载安装QEMU

    ~/LinuxKernel$ sudo apt install qemu
    # 使用qemu加载linux内核,参数kernel需要调整为对应版本号的镜像
    ~/LinuxKernel$ qemu-system-i386 -kernel linux-5.4.2/arch/x86/boot/bzImage
    

    2.2 构造menuOS

    ~/LinuxKernel$ git clone https://github.com/mengning/menu.git
    ~/LinuxKernel/menu$ cd menu
    ~/LinuxKernel/menu$ sudo apt-get install libc6-dev-i386  # 32位编译所需要的库
    ~/LinuxKernel/menu$ nvim Makefile
    

    两处地方需要修改,第一个是修改为对应启动命令,第二个是修改内核版本号为之前编译的内核文件夹名

    ~/LinuxKernel/menu$ make rootfs
    

    接着就会启动MenuOS,同时Linux目录下会生成一个rootfs.img,下次启动就不用make

    比如关了qemu后,下次可以在LinuxKernel文件夹下直接通过qemu-system-i386 -kernel linux-5.4.2/arch/x86/boot/bzImage -initrd rootfs.img来启动虚拟机

    2.3 集成TCP服务端测试网络功能

    在MenuOS中集成我们的TCP服务端程序

    ~/LinuxKernel$ git clone https://github.com/mengning/linuxnet.git
    ~/LinuxKernel$ cd linuxnet/lab2
    ~/LinuxKernel/linuxnet/lab2$ make
    ~/LinuxKernel/linuxnet/lab2$ cd ~/LinuxKernel/menu/
    

    会发现menuos中多个一个replyhi的命令

    此时只是集成了TCP服务端程序

    检查lab3的Makefile,修改内核路径部分,并构建

    ~/LinuxKernel/linuxnet/lab3$ nvim Makefile
    ~/LinuxKernel/linuxnet/lab3$ make rootfs
    

    运行服务并测试TCP功能

    2.4 重新编译内核

    为了能进行调试,对内核进行重新编译

    ~/LinuxKernel/menu$ make menuconfig
    # kernel hacking—>Compile-time checks and compiler options—> 
    # [*] compile the kernel with debug info
    

    依次进入kernel hackingCompile-time checks and compiler options,选中compile the kernel with debug info,然后save

    save的时候检查下是否有该信息,接着就可以Esc退出了

    ~/LinuxKernel/menu$ make
    

    make重新编译(时间较长)

    2.5 启动带gdbserver的MenuOS

    ~/LinuxKernel$ qemu-system-i386 -kernel linux-5.4.2/arch/x86/boot/bzImage -initrd rootfs.img -append "root=/dev/sda init=/init nokaslr" -s -S
    
    • -S freeze CPU at startup(use c to start execution)
    • -s shorthand for -gdb tcp::1234(可以使用-gbd tcp::xxxx来更换端口)
    • nokaslr KASLR是kernel address space layout randomization的缩写

    运行命令后,qemu虚拟机会等待gdb连接,所以是一个黑屏的界面

    2.6 启动gdb连接gdbserver

    2.6.1 新打开一个窗口

    ~/LinuxKernel$ gdb
    (gdb) file ~/LinuxKernel/linux-5.4.2/vmlinux
    (gdb) target remote:1234  # 设置gdbserver端口
    (gdb) break start_kernel  # 设置启动断点
    (gdb) break sys_socketcall  # 套接字调用断点
    

    2.6.2 输入c让系统继续启动

    (gdb) c
    (gdb) list  # 停下来后通过list查看断点上下文命令
    

    可以看到

    gdb中继续输入c,让系统继续启动,发现进入了socketcall断点

    在qemu中可以看到是在启动本地环回端口

    接着c继续,加上环回地址总共进入了三次socketcall断点,在qemu上分别是lo,eth0,list all interfaes,然后进入了系统

    2.6.3 使用tcp服务端和客户端通信

    这里要重新集成测试用的TCP服务端和客户端

    (gdb) replyhi
    (gdb) hello
    

    在这期间,可以看到多次进入socketcall断点

    到此通过gdb可以跟踪到内核代码,比如start_kernelsys_socketcall等内核函数的MenuOS已搭建完成。


    作者:SA19225176,万有引力丶

    参考资料来源:USTC Socket网络编程-编译构建调试Linux系统

  • 相关阅读:
    RxJava Android(RxAndroid) 开发全家桶
    Android Retrofit RxJava实现缓存
    Android Touch事件传递机制详解 下
    Android Touch事件传递机制详解 上
    Android Framework 记录之二
    XMind 8 Update 7 Pro 激活码
    leetcode 2-> Add Two Numbers
    leetcode 1 -> Two Sum
    leetcode 3-> Longest Substring Without Repeating Characters
    Python enumerate() 函数
  • 原文地址:https://www.cnblogs.com/Axi8/p/12021997.html
Copyright © 2011-2022 走看看