- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
实验一操作系统的系统调用
实验一:系统调用
概述
通常来说,我们不需要直接访问Linux内核中的系统调用,而使用C函数库里面的代码,不过有时候我们会发现标准C函数库里面的函数并不能很好的满足我们的需要,而某个内核系统调用正好是我们所需的, 那我们还是应该毫不犹豫的去调用它的。
系统调用函数通常由用户进程在用户态下调用,内核通过system_call 函数响应系统调用产生的软中断,在正确访问核心栈、系统调用开关表之后陷入到操作系统内核中进行处理。
系统调用是用户进程由用户态切换到核心态的一种常见方式。编写系统调用函数可以直接调用了部分操作系统内核代码,。
使用
需要包含的头文件如下:#include linux/unistd.h
宏 _syscall
和其他函数调用一样,对于一个系统调用我们首先要知道的是它的原型。你必须知道它有多少调用参数,每个参数的类型,还有相关函数返回值得类型等。
_syscallX(type,name,type1,arg1,type2,arg2,...)
其中:
X 是0-5,实际上它指出了该系统调用会有多少个参数。
type 该系统调用返回的类型
name 该系统调用的名字
typeN 第N个参数的类型
argN 第N个参数的名字
这些宏创建一个名字为“name”的函数,这个函数的参数就是由你指定的。一旦你包含了_syscall()在你的源代码里面,你就可以用“name”来访问这个系统调用了。
#include stdio.h
#include linux/unistd.h
extern int errno;
_syscall1(int,sysinfo,struct sysinfo,s_info)
main()
{
struct sysinfo s_info;
error = sysinfo(s_info);
printf(“code error = %d\n”, error);
printf(“Uptime = %ds\nLoad: 1 min %d / 5 min %d / 15 min %d\n”
?RAM: total %d / free %d / shared %d\n”
?Memory in buffers = %d\nSwap: total %d / free %d\n”
?Number of processes = %d\n”,
s_info.uptime, s_info.loads[0],
s_info.loads[1], s_info.loads[2],
s_info.totalram, s_info.freeram,
s_info.sharedram, s_info.bufferram,
s_info.totalswap, s_info.freeswap,
s_info.procs);
return(0);
}
例子的输出:
code error = 0
uptime = 502034s
Load: 1 min 13376 / 5 min 5504 / 15 min 1152
RAM: total/ free 827392 / shared 8237056
Memory in buffers = 5066752
Swap: total/ freeNumber of processes = 40
注意syscall()这个宏不生成过程的调用原型,所以你要自己创建原型。你还需要仔细阅读源代码看看系统调用返回的值的意义。通常,返回的值是一个标准的错误代码,例如-EPERM。_syscall()这个宏返回系统调用的返回值r(如果r是非负数),但是如果r是负数,_syscall()则返回”-1”,而将全局变量errno设置为-r。某些系统调用,例如mmap,需要超过了5个参数,通常这些参数是被压入一个堆栈中,然后将这个参数对应的堆栈的指针传过去。但定义一个系统调用的时候,参数的类型这个参数必须是传一个值或者指针(例如结构体)。
添加系统调用
编写系统调用函数
编辑sys.c文件:
# cd /usr/src/linux/kernel
# vi sys.c
在文件的最后增加一个系统调用函数:
asmlinkage int sys_print_info(int testflag)
{
printk( Its my syscall function!n);
return 0;
}
该函数有一个int型入口参数testflag,并返回整数0。
修改与系统调用号相关的文件
编辑入口表文件:
# cd /usr/src/linux/arch/i386/kernel
# vi entry.S
把函数的入口地址加到sys_call_table表
文档评论(0)