发布时间:2014-09-05 16:45:02作者:知识屋
目标:向内核添加系统调用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;
}
运行结果:
用户层
内核层
本文出自 “牛哥的博客” 博客
linux一键安装web环境全攻略 在linux系统中怎么一键安装web环境方法
Linux网络基本网络配置方法介绍 如何配置Linux系统的网络方法
Linux下DNS服务器搭建详解 Linux下搭建DNS服务器和配置文件
对Linux进行详细的性能监控的方法 Linux 系统性能监控命令详解
linux系统root密码忘了怎么办 linux忘记root密码后找回密码的方法
Linux基本命令有哪些 Linux系统常用操作命令有哪些
Linux必学的网络操作命令 linux网络操作相关命令汇总
linux系统从入侵到提权的详细过程 linux入侵提权服务器方法技巧
linux系统怎么用命令切换用户登录 Linux切换用户的命令是什么
在linux中添加普通新用户登录 如何在Linux中添加一个新的用户
2012-07-10
CentOS 6.3安装(详细图解教程)
Linux怎么查看网卡驱动?Linux下查看网卡的驱动程序
centos修改主机名命令
Ubuntu或UbuntuKyKin14.04Unity桌面风格与Gnome桌面风格的切换
FEDORA 17中设置TIGERVNC远程访问
StartOS 5.0相关介绍,新型的Linux系统!
解决vSphere Client登录linux版vCenter失败
LINUX最新提权 Exploits Linux Kernel <= 2.6.37
nginx在网站中的7层转发功能