• 201920201 20199320《Linux内核原理与分析》第四周作业


    第三章 MenuOS的构造

    构造一个简单地Linux内核

    第一步、构建Linux系统MenuOS

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

    注:qemu仿真kernel;bzImage是vnLinux经过gzip压缩后的文件,是压缩的内核映像;initrd是内存根文件系统;rootfs是编译好的文件系统。

    运行结果如图:

    第二步、跟踪调试Linux内核的启动过程(使用gdb跟踪)

    1. 输入如下命令将内核启动:

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

      注:

      • -s:在1234端口上创建了一个gdb-server,可用于之后设置断点跟踪内核;
      • -S:使CPU初始化之前冻结起来。

      启动效果如下图:

    2. 启动gdb输入如下指令加载内核,建立连接

      file linux-3.18.6/vmlinux  //在gdb界面中target remote之前加载符号表
      target remote:1234  //用1234这个端口进行连接
      
    3. gdb中输入如下指令在start_kernel处设置断点

      break start_kernel //可在target remote之前,也可在之后
      

      效果如图:

      查看strat_kernel代码:

      分析: strat_kernel是一切的起点,用于完成硬件系统的初始化工作,为C代码的运行设置环境。

      其中,比较重要的init_task是手工创建的PCB,是进程描述符,0号进程,即最终的idle进程。

    4. gdb中输入如下指令在rest_init()处设置断点

      break rest_init
      

      查看rest_init()代码:

      分析: 通过rest_init()新建kernel_init和kthreadd内核线程

      注:

      • init_task(0号进程)是唯一没有通过fork方式产生的进程;
      • 所有的内核线程都是直接或间接地一kthreadd为父进程。
    5. 总结进程创建过程

      • init_task()(PID为0)通过调用cpu_idle()转为idle进程,运行在内核空间;
      • init_task()创建的kernel_init()(1号内核线程)通过调用do_execve可转为init用 户态1号进程,这是内核启动的第一个用户态进程;
      • init_task()创建的kthreadd()(2号内核线程)始终运行在内核,负责所有内核线程的调度和管理。

      整个过程如图所示:

  • 相关阅读:
    centos7下配置时间同步服务器
    交换机简单配置(转)
    ubuntu16.04安装docker CE
    docker下使用DB2
    iptables之centos6版本详解
    iptables之centos6版本常用设置
    iptables介绍iptables和netfilter
    git的使用学习(九)搭建git服务器
    js 图片预览
    ps -ef | grep java 查看所有关于java的进程
  • 原文地址:https://www.cnblogs.com/liangxu111/p/11667802.html
Copyright © 2020-2023  润新知