• 构建调试Linux内核网络代码的环境MenuOS系统


    构建调试Linux内核网络代码的环境MenuOS系统

    如何构建一个可以调试Linux内核网络代码的环境MenuOS呢?

    在Ubuntu下构建一个MenuOS

    首先,我们要下载Linux内核的源代码。网址是:http://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.1.tar.xz

    然后用命令进行解压。

    xz -d linux-5.0.1.tar.xz
    tara -xvf linux-5.0.1.tar
    cd linux-5.0.1

    接下来安装内核编译工具.

    sudo apt install build-essential flex bison libeel-dev libelf-dev libncurses-dev

    配置编译内核

    make defconfig    #按照默认值生成

    接下来通过QEMU虚拟机加载内核

    sudo apt install qemu
    qemu-system-i386 -kernel linux-5.0.1/arch/x86/boot/bzImage #make i386_defconfig
    qemu-system-x86_64 -kernel linux-5.0.1/arch/x86_64/boot/bzImage

    构造MenuOS

    git clone https://github.com/mengning/menu.git
    cd menu
    sudo apt-get install libc6-dev-i386
    make rootfs
    cd ..
    qemu-system-i386 -kernel linux-5.0.1/arch/x86/boot/bzImage -initrd rootfs.img #makei386_defconfig
    qemu-system-x86_64 -kernel linux-5.0.1/arch/x86_64/boot/bzImage -initrd

    如果是在自己的Ubuntu下构造MenuOS大概就是以上过程了,在这里为了简化实验过程。我选择了在实验楼环境下进行操作,因为这个环境下的Linux内核文件都已经下载配置完成了,所以就方便的多。实验楼的环境Linux的版本是3.18.6

    在实验楼构建MenuOS

    1.首先打开一个终端,进入LinuxKernel文件夹。

    cd LinuxKernel

    2.接下来就构造一个MenuOS

    qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img

    3.验证我们的MenuOS是否能够正常工作。这里我们把hello/hi聊天程序从github上clone到本地来康康。

    git clone https://github.com/mengning/linuxnet.git

    通过图片我们可以看出TCP客户端和服务器正常工作。

    4.然后重新打开一个终端进入gdb调试的过程,在qemu上启动gdb server。

    qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S

    这个命令执行完了过后,就可以让CPU停止在启动的那一刻,此时qemu在等待gdb的连接。

    其中-S的意思是让系统启动的时候冻结CPU,按c键就可以继续执行。

    -s的意思是打开远程调试端口,这里默认用的1234端口。

    5.这个时候再重新打开一个终端进入gdb调试阶段,这里注意,这个冻结的CPU千万别关了,不然待会儿的1234端口连接不上的。在这个gdb中运行下面的命令:

    file linux-3.18.6/vmlinux
    target remote:1234

    其中file linux-3.18.6/vmlinux是用来记载Linux中的符号表,target remote:1234则可以建立gdb和gdbserver之间的连接。

    6.在gdb界面中设置断点,这里断点的设置可以在target remote之前,也可以在之后。在设置好start_kernel处断点并且target remote之后可以继续运行,在运行到start_kernel的时候会停下来,等到gdb调试命令的输入,可以使用list来显示断点处的源代码。这里我们可以看到start_kernel在501行。

    内核代码分析

    我们把start_kernel的代码拿出来看看

    asmlinkage __visible void __init start_kernel(void)
    {
        
        char *command_line;
        char *after_dashes;
    ​
        /*
         * Need to run as early as possible, to initialize the
         * lockdep hash:
         */
        lockdep_init();   
        set_task_stack_end_magic(&init_task);
        smp_setup_processor_id();   
        debug_objects_early_init();    
    ​
        /*
         * Set up the the initial canary ASAP:
         */
        boot_init_stack_canary();  
    ​
        cgroup_init_early();

    内核的初始化程序在start_kernel这个函数中,通过阅读start_kernel代码,可以大致了解到内核在初始化的时候,大概的过程:首先通过lockdep_init()初始化内核依赖关系表,检查互斥机制的死锁问题。然后调用init_task,手工创建一个0号进程。通过smp_setup_processor_id()来获取CPU的硬件ID。boot_init_stack_canary()为栈增加保护机制,预防一些缓冲区溢出之类的攻击。总而言之,start_kernel就是进行了一系列的初始化工作。

     

  • 相关阅读:
    创建基于 SQL Server 表的外部内容类型
    symfony入门之 app/console 命令
    git上传代码到github
    ubuntu下配置apache虚拟主机
    ubuntu14.04下解决编辑器无法输入中文
    PHP把域名解析为站点IP
    mysql平常总结
    php防sql注入函数
    常用的正则检测总结
    redis缓存注意事项
  • 原文地址:https://www.cnblogs.com/raoxinyue/p/12012499.html
Copyright © 2020-2023  润新知