• 2019-2020-1 20199308《Linux内核原理与分析》第四周作业


    《Linux内核分析》

    第三章 MenuOS的构造

    3.1 Linux内核源代码简介

    • 操作系统的“两把宝剑”
      • 中断上下文:保存现场和恢复现场
      • 进程上下文
    • 目录结构
      • arch:与体系结构相关的子目录列表,存放CPU体系结构的相关代码
      • block:存放Linux存储体系中关于块设备管理的代码
      • crypto:存放常见的加密算法的C语言代码
      • Documentation:存放一些文档
      • drivers:驱动目录,里面分门别类的存放了Linux内核支持的所有硬件设备的驱动源代码
      • firmware:固件
      • fs:文件系统(file system),里面列出了Linux支持的各种文件系统的实现
      • include:头文件目录,存放公共的(各种CPU体系结构共用的)头文件
      • init:存放Linux内核启动时的初始化代码
        注:init目录中的main.c源文件是整个Linux内核启动的起点,但它的起点不是main函数,而是start_kernel函数
      • ipc:Linux支持的IPC的代码实现(IPC:进程间通信,inter-process communication)
      • kernel:Linux内核,存放内核本身需要的一些核心代码文件
      • lib:公用的库文件,里面是一些公用的库文件(与C语言的库函数不一样)
      • mm:内存管理memoty management,存放Linux的内存管理代码
      • net:网络相关的代码
    • 在开发一个软件项目时,一般会在项目根目录下写一个readme文件
    • 编译配置Linux内核的关键步骤
      • 1.编译安装内核大概步骤
        • 安装开发包组
        • 下载源码文件
        • .config:准备配置文件
        • make menuconfig:配置内核有选项
        • make[-j#]
        • make modules_install:安装模块
        • make install:安装内核相关文件
        • 安装bzImage为 /boot/vmlinuz-VERSION-RELEASE
        • 生成initramfs文件
        • 编辑grub的配置文件
      • 2.编译配置选项
        • 配置内核选项
        • 支持“更新”模式进项配置:make help
          • make config:基于命令行以遍历的方式去配置内核中可配置的每个选项
          • make menuconfig:基于curses的文本窗口界面
          • make gconfig:基于GTK(GNOME)环境窗口界面
          • make xconfig:基于QT(KDE)环境的窗口界面
        • 支持“全新配置”模式进行配置
          • make difconfig:基于内核为目标平台提供的“默认”配置进行配置
          • make allyesconfig:所有选项均回答为“yes”
          • make allnoconfig:所有选项均回答为“no”
      • 3.编译
        • 全编译:make [-j#]

    3.2 构造一个简单的Linux内核

    • 构建Linux系统MenuOS在实验楼平台上运行
    • 代码:
    $ cd ~/LinuxKernel/
    $ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
    
    • 运行截图:

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

    • 用以下命令启动内核,冻结起来
    $ 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选项
    

    • 水平分割,启动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 
    

    • 再设置一个断点rest_init,继续执行,停在断点处。

    分析关键的函数

    • start_kernel函数的执行过程
    asmlinkage __visible void __init start_kernel(void)
    {
        char *command_line;
        char *after_dashes;
        
        /*
         * Need to run as early as possible, to initialize the
         * lockdep hash:
         */
        lockdep_init();
        set_task_stack_end_magic(&init_task);// init_task即手工创建的PCB,0号进程即最终的idle进程
        smp_setup_processor_id();
        debug_objects_early_init();
        // ...
        trap_init();                          // 中断向量的初始化
        mm_init();                            // 内存模块的初始化
        sched_init();                         // 调度模块的初始化
        // ...
        rest_init();                          // rest_init是0号进程(是使用宏初始化的),它创建1号进程init和其他的一些服务进程
    }
    
  • 相关阅读:
    C#轻量级企业事务
    扩展方法
    JDK Environment Variable And Change default JDK
    AsyncTask简单获取网络图片的例子
    mysql基础
    Oracle基础操作
    java 中 colkection集合、迭代器、增强for、泛型
    centos7 解决 mysql_connect()不支持请检查mysql模块是否正确加载
    python 操作MySQL避坑1064
    面向对象学习
  • 原文地址:https://www.cnblogs.com/hsj910/p/11626091.html
Copyright © 2020-2023  润新知