标签:
操作系统中,内核提供了用户进程与内核进行交互的一组接口。这些接口让应用程序受限的访问硬件设备,提供了新进程与已有进程进行通信的机制,也提供了申请操作系统其他资源的能力。提供接口主要是为了保证系统稳定可靠,避免应用程序恣意妄行。
1. 系统调用:需要int 0x80模拟中断让硬件触发。同步、主动地进入系统空间。
2. 硬中断:异步、被动地进入系统空间。CPU运行时发生错误则中断,中断后没有进程调度。
3. 软中断:中断后还执行其他进程调度。
4. 系统调用过程:
5. 系统调用表:定义于arch/i386/kernel/syscall_table.S ,映射系统调用号和与系统调用。
6. 系统调用的过程:int 0x80 -> 中断向量表 ->系统调用表 JUMP(EAX*4+基地址)根据系统调用号找到对应的系统调用代码并执行。
1.系统调用在用户空间进程和硬件设备之间添加了一个中间层, 该层主要作用有三个:
1. API可以在各种不同的操作系统实现,给应用程序提供完全相同的接口,而它们本身在这些系统上的实现却可能迥异。
2.在Unix世界中,最流行的应用编程接口是基于POSIX标准的。
3. C库包括:
4. 程序员就只需要和API打交道,系统调用无关紧要。而内核只需要和系统调用打交道,只负责提供功能。
5. “提供机制而不是策略”——Unix的系统调用抽象出了用于完成某种确定的目的的函数,内核不用关心函数的使用方法。
6. 调用printf()函数时,应用程序、C库和内核之间的关系如下图:
1. 系统调用(在linux中常称作syscall),通常通过C库中定义的函数调用来进行。返回值是long型变量,如果出错,C库会将错误代码写入errno全局变量。
2. 系统调用再出现错误的时候C库会把错误码写入errno全局变量。通过调用perror()库函数,可以把该变量翻译成用户可以理解的错误字符串。
3. SYSCALL_DEFINE0只是一个宏,它定义一个无参数的系统调用。
4. asmlinkage——这是一个编译指令,通知编译器仅从栈中提取该函数的参数。
5. 系统调用在用户空间和内核空间有不同的返回值类型,在用户空间为int在内核空间为long。
1. 系统调用号一旦分配就不能再有任何变更。
2. 内核记录了系统调用表中的所有已注册过的系统调用的列表,存储在syscalltable中。在×86-64中,它定义于arch/i386/kernel/syscall_64.c文件中。
1. Linux系统执行快的原因:
1. 通知内核的机制是靠软中断实现的:
1. 在x86上,系统调用号是通过eax寄存器传递给内核的。
2. system_call()函数通过将给定的系统调用号与NR——syscall做比较来检查其有效性。
3. 由于系统调用表中的表项是以64位类型存放的,内核需要将给定的系统调用号乘以4,然后用所得到的结果在该表中查询其位置。
参数传递最简单的办法是像传递系统调用号一样,把这些参数也放在寄存器里。在X86-32系统上,ebx、ecx、edx、esi、edi按顺序存放前五个参数。需要六个或六个以上参数时应用一个单独的寄存器存放指向所有这些参数在用户空间地址的指针。
1. 决定系统调用的用途
2. 参数验证
最重要的一种检查就是检查用户提供的指针是否有效。内核必须保证:
- 指针指向的内存区域属于用户空间
- 指针指向的内存区域在进程的地址空间里,进程决不能绕过内存访问限制
- 进程不能绕过内存访问限制
最后一项检查针对是否有合法权限
3. 系统调用上下文
4. 绑定系统调用
5. 从用户空间访问系统调用
对于每个宏来说,都有2+2*n个参数
- 第一个参数对应着系统调用的返回值类型
- 第二个参数是系统调用的名称
- 在以后是按照系统调用参数的顺序排列的每个参数的类型和名称
建立一个新的系统调用的好处:
问题是:
替代方法:
实现一个设备节点,并对此实现read()和write()。使用特定的信息进行检索。
1. 系统调用到底是什么?
2. 系统调用与库函数和应用程序接口有怎样的关系?
3. 执行系统调用的连锁反应:
标签:
原文地址:http://www.cnblogs.com/20135228guoyao/p/5297421.html