linux内核分析第五周学习笔记

linux内核分析第五周学习笔记

标签(空格分隔): 20135328陈都


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


一、给MenuOS增加time和time-asm命令

  • 把menu删除;

rm menu -rf 强制删除

  • 重新克隆一个新的Menu;

  • 进入Menu,用makerootfs自动编译生成根文件系统,同时还自动启动MenuOS

  • 增加了两个命令:time和time_asm,说明扩展了功能。

二、使用gdb跟踪系统调用内核函数sys_time

  • 一直按n单步执行会进入schedule函数

  • Sys_time返回后进入汇编代码处理gdb无法继续跟踪

  • 执行int 0x80之后执行system_call对应的代码

  • 让系统停在system_call的位置进行调试

  • 执行int 0x80之后执行system_call对应的代码

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

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

(1)进程调度的时机要分析一下

  • sys_call_table是系统调用分派表

  • syscall_after_all,需要先保存返回值

  • sys_exit_work

  • 没有这个就restore_all,返回用户态。

  • 一旦进入sys_exit_work:会有一个进程调度时机

    2.简化后便于理解的system_call伪代码:

(1)系统调用的工作机制一旦在start kernel初始化好之后,在代码中一旦出现inter 0x80的指令,它就会立即跳转到system_call这个位置
call *sys_call_table(,%eax,4)调用了系统调度处理函数,eax存的是系统调用号

(2)定义的宏SAVE_ALL和RESTORE_ALL

(3)当一个系统调用发生的时候,它进入内核处理这个系统调用,内核提供了一些服务,在这个服务结束返回到用户态之前,它可能会发生

进程调度,就会发生进程上下文的切换和中断上下文的切换。

3.system_call到iret之间的主要代码分析:

SAVE_ALL:保存现场;

syscall_call:调用了系统调用处理函数;

restore all:恢复现场(因为系统调用处理函数也算是一种特殊的“中断”);syscallexitwork:同上一条i;

INTERRUPT RETURN:也就是iret,系统调用到此结束;

archx86kernel raps.c中有一个函数,将SYSCALL_WECTOR(系统调用中断向量)和system_call汇编代码的入口绑定。完成初始化

简化汇编伪代码

Save_all保存现场

Sys_call_table:绑定系统调用函数

Interrupt_return:结束

韩玉琪同学总结得很到位,在此冒昧引用

系统调用就是特殊的一种中断

  1. 保存现场 在系统调用时,我们需要SAVE_ALL,用于保存系统调用时的上下文。 同样,中断处理的第一步应该也要保存中断程序现场。 目的:在中断处理完之后,可以返回到原来被中断的地方,在原有的运行环境下继续正确的执行下去。
  2. 确定中断信息 在系统调用时,我们需要将系统调用号通过eax传入,通过sys_call_table查询到调用的系统调用,然后跳转到相应的程序进行处理。
    同样,中断处理时系统也需要有一个中断号,通过检索中断向量表,了解中断的类型和设备。
  3. 处理中断 跳转到相应的中断处理程序后,对中断进行处理。
  4. 返回 系统调用时最后要restore_all恢复系统调用时的现场,并用iret返回用户态。 同样,执行完中断处理程序,内核也要执行特定指令序列,恢复中断时现场,并使得进程回到用户态。
原文地址:https://www.cnblogs.com/cdcode/p/5326858.html