《Linux内核分析》 读书笔记 第五章
本章的主要内容就是系统调用,下面将进行逐一分析:
一、系统调用
1.要访问系统调用(在Linux中常称作syscall),通常通过C库中定义的函数调用来进行。
2.负的返回值表示错误,0值通常表示成功。
系统调用在出现错误时C库会把错误码写入errno全局变量,通过调用perror()库函数,可以把该变量翻译成用户可以理解的错误字符串。
3.如何定义系统调用?
例:asmlinkage long sys_getpid(void)
1)函数声明中的asmlinkage是编译指令,通知编译器仅从栈中提取该函数的参数,所有的系统调用都需要这个限定词。
2)函数返回long。为了保证32位和64位的系统兼容,系统调用在用户空间的返回值类型为int,在内核空间为long。
3)命名规则:系统调用get_pid()在内核中被定义成sys_getpid(),bar()被定义为sys_bar()。
4.系统调用号:用来指明执行哪个系统调用,进程不会提及系统调用的名称。
注:系统调用号一旦分配就不能再改变;如果一个系统调用被删除,它所占用的系统调用号也不允许被回收利用。
Linux有一个“未实现”系统调用sys_ni_syscall(),用于针对无效的系统调用。
5.系统调用的性能
Linux系统调用比其他许多操作系统执行得要快,原因:
(1)Linux很短的上下文切换时间;
(2)系统调用处理程序和每个系统调用本身也都非常简洁。
二、软中断
1.软中断:通过引发一个异常来促使系统切换到内核态去执行异常处理程序。
在x86系统上软中断是中断号128,通过int $0x80指令触发该中断system_call()。
2.参数传递:
在x86-32系统上,ebx/ecx/edx/esi/edi按照顺序存放前五个参数;若需要六个及以上的参数,则用一个单独的寄存器存放指向所有这些参数在用户空间地址的指针。
给用户空间的返回值也通过寄存器传递。
三、系统调用的实现
(1)决定它的用途,不提倡多用途的系统调用。
(2)新系统调用的参数、返回值和错误码;
(3)设计接口时尽量为将来多做考虑。
绑定一个系统调用的步骤:
总结:
本章的主要内容就是Linux的系统调用,与上学期的《操作系统》课程有交集之处,结合云课堂中的视频教学,使我较透彻的理解了本章。
系统调用以软中断机制为主,由API、POSIX和C库协调工作。由于Linux的调用频率较低,由此看出该操作系统的稳定。