zoukankan      html  css  js  c++  java
  • Linux内核分析——构造一个简单的Linux系统MenuOS

    马悦+原创作品转载请注明出处+《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

    一、Linux内核源代码简介

    1、计算机三大法宝

      存储程序计算机

      函数调用堆栈

      中断机制

    2、操作系统两把宝剑

      中断上下文的切换

      进程上下文的切换

    3、函数目录

      Linux-3.18.6/arch/x86

      内核启动相关的代码基本都存在init目录中。

      start_kernel函数相当于普通C程序的main函数。

      Linux内核的核心代码在kernel目录中。

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

    实验过程:

    进入实验楼的虚拟机,打开shell。

    cd Linuxkernel/

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

     

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

    三、使用gdb跟踪调试Linux内核的方法

    1、使用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)

      # -s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项

     

    当前状态是被冻结起来的。

    2、gdb设断点

    (1)另外打开一个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之前,也可以在之后

    (2)设置完断点后,输入c命令继续执行,函数会停在断点处。

     

    (3)输入list指令可以查看断点处的代码。

    四、简单分析start_kernel

    1、全局变量init_tast:即手工创建的pcb,0号进程即最终的idle进程。

    2、trap_init:硬件中断,初始化一些中断向量,系统调用。

       set_intr_gate:设置中断门。

         set_system_trap_gate:系统陷阱门SYSCALL VECTOR。

    3、mm_init:内存管理模块初始化。

    4、sched_init:进程调度初始化函数,函数内做了很关键的一步初始化——对0号进程,即idle进程进行初始化。

    5、rest_init:其他初始化函数,函数内将创建1号进程,即init进程。

    6、init_process:是linux系统中的1号进程,是第一个用户态进程,默认根目录下的init程序。

    7、kthreadd:内核线程,用来管理系统资源。

    五、总结

      1、道生一,一生二,二生三,三生万物。

      2、start_kernel函数相当于普通C程序的main函数。内核启动过程包括start_kernel之前和之后,之前全部是做初始化的汇编指令,之后开始C代码的操作系统初始化,最后执行第一个用户态进程init。

      3、总的来说,x86架构的Linux内核启动过程分为6大步,分别为:
         (1)实模式的入口函数_start():在header.S中,这里会进入众所周知的main函数,它拷贝bootloader的各个参数,执行基本硬件设置,解析命令行参数。
         (2)保护模式的入口函数startup_32():在compressed/header_32.S中,这里会解压bzImage内核映像,加载vmlinux内核文件。
         (3)内核入口函数startup_32():在kernel/header_32.S中,这就是所谓的进程0,它会进入体系结构无关的start_kernel()函数,即众所周知的Linux内核启动函数。start_kernel()会做大量的内核初始化操作,解析内核启动的命令行参数,并启动一个内核线程来完成内核模块初始化的过程,然后进入空闲循环。
         (4)内核模块初始化的入口函数kernel_init():在init/main.c中,这里会启动内核模块、创建基于内存的rootfs、加载initramfs文件或cpio-initrd,并启动一个内核线程来运行其中的/init脚本,完成真正根文件系统的挂载。
         (5)根文件系统挂载脚本/init:这里会挂载根文件系统、运行/sbin/init,从而启动众所周知的进程1。
           (6)init进程的系统初始化过程:执行相关脚本,以完成系统初始化,如设置键盘、字体,装载模块,设置网络等,最后运行登录程序,出现登录界面。

  • 相关阅读:
    算法----(1)冒泡排序
    淘宝爬虫
    爬虫_豆瓣电影top250 (正则表达式)
    爬虫_猫眼电影top100(正则表达式)
    Android 简单调用摄像头
    Android 简单天气预报
    思维模型
    This view is not constrained, it only has designtime positions, so it will jump to (0,0) unless you
    Android studio preview界面无法预览,报错render problem
    Android studio 3.1.2报错,no target device found
  • 原文地址:https://www.cnblogs.com/20135235my/p/5268446.html
Copyright © 2011-2022 走看看