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

《Linux内核分析》 第四周

PART ONE 知识点梳理 之 基础:用户态&内核态与系统调用的关系

1.用户态、内核态区别

  • 在高级别的状态下,代码可以执行特权指令,访问任意的物理地址;一般在Linux中,0xc0000000以上的地址(指的是逻辑地址)空间只能在内核态下访问;
  • 在相应的低级别执行状态下,代码的掌控范围会受到限制;

2.中断处理程序

  1. 中断指令会在寄存器上保存一些寄存器的值放入内核堆栈,比如:用户态栈顶地址,标志寄存器,cs:eip。同时,将相关联的中端服务历程的入口加载到cs:eip,把当前的堆栈段esp也加载到CPU里面
  2. 中断发生之后第一件事就是保存现场;中断处理结束前的最后一件事情就是恢复现场

3.系统调用

  1. 系统调用的三层皮

    • xyz,system_call,sys_xyz。即:API,中断向量,服务程序

PART TWO 使用库函数API和C代码中嵌入汇编代码触发同一个系统调用

1.知识储备

  1. 嵌入式汇编代码的参数传递过程

  2. 关于系统调用号

    • 通过查表可以得到API对应的系统调用号,这个参数是固定传递给eax寄存器的。如果函数有参数的话,可以利用ebx传递

2.实验过程

  1. 选取系统调用
    • nice函数系统调用号是34,作用是改变当前进程的优先级。其参数是一个int型的变量,作为当前进程要增加的优先级级数(级数越大,优先级越小)。如果调用成功的话,返回的是当前进程改变之后的优先级(这个数值的范围只能在-20——19之间);否则返回-1
  2. 实验过程
  • 使用函数API获取当前进程的优先级;

  • 进行编译,得到结果:1

  • 然后进行嵌入式汇编代码的编写

  • 结果如下:

  • 结果发现两次得到的结果不一样。这是为什么呢?

    • 其实是因为开始的时候没有注意到nice函数返回值的意义:它返回的是当前进程被改变的优先级,也就是在原有级数的基础上加上传进去的参数。所以,两次进程的原有优先级不同,得到的结果也不同
      • 第二次汇编如下:

PART THREE 总结

本周的自学过程与前两周比较更能锻炼自学能力:其一,在编写C代码以及嵌入式汇编代码的过程中,我查阅了很多系统调用的作用、参数值和返回结果,并且筛选出了我认为比较有代表性的(传递一个参数、返回一个int型变量的nice()函数);其二,对于前后两次代码意义相同但是结果不同的情况,我最初以为是自己编写错误,还误打误撞地学会了检验函数是否出错的方法(也就是errno变量的使用),并且更加深刻得理解了nice()函数的意义。

posted on 2016-03-19 21:20  20135211李行之  阅读(217)  评论(0编辑  收藏  举报