• Linux内核分析——第三周学习笔记


    20135313吴子怡.北京电子科技学院

    chapter1 知识点梳理

    一、Linux内核源代码简介

    (视频中对目录下的文件进行了简介,记录如下)

    1. arch目录

      占有相当庞大的空间
      arch/x86目录下的代码是需要重点关注的。
      arch下其他目录可以删掉。
    2. init目录

      内核启动相关的基本代码基本都在init目录下。
      main.c 文件中有一个start_kernel函数,初始化Linux内核的起点,这个函数相当于普通c程序的main函数。
    3. kernel目录

      Linux内核的核心代码在kernel目录中
    4. 其他

      Documentation 文档
      drivers 驱动
      fs-filesystem 文件系统
      include
      ipc 进程间通信
    5. README:

      INSTALLING 怎样安装内核源代码——怎么解压怎么打补丁
      make mrproper 把生成的中间代码清理干净
      menuconfig

    二、构造一个简单的Linux系统

    • 使用实验楼的虚拟机打开shell,命令如下:

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

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

    • 通过gdb跟踪内核的启动

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

      下载内核源代码编译内核

      cd ~/LinuxKernel/
      wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.18.6.tar.xz
      xz -d linux-3.18.6.tar.xz
      tar -xvf linux-3.18.6.tar
      cd linux-3.18.6
      make i386_defconfig
      make 

      制作根文件系统

      cd ~/LinuxKernel/
      mkdir rootfs
      git clone https://github.com/mengning/menu.git # 如果被墙,可以使用附件menu.zip
      cd menu
      gcc -o init linktable.c menu.c test.c -m32 -static –lpthread # 系统会默认启动init,即第一个用户态进程,1号进程
      cd ../rootfs
      cp ../menu/init ./
      find . | cpio -o -Hnewc |gzip -9 > ../rootfs.img # 镜像

      启动MenuOS系统

      cd ~/LinuxKernel/
      qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
    • 重新配置编译Linux使之携带调试信息
    1. 在原来配置的基础上,make menuconfig选中如下选项重新配置Linux,使之携带调试信息(由于在实验楼中操作,因此省略个别步骤)

    2. make重新编译

    • 使用gdb跟踪调试内核

      qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S 

      关于-s和-S选项的说明:
      -S freeze CPU at startup (use ’c’ to start execution) cpu初始化之前把它冻结起来
      -s shorthand for -gdb tcp::1234 在1234端口上建立了一个gdb server
      若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项

    打开另外一个shell

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

    三、跟踪调试Linux内核的启动过程

    1.使用gdb跟踪调试内核的方法

    除了前半部分提及的,以下部分为补充:

    (gdb)c # 系统开始启动,启动到start_kernel
    (gdb)list # 可以看到start_kernel上下的代码
    (gdb)break rest_init
    (gdb)c # 当前系统执行到rest_init
    (gdb)list # 可以看到rest_init是在start_kernel的尾部调用的。

    chapter2 实践实验过程

    ①构建Menu系统的过程

    ②使用gdb进行调试

    ③将断点设置到start_kernal

    ④将断点设置到rest_init

    chapter3  简单分析一下start_kernel(作业)

    ①在init目录下main.c里找到start_kernel函数

    ②全局变量init_task,即手工创建的PCB,0号进程即最终的idle进程。

    不管分析内核的哪一部分都会涉及到start_kernel.

    ③一些简要提及的函数

    trap_init() 初始化一些中断向量
    mm_init() 内存管理模块
    sched_init() 调度模块
    rest_init()中有kernel_thread(kernel_init,NULL,CLONE_FS),kernel_init中有run_init_process,创建了一号进程,默认路径下的程序。
    

    注意:init_process是一号进程。

    ④创建kthread(一个内核线程来管理系统的资源)。
    启动后,进入了一个cpu_idle,cpu_idle_loop,即一个while(0)的无限循环,或者说是idle进程,它作为0号进程适中存在于系统中。
    当系统没有进程需要执行时就需要调度idle进程。

    chapter4 总结

    阐明对“Linux系统启动过程”的理解。

    sched_init()初始化函数内对0号进程,即idle进程进行初始化。然后rest_init()其他初始化函数,函数内将创建1号进程,即init进程。随后rest_init实际上就是start_kernel内核一启动的时候会一直存在,这个就叫0号进程;0号进程创建了1号进程kernel_init和其他服务线程。这就是内核的启动过程。

    chapter5 附录

    作者:吴子怡

    学号:20135313

    原创作品转载请注明出处

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

  • 相关阅读:
    FineUIPro v5.1.0 发布了!
    FineUI十周年纪念版即将发布(基于像素的响应式布局,独此一家)!
    FineUIPro/Mvc/Core/JS v4.2.0 发布了(老牌ASP.NET控件库,WebForms,ASP.NET MVC,Core,JavaScript)!
    选择IT公司的雇主提问
    项目管理趋势
    突发事件下的项目管理
    12-Factor与微服务
    CQRS(Command and Query Responsibility Segregation)与EventSources实例
    阅读理解力的四个层次
    2018年Code Review状态报告
  • 原文地址:https://www.cnblogs.com/paperfish/p/5262306.html
Copyright © 2020-2023  润新知