zoukankan      html  css  js  c++  java
  • 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号内核线程)始终运行在内核,负责所有内核线程的调度和管理。

      整个过程如图所示:

  • 相关阅读:
    Java怎样对一个属性设置set或get方法的快捷键
    小程序怎样控制rich-text中的<img>标签自适应
    Java中Arrys数组常用的方法
    Java 怎样实现调用其他方法
    Java保留两位小数
    解决ajax请求跨域
    rand(7) 到rand(10)
    c++生成随机数
    批量该文件名
    正则表达式(=)
  • 原文地址:https://www.cnblogs.com/liangxu111/p/11667802.html
Copyright © 2011-2022 走看看