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

    《庖丁解牛Linux内核分析》第三章

    Linux内核源代码简介

    使用cat /proc/version或uname -a命令,可以查看当前系统的Linux内核版本。

    • Linux内核源码目录结构

      • arch目录:与CPU体系结构相关的子目录列表

      • block目录:存放Linux存储体系中关于块设备管理的代码

      • crypto目录:存放常见的加密算法的C语言代码

      • drivers目录:驱动目录,里面分门别类地存放了Linux内核支持的所有硬件设备的驱动源代码

      • firmware目录:固件

      • fs目录:文件系统

      • include目录:存放公共的头文件

      • init:存放Linux内核启动时的初始化代码(lnit目录中的main.c源文件是整个Linux内核启动的起点,但它的起点不是main函数,是start_kernel函数。start_kernel函数是初始化Linux内核启动的起点。)

      • ipc目录:IPC是进程间通信,ipc目录里面是Linux支持的IPC的代码实现

      • kernel目录:kernel意思是内核,这个文件夹存放内核本身需要的一些核心代码文件,包括进程号pid等

      • lib目录:公用的库文件

      • mm目录:内存管理

    构造一个简单的Linux内核

    在“实验楼”虚拟机中,通过两个简单的命令就可以把Linux系统和一个简单的文件系统运行起来:

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

    使用自己的Linux系统环境搭建MenuOS的过程

    实验楼实验三

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

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

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

    内核启动完成后进入 menu程序,支持三个命令 help、version 和 quit。

    使用gdb跟踪调试内核

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

    用上述命令启动内核,发现被冻结了。

    再打开一个shell窗口,用Ctrl+Shift+O水平分割,启动gdb把内核加载进来,建立连接。

    
    /* 打开 GDB 调试器 */
    
    $ gdb
    
    

    在 GDB 中输入以下命令:

    
    /* 在gdb界面中targe remote之前加载符号表 */
    
    (gdb)file linux-3.18.6/vmlinux 
    
    /* 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行 */
    
    (gdb)target remote:1234
    
    /* 断点的设置可以在target remote之前,也可以在之后 */
    
    (gdb)break start_kernel 
    
    

    在start_kernel处设置断点,刚才是stop状态,如果按“c”继续执行,那么系统开始启动执行,启动到start_kernel函数的位置停在断点处,就可以看到start_kernel上下的代码。

    再设置一个断点rest_init,继续执行,停在断点处,可以看到rest_init是在start_kernel的尾部进行调用的。

    
    /* 在rest_init设置断点 */
    
    (gdb)break rest_init 
    
    /* 继续执行 */
    
    (gdb)c 
    
    

    start_kernel()与init_task()/reat_init()中部分函数的分析

    • start_kernel():相当于C语言中的main函数,是一切的起点。完成了Linux内核的初始化工作。每个内核部件都是用这个函数进行初始化的。在start_kernel()开始执行之后会显示linux版本,除此之外,在init程序和内核线程执行的最后阶段还会显示很多其他信息。最后,就会在控制台上出现熟悉的登陆提示,通知用户Linux内核已经启动正在运行。

    • init_task():几乎涵盖了内核的所有主要模块,是唯一没有通过fork方式产生的进程,使用宏进行初始化。

    • rest_init():通过rest_init()新建kernel_init和kthreadd内核线程。

    • 其中各函数功能如下:

      • sched_init():初始化调度模块

      • build_all_zonelists():初始化内存管理

      • page_alloc_init():初始化伙伴系统分配程序

      • trap_init()、init_IRQ():初始化中断向量

      • mm_init():初始化内存管理模块

      • softing_init():软中断,初始化TASKLET_SOFTIRQ和HI_SOFTIRQ

      • time_init():初始化系统日期时间

      • kmem_cache_init():普通和高速缓存,初始化slab分配器

      • calibrate_delay():延迟函数,用于确定CPU时钟

      • kernel_thread():为进程1创建内核线程,这个内核线程又会创建其他的内核线程并执行/sbin/init程序。所有内核线程都是直接或间接地以kthreadd为父进程的

      • kthreadd():管理和调度其他内核线程kernel_thread

    本周遇到的挫折

    虽然之前说安了虚拟机,其实这个假期才开始配置。然而,在任何一个教程中都会一笔带过的VMware下载环节,我遭遇了很多挫折!!!看过了一个帖子总结的可能遇到的所有报错!!!其中,安装VM需要的vmnetbridge.dll在哪这个问题问了我无数遍。

    后来我新的一轮下载中,给我们的VMware小朋友新建了个文件夹,不知为什么就好了。虽然这问题很傻没什么意义,但鉴于我终于按好了很开心,所以来这叨叨两句~

    此为本人Linux学习第四周的内容,如有不足,还请批评指正,不胜感激。

    以上

  • 相关阅读:
    LightOJ 1344 Aladdin and the Game of Bracelets
    CF 1132A,1132B,1132C,1132D,1132E,1132F(Round 61 A,B,C,D,E,F)题解
    CF 1130A 1130B 1130C1129A1 1129A2 1129B(Round542A B C D1 D2 E)题解
    CF 1131A,1131B,1131C,1131D,1131F(Round541 A,B,C,D,F)题解
    CoderForces-Round60D(1117) Magic Gems
    CoderForces Round60-(1117A,1117B,1117C题解)
    LightOJ 1038 Race To 1 Again(概率DP)
    XHXJ'S LIS(数位DP)
    CF 55D Beautiful Numbers(数位DP)
    LightOJ 1229 Tablecross
  • 原文地址:https://www.cnblogs.com/qianxiaoxu/p/11617468.html
Copyright © 2011-2022 走看看