目标:向内核添加系统调用long get_shed_times(unsigned long * num),程序调用此函数时,将此进程被调度的次数存入num指向的内存单元中,32位整数。
系统环境:CentOS 5.5 32bit + 2.6.18 source code + i386架构
首先在task_struct中添加调度计数变量unsigned long sched_times;
- include/linux/sched.h
-
- task_struct {
-
- .........
-
- unsigned long sched_times;
-
- ..........
-
- };
在创建新进程时将sched_times初始化为0
- kernel/fork.c do_fork()函数
-
- long do_fork(unsigned long clone_flags,
- unsigned long stack_start,
- struct pt_regs *regs,
- unsigned long stack_size,
- int __user *parent_tidptr,
- int __user *child_tidptr)
- {
- struct task_struct *p;
- int trace = 0;
- struct pid *pid = alloc_pid();
- long nr;
- ............
-
- p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr, nr);
- p->sched_times = 0;
- ................
-
- }
进程调度时,sched_times ++
- kernel/sched.c scheduale()函数
-
- asmlinkage void __sched schedule(void)
-
- {
-
- ........
-
- idx = sched_find_first_bit(array->bitmap);
- queue = array->queue + idx;
- next = list_entry(queue->next, struct task_struct, run_list);
- next->sched_times ++;
- if (!rt_task(next) && interactive_sleep(next->sleep_type)) {
- unsigned long long delta = now - next->timestamp;
- if (unlikely((long long)(now - next->timestamp) < 0))
- delta = 0;
- .........
-
- }
-
添加系统调用
- kernel/sys.c 最后边
-
- asmlinkage long sys_get_sched_times(unsigned long * addr)
-
- {
- printk(KERN_ALERT "get_sched_times called,sched_times=%d",current->sched_times);
- return copy_to_user(addr,&(current->sched_times),sizeof(long));
-
- }
添加系统调用号 include/asm/unistd.h
在最后,加入#define __NR_get_sched_times 318,并将NR_syscalls改为319
在文件中arch/i386/kernel/syscall_table.S最后添加如下内容:
OK,重新编译内核,重启。
测试:
通常,系统调用需要靠C库支持。但是,也可以直接用syscall或者用Linux本身提供的宏
宏: __syscalln() n的范围从0到6,代表需要传给系统调用的参数个数,例如open
long open(const char *filename, int flags,int mode);
#define __NR_open 5
__syscall3(long,open,const char*,filename,int,flags,int,mode)
上述方法在2.6.20以后就去掉了,因为有安全漏洞。
直接使用syscall(系统调用号,参数...)
-
- #include <stdio.h>
-
- int main()
- {
- unsigned long num;
- int i,x,sum=0;
-
- scanf("%d",&x);
- for(i=0;i<x*100;i++)
- sum = sum +i;
- printf("%d\n",sum);
-
- if(syscall(318,&num))
- printf("Failed\n");
- else
- printf("sched_times =%d\n",num);
- return 0;
- }
运行结果:
用户层
内核层
本文转自nxlhero 51CTO博客,原文链接:http://blog.51cto.com/nxlhero/699396,如需转载请自行联系原作者