期末总结 & 博客汇总

总结与博客链接

攥写人:于涵 学号:20132119

( *原创作品转载请注明出处*)

( 学习课程:《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-100

博客链接(前几次是新浪微博后统一换成博客园):

1.反汇编一个简单的C程序:
http://blog.sina.com.cn/s/blog_e43db01b0102w6ho.html
2.操作系统是如何工作的:
http://blog.sina.com.cn/s/blog_e43db01b0102w6wk.html
3.跟踪分析Linux内核的启动过程:
http://blog.sina.com.cn/s/blog_e43db01b0102w7bo.html
4.使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用:
http://www.cnblogs.com/yuhan20132119/p/5299172.html
5.分析system_call中断处理过程:
http://www.cnblogs.com/yuhan20132119/p/5322807.html
6.分析Linux内核创建一个新进程的过程:
http://www.cnblogs.com/yuhan20132119/p/5341695.html
7.Linux内核如何装载和启动一个可执行程序:
http://www.cnblogs.com/yuhan20132119/p/5371399.html
8.理解进程调度时机跟踪分析进程调度与进程切换的过程:
http://www.cnblogs.com/yuhan20132119/p/5402435.html

总结

第一章:

1、pushl %eax

把eax压栈到堆栈栈底

即首先把esp减4

esp表示堆栈栈顶

ebp表示堆栈基址

2、popl %eax

把eax从堆栈栈顶取32位,放在寄存器eax中

即首先把栈顶esp的数值放在eax中,再把栈顶加4

3、call 0x12345

调用该地址

即将当前的eip(当前CPU执行命令的指针)压栈,赋给eip一个新值(CPU下一条执行的指令)

4、ret

即将call时保存的eip还原到eip寄存器,return call之前的那条指令

eip(*)这个*指程序员不能直接修改eip

第二章:

cs : eip:总是指向下一条的指令地址

• 顺序执行:总是指向地址连续的下一条指令

• 跳转/分支:执行这样的指令的时候,cs : eip的值会

根据程序需要被修改

• call:将当前cs : eip的值压入栈顶,cs : eip指向被

调用函数的入口地址

• ret:从栈顶弹出原来保存在这里的cs : eip的值,放

入cs : eip中 

第三章:

  操作系统两把宝剑:

  1、中断上下文的切换:保存现场和恢复现场

  2、进程上下文的切换

  使用gdb跟踪调试内核

  输入以下命令

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

  -S表示:在CPU初始化之前,冻结CPU

  -s表示在:1234端口上创建一个tcp接口

第四章:

  如何区分用户态、内核态

  CPU每条指令的读取都是通过cs:eip(代码段选择寄存器:偏移量寄存器)这两个寄存器,由硬件完成判断。

    内核态时,cs与eip的值可以访问任意地址

    用户态时,cs与eip只可以访问0x00000000—0xbfffffff的地址空间

   系统调用的三层皮

    一层皮:API

    二层皮:中断向量对应的中断服务程序

    三层皮:系统调用对应的很多不同种类的服务程序

第五章:

  系统调用在内核代码中的处理过程

  系统调用在内核代码中的工作机制和初始化

  整个系统调用过程中,时间很重要。

  以system_call为例,int 0x80指令与systemcall是通过中断向量联系起来的,而API和对应的sys是通过系统调用号联系起来的

  用户态时,系统调用xyz()使用int 0x80,它对应调用system_call

第六章:

  操作系统三大功能

     进程管理  内存管理  文件系统

   0号进程是手工写入它的进程描述符数据,1号进程的创建是复制了0号进程的PCB,根据1号进程的需要,修改PID,加载一个init可执行程序。

  创建一个新进程在内核中的执行过程

  fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建。

  Linux通过复制父进程来创建一个新进程,那么这就给我们理解这一个过程提供一个想象的框架:

  复制一个PCB——task_struct

  要给新进程分配一个新的内核堆栈

  要修改复制过来的进程数据,比如pid、进程链表等等都要改改,见copy_process内部。

  从用户态的代码看fork();函数返回了两次,即在父子进程中各返回一次,父进程从系统调用中返回比较容易理解,子进程从系统调用中返回。那它在系统调用处理过程中的哪里开始执行的呢?这就涉及子进程的内核堆栈数据状态和task_struct中thread记录的sp和ip的一致性问题,这是在哪里设定的?copy_thread in copy_process

 

第七章:

  可执行程序是怎么来的

  C代码—>预处理—>汇编代码—>目标代码—>可执行文件

  ELF中三种目标文件

  一个可重定位(relocatable)文件保存着代码和适当的数据,用来和其他的object文件一起来创建一个可执行文件或者是一个共享文件。(主要是.o文件)

  一个可执行(executable)文件保存着一个用来执行的程序;该文件指出了exec(BA_OS)如何来创建程序进程映象。

  一个共享object文件保存着代码和合适的数据,用来被下面的两个链接器链接。第一个是连接编辑器[请参看ld(SD_CMD)],可以和其他的可重定位和共享object文件来创建其他的object。第二个是动态链接器,联合一个可执行文件和其他的共享object文件来创建一个进程映象。(主要是.so文件)

  execve和fork都是特殊的系统调用

  正常的系统调用:陷入到内核态,返回到用户态,执行系统调用的下一条指令。

  fork:进入到内核态,两次返回:第一次返回到父进程的位置,继续执行。第二次,在子进程中从ret_from_fork开始执行然后返回用户态。

  execve:当前的可执行程序执行到execve时,陷入到内核态,用execve加载的可执行文件将当前的可执行程序覆盖掉,当execve系统调用返回时,返回的不是原来的系统调用,而是新的可执行程序的执行起点,即main函数的位置。

第八章

进程分类

  第一种分类

I/O-bound:等待I/O

  CPU-bound:大量占用CPU进行计算

  第二种分类

  交互式进程(shell)

  实时进程

  批处理进程

调度策略:是一组规则,它们决定什么时候以怎样的方式选择一个新进程运行

  Linux的调度基于分时优先级

  Linux的进程根据优先级排队

  根据特定的算法计算出进程的优先级,用一个值表示

  这个值表示把进程如何适当的分配给CPU

  Linux进程中的优先级是动态的

  调度程序会根据进程的行为周期性地调整进程的优先级

  例如:

  较长时间未被分配到cpu的进程,通常↑

  已经在cpu上运行了较长时间的进程,通常↓

  内核中的调度算法相关代码使用了类似OOD中的策略模式

   分析schedule函数  

    schedule()函数选择一个新的进程来运行,并调用context_switch进行上下文的切换,这个宏调用switch_to来进行关键上下文切换

     next = pick_next_task(rq, prev);//进程调度算法都封装这个函数内部

    context_switch(rq, prev, next);//进程上下文切换

    switch_to利用了prev和next两个参数:prev指向当前进程,next指向被调度的进程

转载于:https://www.cnblogs.com/yuhan20132119/p/5450673.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值