Linux内核分析——Linux内核学习总结

时间:2023-01-24 20:31:18

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

              Linux内核学习总结

一、总结

(一)计算机是如何工作的

  1、冯诺依曼体系结构的核心思想是存储程序计算机。

  2、CPU在实际取指令时根据cs:eip来准确定位一个指令。

  3、寄存器模式,以%开头的寄存器标示符。

    立即数是以$开头的数值。

    直接寻址:直接访问一个指定的内存地址的数据。

    间接寻址:将寄存器的值作为一个内存地址来访问内存。

    变址寻址:在间接寻址之时改变寄存器的数值。

  4、eip寄存器不能被直接修改,只能通过特殊指令间接修改。

  5、在32位x86 CPU中,我们使用push和pop指令实现入栈和出栈,popl指令可以使得esp寄存器的值增加4。

  6、函数的返回值默认使用eax寄存器来返回给上级函数

(二)操作系统是如何工作的

  1、三个法宝:存储程序计算机、函数调用堆栈、中断机制。

  2、esp 堆栈指针

     ebp 基址指针(在C语言中用作记录当前函数调用基址)

  3、函数调用堆栈:首先使用gcc -g生成test.c的可执行文件test,然后使用objdump -S获得test的反汇编文件。

  4、函数my_start_kernel完成了0号进程的初始化和启动(入口是myprocess)。

  5、在my_schedule函数中,完成进程的切换。

  6、mykernel实验中,时钟中断处理函数是void my_timer_handler(void)。

  7、操作系统两把宝剑:中断上下文的切换、进程上下文的切换。

(三) 构造一个简单的Linux系统MenuOS

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

  2、sched_init()进程调度初始化函数,函数内关键的初始化——对0号进程,即idle进程进行初始化;

  3、Linux源码结构中,和进程间通信相关的目录是:ipc

  4、MenuOS 系统的文件系统支持的命令是:help、quit、version

  5、gdb中设置断点使用的命令是:break

(四) 扒开系统调用的三层皮(上)

  1、系统调用的三层皮:1API(xyz)、中断向量(system_call)、中断服务程序(sys_xyz)。

  2、system_call是linux中所有系统调用的入口点,每个系统调用至少有一个参数,即系统调用号。

  3、Linux中,系统调用号是使用eax寄存器传递的。系统调用号将API xyz和中断服务程序sys_xyz关联起来。

  4、Linux中可以通过执行int $128来执行系统调用。

  5、Linux中,用户态切换到内核态时,int指令会保存:用户态堆栈顶地址、当时的状态字、当时的cs:eip值

  6、系统是通过中断的方式将用户态转换为内核态,并通过调用系统函数来实现系统功能。

  7、当系统中断出现时,CPU保护现场和上下文切换来保护目前用户态所运行的状态,并通过返回系统调用函数的值来让用户判断是否已经有效地调用,结果如何。

  8、系统调用是一个软中断,中断号是0x80——通过int 0x80,触发系统调用

(五) 扒开系统调用的三层皮(下)

  1、make rootfs:一个脚本,自动编译自动生成根文件系统,并自动启动MenuOS。

  2、gdb

       (gdb)file linux-3.18.6/vmlinux  //在gdb界面中targe remote之前加载符号表

       (gdb)target remote:1234  //建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行

     (gdb)b sys_time

     (gdb)c   //启动到MenuOs,在MenuOs中使用time,会停在time函数处

     (gdb)list  //对应代码

     (gdb)s    //单步执行

     (gdb)finish  //将这个函数执行完

  3、32位x86 Linux系统中系统调用处理过程的最后一条汇编指令是iret。

  4、Linux内核中,系统调用处理过程中保护现场使用的宏是SAVE_ALL。

(六) 进程的描述和进程的创建

  1、操作系统的三大管理功能包括:进程管理、内存管理、文件系统

  2、PCB task_struct中包含:进程状态、进程打开的文件、进程优先级信息

  3、通过唯一的进程标识PID来区别每个进程。

  4、fork()系统调用从内核返回两次:一次回到父进程,另一次回到新产生的子进程。

  5、fork()实际上是由clone()系统调用实现的。

  6、Linux中,fork、vfork和clone三个系统调用都是通过调用do_fork来实现进程的创建。

  7、Linux中,1号进程是所有用户态进程的祖先,0号进程是所有内核线程的祖先。 

  8、Linux中,fork()系统调用产生的子进程在系统调用处理过程中从ret_from_fork处开始执行。

(七) 可执行程序的装载

  1、Linux下有三种目标文件格式,它们是:共享目标文件格式、可执行文件格式、可重定位文件格式。

  2、运行时动态装载链接至少需要用到函数:dlopen、dlsym

  3、一般系统调用库函数API的参数传递过程,比如execve系统调用,先进行函数调用参数传递,然后系统调用参数传递,最后又进行函数调用参数传递。  

  4、Linux下可以使用readelf命令查看分析ELF格式文件。

  5、ELF可执行文件会被默认映射到0x8048000这个地址。

  6、动态连接有两种形式:可执行程序装载时动态连接和运行时动态链接。

  7、execve执行静态链接程序时,通过修改内核堆栈中保存的eip的值作为新进程的起点。

  8、可执行程序加载的主要工作:当创建或者增加一个进程映像的时候,系统在理论上将拷贝一个文件的段到一个虚拟的内存段。

  9、32位x86进程地址空间共4G,内核空间是1G。

  10、如果是一个静态连接的文件,elf_entry就是指的main函数开始的位置。如果是一个需要依赖动态链接库的文件,elf_entry指向的是动态链接器的起点,将cpu控制权交给ld来加载依赖库并完成动态链接。

(八) 进程的切换和系统的一般执行过程

  1、不同类型的进程有不同的调度需求

  第一种分类:

    (1)I/O-bound:频繁进行I/O,花费很多时间等待I/O操作的完成。

    (2)CPU-bound:计算密集型,需要大量CPU时间进行计算。

  第二种分类:

    (1)批处理进程:不必交互、很快响应。

    (2)实时进程:要求响应时间短。

    (3)交互式进程(shell)。

  2、进程调度的时机:

    (1)中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule();

    (2)内核线程(只有内核态没有用户态的特殊进程)可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度;

    (3)用户态进程无法实现主动调度,只能被动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度。

  3、进程的切换

    (1)为了控制进程的执行,内核必须有能力挂起正在CPU上执行的进程,并恢复以前挂起的某个进程的执行,这叫做进程切换、任务切换、上下文切换;

    (2)挂起正在CPU上执行的进程,与中断时保存现场是不同的,中断前后是在同一个进程上下文中,只是由用户态转向内核态执行;

    (3)进程上下文包含了进程执行需要的所有信息

        1)用户地址空间:包括程序代码,数据,用户堆栈等

        2)控制信息:进程描述符,内核堆栈等

        3)硬件上下文(注意中断也要保存硬件上下文只是保存的方法不同)

  4、Linux进程调度是基于分时和优先级的。

  5、Linux中,内核线程是只有内核态没有用户态的特殊进程。 

  6、内核可以看作各种中断处理过程和内核线程的集合。

  7、Linux系统的一般执行过程 可以抽象成正在运行的用户态进程X切换到运行用户态进程Y的过程。 

  8、Linux中,内核线程可以主动调度,主动调度时不需要中断上下文的切换。  

  9、Linux内核调用schedule()函数进行调度,并调用context_switch进行上下文的切换,这个宏调用switch_to来进行关键上下文切换。

二、心得体会

  1、对Linux系统的理解及学习Linux内核的心得

     (1) 操作系统是指在整个系统中负责完成最基本功能和系统管理的那些部分。Linux操作系统是基于UNIX操作系统发展而来的一种克隆系统。它具有:完全免费、完全兼容POSIX 1.0标准、多用户,多任务、良好的界面、丰富的网络功能、可靠的安全、稳定性能、支持多种平台等特性。

     (2)内核独立于普通应用程序,一般处于系统态,拥有受保护的内存空间和访问硬件设备的所有权限。这种系统态和被保护起来的内存空间,统称为内核空间。在系统中运行的应用程序通过系统调用来与内核通信。

   (3)应用程序完成其工作的基本行为方式是:应用程序通过系统调用界面陷入内核。内核可以直接调用函数。

     (4)操作系统内核可以分为两大阵营:单内核和微内核(第三阵营是外内核,主要用在科研系统中)。Linux是一个单内核。

     (5)Linux内核有两种,稳定的和处于开发中的:从副版本号如果是偶数,就是稳定版,如果是奇数,就是开发版。

     (6)内核开发的特点:无libc库抑或标准头文件、没有内存保护机制、不轻易在内核中使用浮点数、容积小而固定的栈、同步和并发、可移植性。

     (7)内核有独一无二的特质。它实施自己的规则和奖惩措施,拥有整个系统的最高管理权。  

  2、收获

  光阴似箭,日月如梭,不知不觉已经过了半个学期,在这半个学期中,通过MOOC课程的视频学习、课本的自学以及课上老师的讲解,获得了很多知识。知道了计算机、操作系统是如何工作的,学会了构造一个简单的Linux系统MenuOS,理解了系统调用的三层皮:1API(xyz)、中断向量(system_call)、中断服务程序(sys_xyz)。进程的描述和进程的创建等内容。

  课堂上老师会对网课进行总结梳理、答疑解惑,让我们对知识的理解更加深刻。最后,谢谢老师的悉心教导!

三、每周MOOC课程笔记链接汇总

[第一周——计算机是如何工作的]   (http://www.cnblogs.com/20135235my/p/5219970.html)

[第二周——操作系统是如何工作的]   (http://www.cnblogs.com/20135235my/p/5237267.html)

[第三周——构造一个简单的Linux系统MenuOS]   (http://www.cnblogs.com/20135235my/p/5268446.html)

[第四周——扒开系统调用的三层皮(上)]   (http://www.cnblogs.com/20135235my/p/5291918.html)

[第五周——扒开系统调用的三层皮(下)]   (http://www.cnblogs.com/20135235my/p/5322737.html)

[第六周——进程的描述和进程的创建]   (http://www.cnblogs.com/20135235my/p/5349690.html)

[第七周——可执行程序的装载]   (http://www.cnblogs.com/20135235my/p/5372261.html)

[第八周——进程的切换和系统的一般执行过程]   (http://www.cnblogs.com/20135235my/p/5400741.html)