码迷,mamicode.com
首页 > 系统相关 > 详细

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

时间:2019-12-11 19:05:50      阅读:109      评论:0      收藏:0      [点我收藏+]

标签:压缩文件   客户   引导程序   tree   系统初始   操作   lin   添加   简单的   

1.  构建MenuOS系统

  a). 下载linux内核并编译 (在虚拟机上自己实现一个小的linux操作系统)

      a.1) 实验环境: VMware虚拟机、64位Ubuntu16.04   

    a.2) 下载linux内核源码编译内核: 版本 linux-5.0.1(https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.1.tar.xz) 

    a.3) 解压缩文件: $ xz -d linux-5.0.1.tar.xz;  $ tar -xvf linux-5.0.1.tar

    a.4) $ cd linux-5.0.1  

   b).  安装内核编译工具

    $  sudo apt install build-essential flex bison libssl-dev libelf-dev libncurses-dev

  c).  配置编译内核

    $ sudo cp /boot/config-xxx -r .config    #使用现存内核的配置文件:xxx指命令输入此处可以按Tab键补全

     $ sudo make oldconfig  # 应用现存配置文件

     $ sudo make localmodconfig  # 仅安装已有module

       $ sudo make menuconfig  # 配置其他编译选项  (依次选择Kernel hacking --> Compile-time checks and compiler options --> Compile the kernel with debug info, 保存退出)

    技术图片 

    $ cd ~/MenuOS/linux-5.0.1  # 以上内核的准备工作结束, 开始编译内核

    $ sudo make   # make 进行内核配置,过程较慢

  c). 通过qemu虚拟机加载内核

   $ cd ../

   $ sudo apt install qemu  # 安装qemu  

    $ qemu-system-x86_64 -kernel linux-5.0.1/arch/x86_64/boot/bzImage  # make i386_defconfig  # 运行该命令,成功则会弹出一个MenuOs系统窗口

   d).  构造MenuOS

     $  git clone https://github.com/mengning/menu.git

    $ cd menu

    $ sudo apt-get install libc6-dev-i386 # 在64位环境下编译32位需安装

    # 在进一步执行前,需要先修改~/LinuxKernel/menu目录下Makefile文件下的一行内容

    # 将原qemu处的命令改为qemu-system-x86_64 -kernel ../linux-5.0.1/arch/x86_64/boot/bzImage -initrd ../rootfs.img

    技术图片

    $ make rootfs (成功则会出现如下界面)

    技术图片

 

  e).  验证MenuOS的网络可以正常工作 

    $ cd ~/LinuxKernel

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

    # 集成服务器到MENUOS上

    $ cd linuxnet/lab2

    $ make

    $ cd ../../menu/

    $ make rootfs  # 初始化根目录

    技术图片

    # 集成服务器到MENUOS上 (先修改lab3/makefile的qemu处的命令修改为qemu-system-x86_64 -kernel ../../linux-5.0.1/arch/x86_64/boot/bzImage -initrd ../rootfs.img )

    $ cd  ../inuxnet/lab3

    $ make rootfs

    # 可以观察到,现在多了replyhi和hello两个命令

    技术图片

    $ 直接在QEMU中输入hello命令, 输出如下,则网络正常工作

    技术图片

 2). 也可以实验楼线上直接运行MenuOS系统(实验楼课程地址:  https://www.shiyanlou.com/courses/1198)

    启动MenuOS系统 

       $ cd ~/LinuxKernel/    

    $ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img  # 直接启动内核 (initrd: 指定一个根文件系统)     

    # 成功运行MenuOS系统会跳出下面的界面(到此时,已经成功构建一个简单的linux系统)

    技术图片

2. 使用gdb跟踪调试信息

    a). 在qemu中重新启动gdb server

      $ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S  # 启动一个虚拟机qemu, 并且此时处于冻结状态

    b). 重新打开一个终端,执行gdb (相当于gdb client)

      $ gdb   # 启动gdb

     $ file linux-3.18.6/vmlinux   #  加载符号表

     $ target remote:1234   #  建立 gdb client 和 gdb server 之间的连接

     $ break start_kernel   #  在start_kernel处设置断点

     $ c    # 按 c 让qemu上的Linux继续运行, 即启动程序解除冻结 

     技术图片

     $ list    # 可以查看断点处  start_kernel 的源码 (即 已经验证 gdb可以跟踪到内核代码)

     技术图片

     # 到这一步已经验证我们成功构建了menuos系统并且可以使用gdb进行调试

3. 将网络通信程序集成到 MenuOS 系统中(实验楼上已经集成好了,故我们直接运行)

   a). TCP客户端和服务器发送和接收hello/hi

    # 在step2基础上,关闭之前的所有命令,重新输入以下命令

    $  cd ~/LinuxKernel  

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

    $ cd linuxnet/lab3

    $ make

    $ cd ../../menu/

    $ make rootfs   # rootfs 脚本会自动编译、自动生成根文件系统,还会帮我们运行起来 MenuOS 系统

     此时重新启动一个qemu窗口, 可以看到相比之前的三个命令,现在添加了replyhi, hello两个命令

    技术图片

    再在MenuOS执行hello命令:  MenuOS>> hello    # 已经证实在MenuOS上能够完成TCP客户端和服务器发送和接收hello/hi,也就是MenuOS的网络可以正常工作

    技术图片

 4. 内核的启动过程简单介绍

  内核映像被加载到内存并获得控制权之后,内核启动流程开始。通常,内核映像以压缩形式存储,并不是一个可以执行的内核。

  因此,内核阶段的首要工作是自解压内核映像。

  内核编译生成vmliunx后,通常会对其进行压缩,得到zImage(小内核,小于512KB)或bzImage(大内核,大于512KB)。在它们的头部嵌有解压缩程序。

  linux内核的启动过程: 

    (CPU进入复位状态,内存数据清零,CS:IP(FFFF:0000)指向BIOS的入口,系统通过此方法进入BIOS启动过程)    

    ==> 系统上电  
        ===> CPU自身初始化 

    ---------------------------------BIOS------------------------------------------  (BIOS启动,主要完成硬件初始化,包含以下两个过程)
          ===> 上电自检
            ===> 加载内核引导程序 (读入Boot Loader, 其主要作用是将系统启动代码读入内存)

    ------------------------------内核引导程序----------------------------------- (此时控制权转交给了Boot Loader,引导OS的启动)
              ===> 主引导程序
                ===> 次引导程序

    ----------------------------------------------------------------------------------  (已经将OS代码调入内存,将控制权转交给OS,OS的启动程序开始执行)
                  ===> 调用内核 (控制权在Setup.s程序处,之后它会将控制权交给Head.s, Head.s在最后将控制权交给main.c中的start_kernel函数,剩余的初始化工作皆由它完成)

  我们在start_kernel函数处设置断点,并继续执行MenuOs系统,得到下面的图

      技术图片

   可以看到此时在start_kernel函数处停止,此时已经完成了

  技术图片 

   我们主要介绍一下Boot Loader 将控制权转交给OS后,从start_kernel开始到init的几个重要的初始化过程

// start_kernel()执行后,从内核态转到用户态,此时可以以用户的身份使用
linuxasmlinkage void __init start_kernel(void)
{
  ... 
  setup.arch();  // 基本硬件初始化
  ...
  paging_init(); // 完成页的初始化
  ...
  trap_init();   // 终端向量表初始化
  ...
  sched.init();  // 为进程调度执行做准备
  ...
  time_init();  
  ...
  console_init();  
  ...
  inode_init();  //  文件系统初始化开始
  ...
  mem_init();    // 结束后启动/etc下的配置文件,并进入用户态
  
}

参考来源:

  1. https://github.com/mengning/net/tree/master/lab3

  2. 深入分析Linux内核源码

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

标签:压缩文件   客户   引导程序   tree   系统初始   操作   lin   添加   简单的   

原文地址:https://www.cnblogs.com/zhouz/p/11988664.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!