Linux内核学习总结

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

眨眼间,我学习的孟老师的第二门网易云的课程就要结束了,通过这次的课程我依旧受益良多。
下面是对这次课程的总结
1. 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的

冯诺依曼体系结构的计算机,又叫存储程序计算机,从硬件的角度来看,其工作模型是CPU依次读取内存中的指令来完成工作。这节课详细介绍了CPU计算模块、寄存器和内存是如何配合工作的。
2. 完成一个简单的时间片轮转多道程序内核代码

mykernel是由老师建立的一个用于开放自己的操作系统的内核平台,它基于Linux Kernel 3.9.4 source code。通过本讲的学习和实验,我们知道操作系统的核心功能就是:进程调度和中断机制,通过与硬件的配合实现多任务处理,再加上上层应用软件的支持,最终变成可以使用户可以很容易操作的计算机系统。还了解到进程的调度和时间中断的概念。知道了一个进程在内核中,被描述为一个结构体,储存了进程的pid,运行状态,堆栈,以及sp和ip等重要信息。通过分析my_schedule的汇编代码,了解到了进程切换的关键过程。我们可以认为一个进程相当于一个堆栈,每个进程有自己的堆栈空间。如果将ebp和esp修改为另一个进程的ebp和esp,并且完成一些寄存器的保存,就相当于完成的进程的切换。
3. 跟踪分析Linux内核的启动过程

start_kernel()是内核的汇编与C语言的交接点,在该函数以前,内核的代码都是用汇编写的,完成一些最基本的初始化与环境设置工作。start_kernel就像是c代码中的main函数。不管你关注Linux的内核模块,总是离不开start_kernel函数的,因为大部分模块的初始化工作都是在start_kernel中完成的。按照这节课的实验步骤,跟踪Linux内核的启动过程。通过自己编译内核源码,并且调试了启动过程,了解到内核在启动时经历了哪些初始化。内核几乎所有的初始化都是在start_kernel进行的,在start_kernel之前主要是汇编代码完成的一些操作。在start_kernel中会初始化中断向量,内存管理模块,调度模块等一系列初始化。在最后的rest_init()中会初始化0号进程和1号用户态进程,然后最终启动系统。
4. 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

即便是最简单的程序,也难免要用到诸如输入、输出以及退出等操作,而要进行这些操作则需要调用操作系统所提供的服务,也就是系统调用。除非你的程序只完成加减乘除等数学运算,否则将很难避免使用系统调用。在 Linux 平台下有两种方式来使用系统调用:利用封装后的 C 库(libc)或者通过汇编直接调用。这节课介绍了系统调用的概念,以及如何使用系统调用。
5. 分析system_call中断处理过程

通过gdb我们可以给系统调用内核处里程序如sys_write, sys_time设置断点,并让程序停在断点处,进行断点跟踪系统调用处里过程。由于system_call是完全用汇编写就一个的函数,虽然我们也可以在system_call处设置断点,但却无法让系统停在system_call处,所以也无法通过单步跟踪学习其处里流程。但system_call是所有系统调用的入口,也是程序由用户态转入内核态执行时无法越过的一个函数,其重要性不言而喻,所以我们跟随老师简化的汇编代码以及源代码学习其主要的流程。
6. 分析Linux内核创建一个新进程的过程

为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息。在Linux应用程序的开发中,可以通过fork、vfork和clone等API来创建一个子进程,它们在Linux内核中对应的系统调用分别为sys_fork、sys_vfork和sys_clone函数,而这些函数最终都会调用do_fork完成子进程的创建。do_fork主要是复制了父进程的task_struct,然后修改必要的信息,从而得到子进程的task_struct。
7. Linux内核如何装载和启动一个可执行程序

Linux系统可以通过execve API启动一个新进程,该API又呼叫sys_execve系统调用,负责将新的程序代码和数据替换到新的进程中,打开可执行 文件,载入依赖的库文件,申请新的内存空间,最后执行 start_thread(regs, elf_entry, bprm->p) ,设置 new_ip, new_sp ,完成新进程的代码和数据替换,然后返回,接下来就是执行新的进程代码了。
8. 进程的切换和系统的一般执行过程

   Linux系统的一般执行过程,最一般的情况是:正在运行的用户态进程X切换到运行用户态进程Y的过程要经过以下步骤

   1). 正在运行的用户态进程X
   2). 发生中断:save cs:eip/esp/eflags(current) to kernel stack, then load cs:eip(entry of a specific ISR) and ss:esp(point to kernel stack).
   3). SAVE_ALL //保存现场,这里是已经进入内核中断处里过程
   4). 中断处理过程中或中断返回前调用了schedule(),其中的switch_to做了关键的进程上下文切换
   5). 标号1之后开始运行用户态进程Y(这里Y曾经通过以上步骤被切换出去过因此可以从标号1继续执行)
   6). restore_all //恢复现场
   7). iret - pop cs:eip/ss:esp/eflags from kernel stack
   8). 继续运行用户态进程Y

总结

通过本学期孟宁老师的linux内核的课程学习,对linux内核有了一个大致的认识和了解,和上学期的孟老师的高软课程一样,依然是网易云课堂的教学方式,这种方式我十分喜欢,通过自己看教学视频,再与老师进行讨论并自己动手做实验这一个模式可以说十分高效合理。当然,这短时间的学习不能说能对linux的内核有多深入的理解,只是初窥linux内核的模样,以后还需要更多的学习才能有更深入的理解。俗话说师父领进门,修行在个人。老师在这门课中扮演的是引路人的角色,而这条路走得好不好主要还是看我们以后如何继续学习。总之通过课程的学习,我对linux内核有了一个大致的了解,遗憾就是毕竟学时有限,无法通过课程学习的更加深入,以后还需要自己的多多学习。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值