系统调用和快速系统调用
来源:互联网 发布:ugui源码调试 编辑:程序博客网 时间:2024/05/23 11:25
欢迎访问小站,阅读原文http://www.yandong.org/archives/519
介绍
系统调用,顾名思义,说的是操作系统提供给用户程序调用的一组“特殊”接口。用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件系统相关的调用请求系统打开文件、关闭文件或读写文件,可以通过时钟相关的系统调用获得系统时间或设置定时器等。
从逻辑上来说,系统调用可被看成是一个内核与用户空间程序交互的接口——它好比一个中间人,把用户进程的请求传达给内核,待内核把请求处理完毕后再将处理结果送回给用户空间。
什么是快速系统调用
在产生一个中断(广义的中断,包括硬中断、软中断、异常)后,处理器中控制器会进行一系列权限检查,只有得到核实后,控制单元才设置中断处理所需要的执行环境。基于软中断int 0×80的系统调用同样也需要作一系列的检查,才能进入内核态进行系统调用的处理工作。
由于系统调用的特点,这一系列权限检查变得多余。为此Intel在Pentium II处理器中引入了一对新的指令SYSENTER/SYSEXIT,用于实现快速系统调用;其中指令SYSENTER用于进入内核态,而指令SYSEXIT用于从内核态返回。这两条该指令避免了权限检查,直接将处理器置为预定义的运行级别(基于软中断的系统调用需要从门描述符中获得运行级别信息)。同时,通过将系统调用所需的执行环境信息保存在一组型号相关寄存器(Model Specific Register,简称MSR)中,避免了访问内存,进一步提高进入内核态的速度。下面分小节对快速系统调用进行全面的介绍和分析。
如何检查系统是否支持快速系统调用呢?
static int my_init_module(void){if (!boot_cpu_has(X86_FEATURE_SEP)) { printk(KERN_ERR "NOT SUPPORT \n");return 0;}printk(KERN_ERR "SUPPORT \n"); return 0;}修改linux系统调用
原理: 系统调用都在sys_call_table的表里面,修改这个表里面的东西可以达到修改系统调用的目的,
另外获取sys_call_table地址的一个简单方式是在/boot/system.map里面查找
#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/file.h>#include <linux/fs_struct.h>#include <linux/fdtable.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/syscalls.h>#include <linux/list.h>#include <linux/jiffies.h>#include <linux/cdev.h>#include <asm/unistd.h>#include <asm/uaccess.h>#include <linux/path.h>#include <linux/time.h>#include <linux/stat.h>#include <net/sock.h>#include <net/inet_sock.h>#include <asm/cpufeature.h>#define MY_FILE "/root/linux_kernel_info"static int my_init_module(void);static void my_cleanup_module(void);unsigned int clear_and_return_cr0(void);void setback_cr0(unsigned int val);unsigned long **sys_call_table = (unsigned long **)0xc0509940;int orig_mkdir;unsigned int orig_cr0;/** * 清除写保护*/unsigned int clear_and_return_cr0(void){ unsigned int cr0 = 0; unsigned int ret; asm volatile ("movl %%cr0, %%eax" : "=a"(cr0) ); ret = cr0; /* clear the 20 bit of CR0, a.k.a WP bit */ cr0 &= 0xfffeffff; asm volatile ("movl %%eax, %%cr0" : : "a"(cr0) ); return ret;}/** *设置cr0,--本程序用来恢复写保护*/void setback_cr0(unsigned int val){ asm volatile ("movl %%eax, %%cr0" : : "a"(val) );}int hacked_mkdir(const char __user *pathname, int mode){printk(KERN_ALERT "mkdir do nothing\n", MY_FILE);return 0; /*everything is ok, but he new systemcall does nothing*/}static int my_init_module(void){printk(KERN_ALERT "sys_call_table %x\n", sys_call_table);orig_mkdir=(int)(sys_call_table[__NR_mkdir]);printk(KERN_ALERT "sys_call_table %x\n", orig_mkdir);orig_cr0 = clear_and_return_cr0(); //清除写保护 sys_call_table[__NR_mkdir]=(void *)hacked_mkdir; setback_cr0(orig_cr0); return 0;}static void my_cleanup_module(void){ printk(KERN_ALERT "Module %s unloaded.\n", MY_FILE);orig_cr0 = clear_and_return_cr0(); sys_call_table[__NR_mkdir]=(void *)orig_mkdir; /*set mkdir syscall to the origal one*/setback_cr0(orig_cr0);}module_init(my_init_module);module_exit(my_cleanup_module);MODULE_LICENSE("GPL");MODULE_AUTHOR("Nilushan Silva");MODULE_DESCRIPTION("task_struct offset Finder");
获取sys_call_table的方式
链接
http://www.ibm.com/developerworks/cn/linux/kernel/l-k26ncpu/
http://book.51cto.com/art/200810/93833.htm
http://blog.csdn.net/misterliwei/article/details/4351592
待续。。。
- 系统调用和快速系统调用
- 快速系统调用
- 库函数调用和系统调用
- 库函数调用和系统调用
- 系统调用和函数调用
- 快速调用系统对话框(全)
- 如何快速调用系统相机
- 系统调用和库函数
- 库函数和系统调用
- 系统调用和库函数
- 库函数和系统调用
- 库函数和系统调用
- 系统调用和库函数
- API和系统调用
- 系统调用和API
- 系统调用和库函数
- 系统调用和库函数
- 系统调用和库函数
- 通过SQL语句或数据库,生成数据库模型PDM方法详解
- 14周项目2:抽象基类shape
- 第十四周—2.Shape类及其派生类中的纯虚函数
- 学习cocos2d-x之路(4)--实现Hero在各个方向移动
- frambuffer 节点注册过程
- 系统调用和快速系统调用
- TuneUp Utilities
- Java 基础源码 switch语句判断指定月份属于一年中的哪个季度
- 析构函数
- Javascript 两数相除保留两位小数点
- APP被苹果App Store拒绝的79个原因(未完待续)
- dispatch_once函数创建单例
- 值得开发者关注的8个HTML5 API
- iOS编译ffmpeg