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

    MenuOS的构造

    Linux内核源代码简介

    操作系统“两把宝剑”:

    • 中断上下文——保护现场和恢复现场
    • 进程上下文

    查看当前系统的Linux内核版本

    $ cat /proc/version
    或
    $ uname -a
    

    Linux内核源码目录结构

    • arch目录:与CPU体系结构相关的子目录列表
    • block目录:存放Linux存储体系中关于块设备管理的代码
    • crypto目录:存放常见的加密算法的C语言代码
    • Documentation目录:存放一些文档
    • drivers目录:驱动目录,里面分门别类地存放了Linux内核支持的所有硬件设备的驱动源代码
    • firmware目录:固件
    • fs目录:文件系统,列出了Linux支持的各种文件系统的实现。
    • include目录:头文件目录,存放公共的头文件
    • init:存放Linux内核启动时的初始化代码
    • ipc目录:IPC是进程间通信,ipc目录里面是Linux支持的IPC的代码实现
    • kernel目录:kernel意思是内核,这个文件夹存放内核本身需要的一些核心代码文件,包括进程号pid等
    • lib目录:公用的库文件
    • mm目录:内存管理
    • net目录:存放网络相关的代码

    构造一个简单的Linux内核

    $ 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 CPU初始化之前冻结起来
    #   -s 在1234端口上创建一个gdb-server 
    

    启动gdb

    (gdb)file linux-3.18.6/vmlinux 
    #在gdb界面中target remote之前加载符号表
    
    (gdb)target remote:1234
    #用1234这个端口进行连接
    
    (gdb)break start_kernel
    #在start_kernel处设置断点
    

    start_kernel()函数

    函数分析

    setup_arch(&command_line);   //设置与初始化硬件体系相关的环境并调用
    
    sched_init()                 //初始化调度器,先于中断开始前
    
    printk(boot_command_line);   //提取分析核心启动参数过程(从
    bootloader 中传递)
    
    trap_init();                  //自陷入口函数初始化,针对此版本arm中直接return
    
    early_irq_init();              //中断初始化过程
    
    init_IRQ();          
    
    init_timers();                //初始化定时器,开启定时器软中断服务以及注册服务程序以及初始化各CPU中的tev_base等init_timers()->run_timer_softirq()->__run_timers() 
    
    timekeeping_init(); 
    
    time_init(); //设置定时器及返回当前时间
    console_init() //初步的初始化控制台,此控制台只能打印出一些简单//的启动信息…
    
    mem_init(); //初始化内存并计算可用内存大小
    
    kmem_cache_init(); // 初始化SLAB缓存分配器
    
    calibrate_delay(); //延迟校准,jiffy,记录系统的定时器的节拍数,每变化一次代表了系统定时器2个连续节拍时间的间隔。
    
    fork_init(num_physpages); //初始化max_threads,init_task参数为fork()提供参考
    
    buffer_init(); //初始化块设备读写缓冲区
    
    vfs_caches_init(num_physpages);   //初始化虚拟文件系统 
    
    inode_init() ->files_init() ->mnt_init()...
    
    signals_init(); //初始化内核信号队列….
    
    rest_init(); //最后实际进入reset_init()函数,包括所有剩下的硬件//驱动,线程初始化等过程…这也最终完成//start_kernel//的启动过程。
    

    rest_init()函数

    rest_init()新建kernel_init和kthreadd内核线程。
    kthreadd函数的任务是管理和调度其他内核线程kernel_thread,所有的内核线程都是直接或间接以kthreadd为父进程。

    遇到的问题和理解

    本地虚拟机上装不上qemu

    解决方法:

    建立软连接

    $sudo ln -s /usr/bin/qemu-system-i386 /usr/bin/qemu

    "0"号进程和"1"号进程的理解

    “0号进程”即idle进程,系统创建的第一个进程,也是唯一一个没有通过fork或者kernel_thread产生的进程。它创建了1号进程“kernel_init”和其他进程。

    “1号进程”即init进程,是第一个用户态进程,通过rest_init()->kernel_init()->run_init_process生成。

    参考博客

  • 相关阅读:
    14:求满足条件的3位数
    1696:逆波兰表达式
    筛法求素数 6分
    1751:分解因数
    1750:全排列
    1788:Pell数列
    666:放苹果
    06:寻宝
    04:最匹配的矩阵
    雷电
  • 原文地址:https://www.cnblogs.com/20209318zs/p/13908351.html
Copyright © 2011-2022 走看看