zoukankan      html  css  js  c++  java
  • 2020-2021-1 20209320 《Linux内核原理与分析》第四周作业

    1.实验过程

    启动memu系统

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

    使用gdb跟踪调试内核

    $ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S 
    
     关于-s和-S选项的说明:
     1. -S freeze CPU at startup (use ’c’ to start execution)
     2. -s shorthand for -gdb tcp::1234 
     若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项  
    

    gdb指令打开gdb调试器

    start_kernel函数

    start_kernel执行过程

    1.调用sched_init()函数来初始化调度程序

    2.调用build_all_zonelists()函数俩初始化内存管理

    3.调用page_alloc_init()函数来初始化伙伴系统分配程序

    4.调用trap_init()函数和init_IRQ()函数以初始化IDT

    5.调用softing_init()函数初始化TASKLET_SOFTIRQ和HI_SOFTIRQ(软中断)

    6.调用time_init()初始化系统日期时间

    7.调用kmem_cache_init()函数初始化slab分配器(普通和高速缓存)

    8.调用calibrate_delay()函数用于确定CPU时钟(延迟函数)

    9.调用kernel_thread()函数为进程1创建内个线程,这个内核线程又会创建其他的内核线程并执行/sbin/init程序

    10.在start_kernel()开始执行之后会显示linux版本,除此之外,在init程序和内核线程执行的最后阶段还会显示很多其他信息。最后,就会在控制台上出现熟悉的登陆提示,通知用户Linux内核已经启动正在运行。

    Linux内核的启动在宏观上来看,就是start_kernel()来进行各种初始化工作,最终执行到rest_init()来初始化0号进程和1号用户态的进程。然后操作系统就运行起来了。
    rest_init()最后执行cpu_startup_entry();cpu_startup_entry会调用cpu_idle_loop(), 在cpu_idle_loop()里面有个while(1)的循环一直执行,作为idle进程,pid是0号,此进程会一直执行下去,并且在系统没有任何需要执行的进程时,调度到此进程。

    rest_init()函数分析

    • rest_init中调用kernel_thread函数启动了2个内核线程,分别是:kernel_init和kthreadd
    • 调用schedule函数开启了内核的调度系统,从此linux系统开始转起来了。
    • rest_init最终调用cpu_idle函数结束了整个内核的启动。也就是说linux内核最终结束了一个函数cpu_idle。这个函数里面肯定是死循环。
    • 简单来说,linux内核最终的状态是:有事干的时候去执行有意义的工作(执行各个进程任务),实在没活干的时候就去死循环(实际上死循环也可以看成是一个任务)。
    • 之前已经启动了内核调度系统,调度系统会负责考评系统中所有的进程,这些进程里面只有有哪个需要被运行,调度系统就会终止cpu_idle死循环进程(空闲进程)转而去执行有意义的干活的进程。这样操作系统就转起来了。

    总结

    linux内核的启动过程从start_kernel到init,整个linux系统的所有进程是一个树形结构,树根是0号进程 。Linux一开始先在无进程的情况下将一直从初始化部分的代码执行到start_kernel,然后再到其最后一个函数调用rest_init。从rest_init开始,Linux开始产生进程,在rest_init中,通过init_task产生pid=0的进程,即0号进程(idle进程),它是内核状态下的进程;在rest_init函数中,内核通过kernel_ini创建1号进程,它是第一个用户态进程。关于init_task(也就是idle),当运行队列中没有别的就绪进程时,init_task(也就是idle)将会被调用,它的核心是一个while(1)循环,在循环中它将会调用schedule函数以便在运行队列中有新进程加入时切换到该新进程上。

  • 相关阅读:
    python 爬取豆瓣电影短评并wordcloud生成词云图
    基于javaweb人脸识别注册登录系统
    html/jsp导出pdf格式的几种方法(jsPDF,iText,wkhtmltopdf)
    微信小程序wx.getLocation()获取经纬度及JavaScript SDK调用腾讯地图API获取某一类地址
    微信小程序登录流程及解析用户openid session_key,获取用户信息
    Windows Server 2012 R2服务器部署Tomcat JDK、安装Mysql以及将Java项目部署到CVM
    Tomcat出现端口占用错误
    linux cmake error undefined reference to symbol 'pthread_create@@GLIBC_2.2.5
    CMake Warning This command specifies the relative path as a link directory.
    linux vim查看文件编码格式
  • 原文地址:https://www.cnblogs.com/dyyblog/p/13898520.html
Copyright © 2011-2022 走看看