zoukankan      html  css  js  c++  java
  • 《Linux内核原理与分析》第四次作业

    跟踪分析Linux内核的启动过程

    使用实验楼的虚拟机打开shell

    实验楼

    实验楼

    使用 gdb 跟踪调试内核

    使用 qemu

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

    参数:

      — s:在初始化时冻结CPU
    
      — S:为gdb分配1234端口
    

    实验楼

    gdb调试

    另开一个shell窗口

            — gdb
            —(gdb) file linux-3.18.6/vmlinux      #在gdb界面中target remote之前加载符号表
            —(gdb)target  remote  :1234     #建立连接
            —(gdb)break  start_kernel      #设置断点
    
    

    实验楼

    实验楼

    从 start_kernel 开始到 init 进程启动

    -set_task_stack_end_magic()
    
         为了检测栈溢出
    
    -smp_setup_processor_id()
    
        设置对称多处理器
    
    -cgroup_init_early ()
    
     初始化 Control Groups
    
    -page_address_init()
    
        页地址初始化(属于内存管理部分)
    
    -setup_arch()
    
    -build_all_zonelists()
    
    -page_alloc_init ()
    
    -setup_log_buf ()
    
        初始化log 缓冲区(kernel/printk/printk.c)
    
    -pidhash_init ()
    
        初始化 pid 哈希表
    
    -vfs_caches_init_early ()
    
    -sort_main_extable ()
    
    
    ###初始化中断向量
    
    
    
        -mm_init ()
    
        内存管理初始化
    
       -sched_init ()
    
        调度服务初始化
    
       -rest_init()
    
    
        剩余初始化
    
                 -  kernel_init:init进程
    
                 -  kthreadd:内核线程
    
                 -  cpu_idle进程:代码中一直循环,如果系统中没有可执行的进程时,执行 idle 进程
    
    

    个人对linux启动过程的理解

       start_kernel()函数的作用是完成linux内核的初始化,几乎所有模块都是由这个函数初始化的,通过阅读代码和使用gdb 工具,完成了下列动作:
    
       调用sched_init()函数来初始化调度程序;调用page_alloc_init()初始化伙伴系统分配程序;调用trap_init()和init_IRQ()完成异常和中断初始化;调用softirq_init()函数初始化软中断;调用time_init()函数初始化系统和时间;等等。。。
    
      启动过程分析:计算机上电后,加载BIOS的硬件信息与进行自我测试,读取并执行第一个启动设备内主引导记录内的Bootloader,依据bootloader的设置加载Kernel ,Kernel会开始检测硬件与加载驱动程序。这其中的每一部分都需要大篇的文字描述,这里只是重点从进程角度来了解一下:init_task进程(0号进程)是静态创造的,是内核开发人员创造的,而不是其他进程通过do_fork形成的。它从start_kernel()初始化直到start_kernel()中最后一个函数rest_init(),从rest_init开始,Linux开始产生进程,在rest_init函数中,内核将通过kernel_thread()产生第一个真正的进程(pid=1),而此时init_task的任务基本上已经完全结束了,它将沦落为一个idle 进程,事实上在更早前的sched_init()函数中,通过init_idle(current, smp_processor_id())函数的调用就已经把init_task初始化成了一个idle 进程。
  • 相关阅读:
    【LeetCode】206. Reverse Linked List
    【LeetCode】160. Intersection of Two Linked Lists
    【LeetCode】190. Reverse Bits
    【LeetCode】165. Compare Version Numbers
    继续深入《一张神奇的图》
    Base64编码简介
    证明任意两个正整数相等(伪命题)
    DEADBEEF
    汉诺塔问题
    字符编码(2)-- 程序中的编码
  • 原文地址:https://www.cnblogs.com/20189223cjt/p/9892676.html
Copyright © 2011-2022 走看看