添加系统调用实验报告Word文件下载.docx
《添加系统调用实验报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《添加系统调用实验报告Word文件下载.docx(23页珍藏版)》请在冰点文库上搜索。
2.1.4、移动config-2.4.18forMP.txt到linux-2.4.18根目录,替换掉.config
2.1.5、进入linux-2.4.18目录,配置和编译内核模块
makeoldconfig
makedep
makeclean
makebzImage
makemodules
2.2内核安装与测试
2.2.1安装内核映像文件
cparch/i386/boot/bzImage/boot/vmlinux-2.4.18
2.2.2拷贝和安装Linux系统映射文件System.map,并创建其与系统映射文件System.map之间的符号链接
2.2.3执行命令makemodules_install以安装可动态加载的内核模块
2.2.4添加启动项的配置
利用vi编辑器,vigrub.conf
查看/所在的位置,为/dev/sda3
2.2.5reboot重新启动系统,从自己创建的内核启动系统
启动后查看内核
分别用uname–r,和dmesg查看
三、Linux系统调用添加与实现
3.1在内核增加系统调用
3.1.1结构体structsrz_rusage可声明如下:
.
structsrz_rusage{
structtimevalru_utime;
/*usertimeused*/
structtimevalru_stime;
/*systemtimeused*/
longru_majflt;
/*majorpagefaults*/
longru_minflt;
/*minorpagefaults*/
longru_nswap;
/*swaps*/
};
3.1.2添加到linux-2.4.18/include/linux下的resource.h中
3.1.3添加的系统调用名称为:
intget_process_usage(pid_t,structsrz_rusage*);
参考的getrusage和sys_getrusage的代码在linux-2.4.18/linux/kernel/sys.c下面
3.1.4
分析getrusage()和sys_getrusage()的源代码
1)数据结构rusage在头文件resource.h中定义。
structrusage{
structtimevalru_utime;
structtimevalru_stime;
longru_maxrss;
/*maximumresidentsetsize*/
longru_ixrss;
/*integralsharedmemorysize*/
longru_idrss;
/*integralunshareddatasize*/
longru_isrss;
/*integralunsharedstacksize*/
longru_minflt;
/*pagereclaims*/
longru_majflt;
/*pagefaults*/
longru_nswap;
/*swaps*/
longru_inblock;
/*blockinputoperations*/
longru_oublock;
/*blockoutputoperations*/
longru_msgsnd;
/*messagessent*/
longru_msgrcv;
/*messagesreceived*/
longru_nsignals;
/*signalsreceived*/
longru_nvcsw;
/*voluntarycontextswitches*/
longru_nivcsw;
/*involuntary"
*/
2)函数getrusage()的作用是获取系统资源使用情况。
/*
*Itwouldmakesensetoputstructrusageinthetask_struct,
*exceptthatwouldmakethetask_structbe*reallybig*.After
*task_structgetsmovedintomalloc'
edmemory,itwould
*makesensetodothis.Itwillmakemovingtherestoftheinformation
*alotsimpler!
(Whichwe'
renotdoingrightnowbecausewe'
renot
*measuringthemyet).
*
*ThisisSMPsafe.Eitherwearecalledfromsys_getrusageonourselves
*below(weknowwearen'
tgoingtoexit/disappearandonlywechangeour
*rusagecounters),orwearecalledfromwait4()onaprocesswhichis
*eitherstoppedorzombied.Inthezombiedcasethetaskwon'
tget
*reapedtillshortlyafterthecalltogetrusage(),inbothcasesthe
*taskbeingexaminedisinafrozenstatesothecounterswon'
tchange.
*FIXME!
Getthefaultcountsproperly!
intgetrusage(structtask_struct*p,intwho,structrusage*ru)
{
structrusager;
memset((char*)&
r,0,sizeof(r));
switch(who){
caseRUSAGE_SELF:
r.ru_utime.tv_sec=CT_TO_SECS(p->
times.tms_utime);
r.ru_utime.tv_usec=CT_TO_USECS(p->
r.ru_stime.tv_sec=CT_TO_SECS(p->
times.tms_stime);
r.ru_stime.tv_usec=CT_TO_USECS(p->
r.ru_minflt=p->
min_flt;
r.ru_majflt=p->
maj_flt;
r.ru_nswap=p->
nswap;
break;
caseRUSAGE_CHILDREN:
times.tms_cutime);
times.tms_cstime);
cmin_flt;
cmaj_flt;
cnswap;
default:
times.tms_utime+p->
times.tms_stime+p->
min_flt+p->
maj_flt+p->
nswap+p->
returncopy_to_user(ru,&
r,sizeof(r))?
-EFAULT:
0;
}
3)sys_getrusage()只是调用了内核函数getrusage(),是内核提供给用户的接口。
asmlinkagelongsys_getrusage(intwho,structrusage*ru)
if(who!
=RUSAGE_SELF&
&
who!
=RUSAGE_CHILDREN)
return-EINVAL;
returngetrusage(current,who,ru);
3.2编写应用程序调用该系统(调用)过程
3.2.1在sys.c中添加函数get_process_usage()和系统调用函数sys_get_process_usage()的代码;
目录linux-2.4.18/kernel/sys.c
int
get_process_usage(struct
task_struct
*p,struct
srz_rusage
*ru)
{
struct
r;
memset((char
*)
r,
0,
sizeof(r));
//比上次的实验报告里,更新的内容
printk(“Theprogram(get_process_usage)issuccessful!
\n”);
r.ru_utime.tv_sec=CT_TO_SECS(p->
r.ru_utime.tv_usec=CT_TO_USECS(p->
r.ru_stime.tv_sec=CT_TO_SECS(p->
r.ru_stime.tv_usec=CT_TO_USECS(p->
r.ru_minflt=p->
r.ru_majflt=p->
r.ru_nswap=p->
return
copy_to_user(ru,&
r,sizeof(r))?
-EFAULT:
0;
asmlinkage
long
sys_get_process_usage(pid_t
pid,struct
*p;
p=find_task_by_pid(pid);
if(p)
get_process_usage(p,ru);
-EINVAL;
3)修改完源程序以后,下一个任务是使Linux内核知道该程序的存在。
为了从已有的内核程序中增加到新的函数的连接,需要编辑两个文件。
第一个要修改的文件是/root/linux-2.4.18/include/asm-i386/unistd.h,该文件中包含了系统调用清单,用来给每个系统调用分配一个唯一的号码。
应该将新的系统调用名称加到清单的最后,并给它分配号码序列中下一个可用的系统调用号。
#define__NR_get_process_usage238
根据上图已知系统调用已经用到了237,我们用238
第二个要修改的文件是:
/root/linux-2.4.18/arch/i386/kernel/entry.S,该文件中有类似[.longSYMBOL_NAME()]的清单,该清单用来对sys_call_table[]数组进行初始化,该数组包含指向内核中每个系统调用的指针。
我们在清单最后添加一行:
.longSYMBOL_NAME(sys_get_process_usage)
编译安装内核以后的启动界面
四、编写程序调用新的系统调用
4.1.1程序一
头文件
//get_process_usag.h
#include<
/root/linux-2.4.18-srz/include/linux/resource.h>
/root/linux-2.4.18-srz/include/asm-i386/unistd.h>
源程序
//get_process_usag.c
#include"
get_process_usag.h"
stdio.h>
intget(pid_tpid);
intmain(intargc,char*argv[])
pid_tpid;
pid=atoi(argv[1]);
get(pid);
intget(pid_tpid)
structsrz_rusageru;
longr=0;
if(pid<
=0){
printf("
\nerror:
Pidmustint!
\n\n"
);
return0;
r=syscall(238,pid,&
ru);
if(!
r)
{
ShangRongZhusuccess!
User_time:
\t%dseconds:
%dmseconds\n"
ru.ru_utime.tv_sec,ru.ru_utime.tv_usec);
System_time:
%dmseconds\n"
ru.ru_stime.tv_sec,ru.ru_stime.tv_usec);
Minlostpage:
\t%d\n"
ru.ru_minflt);
Maxlostpage:
ru.ru_majflt);
Changepagetimes:
\t%d\n"
ru.ru_nswap);
else
Error,cheakthepid:
\n"
r);
编译
Gcc–otestsyscallgetpu_syscall.c
执行
./testsyscallpid_no
执行结果
Dmesg查看信息
4.1.2程序二
//get_process_syscall2.c
_syscall2(long,get_process_usage,pid_t,pid,structsrz_rusage*,ru)
r=get_process_usage(pid,&
执行结果如下
Gcc-otestsyscall2getpu_syscall2.c
dmesg查看
附件:
源程序一
:
第一种实现方法
第二种实现方法
intget(pid_t