zoukankan      html  css  js  c++  java
  • 通过gdb调试分析Linux内核的启动过程

    作者:吴乐 山东师范大学

    《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

    一、实验流程

    1.打开环境

    执行命令:cd LinuxKernel/

    执行命令:qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img

    MenuOS便可以成功启动。可以测试三个命令“help,version,quit”的工作情况

    2、使用gdb跟踪调试内核

    执行命令:qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S 

    冻结启动窗口,重新打开一个终端使用gdb命令调试

    如下图所示:

    执行以下三个命令:

    1.file linux-3.18.6/vmlinux

    2.target remote:1234

    3.设置断点:break start_kernel

    list可以显示上下、相关的代码帮助理解启动过程

    以同样的方式设置多个断点,按c键继续执行,可以最终调试内核的启动过程。(以rest_init中断为例)

    二,加载内核的过程

      操作系统接管硬件以后,首先读入 /boot 目录下的内核文件。

         我们知道系统是从BIOS加电自检,载入MBR中的引导程序(LILO/GRUB),再加载linux内核开始运行的,一直到指定shell开始运行告一段落,这时用户开始操作Linux。而大致是在vmlinux的入口startup_32(head.S)中为pid号为0的原始进程设置了执行环境,然后原是进程开始执行start_kernel()完成Linux内核的初始化工作。包括初始化页表,初始化中断向量表,初始化系统时间等。继而调用 fork(),创建第一个用户进程:  

    kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);

      这个进程就是著名的pid为1的init进程,它会继续完成剩下的初始化工作,然后execve(/sbin/init), 成为系统中的其他所有进程的祖先。关于init我们这次先不研究,回过头来看pid=0的进程,在创建了init进程后,pid=0的进程调用cpu_idle()演变成了idle进程。

      总而言之,系统启动后首先执行一系列的初始化工作,直到start_kernel处,它是代码的入口点,相当于main.c函数。然后启动系统的第一个进程init,init是所有进程的父进程,由init再启动子进程,从而使得系统成功运行起来。

  • 相关阅读:
    第九周作业
    第八周
    第七周
    Jmeter连接到Mysql
    数据库常用链接URL写法
    功能测试方法
    常建输入框的测试
    系统业务流程测试(转)
    Linux
    搭建Git服务器
  • 原文地址:https://www.cnblogs.com/wule/p/4348667.html
Copyright © 2011-2022 走看看