当前位置: 首页 > news >正文

Linux内核分析5

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

 

一、学习总结

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

二、实验过程

实验环境是使用本课程配备的实验楼虚拟机环境,打开命令行客户端,cd LinuxKernel目录,使用命令rm -rf menu删除原来的代码,使用git clone https://github.com/mengning/menu.git获取menu的最新代码,然后 cd menu 进入menu子文件夹,使用gedti test.c打开文件,讲我上周实验的代码拷贝改写成为menu的两个菜单项,主要代码部分如下:

 

  1. int SayHello(int argc, char *argv[])  
  2. {  
  3.         char* msg = "Hello World";  
  4.         printf("%s", msg);  
  5.   
  6.         printf("\n");  
  7.   
  8.         return 0;  
  9. }  
  10.   
  11. int SayHelloAsm(int argc, char *argv[])  
  12. {  
  13.         char* msg = "Hello World";  
  14.         int len = 11;  
  15.         int result = 0;  
  16.   
  17.         __asm__ __volatile__("movl %2, %%edx;\n\r"   
  18.                 "movl %1, %%ecx;\n\r"   
  19.                  "movl $1, %%ebx;\n\r"   
  20.                  "movl $4, %%eax;\n\r"   
  21.                   "int  $0x80"   
  22.                 :"=m"(result)   
  23.                 :"m"(msg),"r"(len)    
  24.                 :"%eax");   
  25.   
  26.         printf("\n");  
  27.   
  28.         return 0;  
  29. }  
  30.   
  31. int main()  
  32. {  
  33.     PrintMenuOS();  
  34.     SetPrompt("MenuOS>>");  
  35.     MenuConfig("version","MenuOS V1.0(Based on Linux 3.18.6)",NULL);  
  36.     MenuConfig("quit","Quit from MenuOS",Quit);  
  37.     MenuConfig("time","Show System Time",Time);  
  38.     MenuConfig("time-asm","Show System Time(asm)",TimeAsm);  
  39. <strong>    MenuConfig("sayhello","Say Hello World",SayHello);  
  40.     MenuConfig("sayhello-asm","Say Hello World",SayHelloAsm);</strong>  
  41.     ExecuteMenu();  
  42. }  


这里主要就是加了两个菜单项 sayhello 和 sayhello-asm 及其对应的实现函数,保存 test.c 函数,使用 make rootfs 编译运行 menuos 系统,输入help 可以看到我们新加入的菜单:

 

使用 gdb 跟踪相关的函数过程,在我前述的博客中有笔记详细的描述,有兴趣的可以参考下:http://blog.csdn.net/sunyeyi/article/details/44517109,这里主要就是说明下,我们可以在 gdb 里使用 b system_call 设置断点,但是却无法让程序停在这个地方。当然网上也有资料提供了其他技术来跟踪这个函数,由于个人时间能力所限,没有去研究!

 

三、通过源代码分析 system_call 处理流程 

先看下系统调用机制的初始化,在start_kernel函数中,trap_init函数就是完成系统调用初始化的。

 

  1. trap_init();  


在trap_init()函数中,关键代码如下,通过中断向量,将system_call函数和0x80绑定:

 

\arch\x86\kernel\traps.c

  1. #ifdef CONFIG_X86_32  
  2.     set_system_trap_gate(SYSCALL_VECTOR, &system_call);  
  3.     set_bit(SYSCALL_VECTOR, used_vectors);  
  4. #endif  

 

 

据此,用户态代码只要执行 int 0x80 中断,就会由 system_call 函数来处里。

再来看看system_call源代码,http://codelab.shiyanlou.com/xref/linux-3.18.6/arch/x86/kernel/entry_32.S,490行处。

根据这段源代码,参考老师在视频中的讲述,我们可以得到system_call的简化流程图如下:

这里我们需要特别注意的就是,在系统调用system_call返回之前,会检查当前进程是否需要执行syscall_exit_work,如果不需要就restore_all,然后中断返回了;如果需要处里,那么就在syscall_exit_work流程中查看是否有进程信号需要处理,若有就处里,是否需要进程调度,若有就调用schedule,切换到其他进程执行;然后才restore_all,中断返回。

 

四、总结

通过中断向量表,int 0x80和system_call关联起来;system_call又是通过系统调用号,将每一个系统调用和特定的系统调用服务例程关联起来;在system_call返回用户态之前,会执行syscall_exit_work,work_notifysig,schedule等函数以应对可能的进程信号处理和进程调度。

转载于:https://www.cnblogs.com/20132216zzx/p/5307051.html

相关文章:

  • C#基础知识点
  • 不用bootstrap,只用CSS创建网格布局
  • 次小生成树模板
  • 最大非连续子序列
  • MongoDB 数据库安装
  • 返回一个整数数组中最大子数组的和
  • 魔兽登录系统
  • 任务栏托盘不消失的问题-有启示
  • OAuth2 基于TP 搭建简单案例
  • __OSX_AVAILABLE_STARTING
  • simpson公式求定积分
  • hdu 1166 敌兵布阵(线段树详解)
  • java获取获得Timestamp类型的当前系统时间。
  • 在SQLServer使用触发器实现数据完整性
  • 软件测试学习日志3 ————软件测试作业之控制流图
  • angular组件开发
  • ECMAScript6(0):ES6简明参考手册
  • express + mock 让前后台并行开发
  • Javascript基础之Array数组API
  • JS笔记四:作用域、变量(函数)提升
  • Python - 闭包Closure
  • sublime配置文件
  • Yeoman_Bower_Grunt
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 分布式任务队列Celery
  • 复杂数据处理
  • 记一次和乔布斯合作最难忘的经历
  • 简析gRPC client 连接管理
  • 实现简单的正则表达式引擎
  • 手写双向链表LinkedList的几个常用功能
  • 优化 Vue 项目编译文件大小
  • Java总结 - String - 这篇请使劲喷我
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (1)Android开发优化---------UI优化
  • (70min)字节暑假实习二面(已挂)
  • (day 12)JavaScript学习笔记(数组3)
  • (Python) SOAP Web Service (HTTP POST)
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (二)构建dubbo分布式平台-平台功能导图
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (论文阅读40-45)图像描述1
  • (一)Thymeleaf用法——Thymeleaf简介
  • (一一四)第九章编程练习
  • (转)setTimeout 和 setInterval 的区别
  • (转载)CentOS查看系统信息|CentOS查看命令
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .NET/C# 将一个命令行参数字符串转换为命令行参数数组 args