모듈 프로그래밍 하고 있는데 그냥 다운이 되네요.
set_freq.c라는 파일을 모듈로 적재하기 위해
make
insmod set_freq.ko
mknod /dev/task_check_dev c 251 0
./task_check_app
도대체 이유를 모르겠네요.
모드도 올라갔는데, 실행을 시키면 컴퓨터가 다운이 되네요.
FEDORA 8이고, 커널 버전은 2.6.21.7입니다.
밑에 소스 헤더 파일에 꺽쇠 없는건 tag땜에 지웠으니까 신경쓰지 마세요.
소스는 여기에.
set_freq.c ===>
#include linux/kernel.h
#include linux/module.h
#include linux/sched.h
#include linux/fs.h
#include linux/timer.h
#include linux/time.h
#include linux/timex.h
#include linux/interrupt.h
#include linux/init.h
#include linux/mc146818rtc.h
#include linux/ioport.h
#include asm/8253pit.h
#include asm/pgtable.h
#include asm/hpet.h
#include linux/hpet.h
#include linux/sysdev.h
#include linux/bcd.h
#include linux/kallsyms.h
#include linux/acpi.h
#include acpi/achware.h
#include asm/sections.h
#include linux/cpufreq.h
#include asm/apic.h
#include asm/msr.h
#include asm/processor.h
#include asm/cpufeature.h
#include linux/types.h
#define DEV_NAME "task_check_dev"
#define PIT_TICK_RATE 1193180Ul
//extern u64 __xdiv64_32(u64 n, u32 d);
//extern void panic(const char * fmt, ...);
u64 __udivdi3(u64 n, u64 d)
{
/*
if( d & ~0xffffffff)
panic("Need true 64-bit/64-bit division");
return __xdiv64_32(n, (u32)d);
*/
return n;
}
//static struct timer_list my_timer;
MODULE_LICENSE( "GPL" );
static int major;
int a=1,b=1,c=1;
spinlock_t test_lock = SPIN_LOCK_UNLOCKED;
static void sync_core();
static unsigned int get_current_cpu_frequency();
static void sync_core()
{
int tmp;
asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
}
static unsigned int get_current_cpu_frequency()
{
unsigned long start, end;
unsigned long flags;
spin_lock_irqsave(&test_lock, flags);
outb(0xb0, 0x43);
outb((PIT_TICK_RATE / 20) & 0xff, 0x42);
outb((PIT_TICK_RATE / 20) >> 8, 0x42);
rdtscll(start);
sync_core();
while((inb(0x61) & 0x20) == 0 );
sync_core();
rdtscll(end);
spin_unlock_irqrestore(&test_lock, flags);
return (end - start) / 50;
}
static void set_cpu_freq(int value)
{
int d,e;
int l,h;
struct cpufreq_freqs freqs;
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
printk("%#010x, %#010x\n",l,h);
if (!(l & (1
l = (1
printk("trying to enable Enhanced SpeedStep (%x)\n", l);
wrmsr(MSR_IA32_MISC_ENABLE, l, h);
/* check to see if it stuck */
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
printk("%d, %d\n",l,h);
if (!(l & (1
printk("couldn't enable Enhanced SpeedStep\n");
//return -ENODEV;
}
}
rdmsr(MSR_IA32_PERF_STATUS, a, b);
printk("%d, %d\n",a,b);
d = (a >> 8) & 0xff;
d = d * 100000;
e = (b >> 8) & 0xff;
e = e * 100000;
printk("%d,%d\n" ,d,e);
rdmsr(MSR_IA32_PERF_CTL, d, b);
printk("%d,%d\n",d,b);
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
c = 10;
c = (c
wrmsr(MSR_IA32_PERF_CTL, c, b);
//wrmsr(MSR_IA32_PERF_STATUS, c, c);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
rdmsr(MSR_IA32_PERF_STATUS, d, e);
d = (d >> 8) & 0xff;
d = d * 100000;
e = (e >> 8) & 0xff;
e = e * 100000;
printk("%d,%d\n" ,d,e);
}
static int cal_freq(unsigned long long tick_count)
{
unsigned long long result;
result = tick_count / 1000000;
result = result / 1000000;
if(result
return 8;
else if (result >= 1000 && result
return 10;
else
return 12;
}
static int task_check_ioctl(struct inode *inode, struct file *fp, unsigned int op_code, unsigned long arg)
{
struct task_struct * search;
unsigned long long request_tick_count;
int count=1;
int value;
int cur_freq;
//start point of task list
search = &init_task;
//request_tick_count init
//if init_task is running
if( search->state == TASK_RUNNING )
request_tick_count = search->sched_time;
else //if init task is not running
request_tick_count = 0;
//printk(" init_task counter = %d\n", search->counter );
while( next_task(search) != &init_task )
{
//search = search->next_task;
search = next_task(search);
//count++;
//if init_task is running
if( search->state == TASK_RUNNING )
{
request_tick_count += search->sched_time;
count++;
}
printk("%d\n", count);
//printk("counter : %llu\n", search->sched_time);
//printk("\n");
}
//if( request_tick_count
//request_tick_count = 13;
printk("request tick count is %llu\n", request_tick_count);
printk("total #of process : %d\n", count);
value = cal_freq( request_tick_count );
set_cpu_freq(value);
cur_freq = get_current_cpu_frequency();
printk("current cpu frequency : %d\n", cur_freq);
return 0;
}
static struct file_operations task_check_fops = {
.ioctl = task_check_ioctl
};
int init_module()
{
printk( KERN_ALERT "load task check module\n");
major = register_chrdev( 0, DEV_NAME, &task_check_fops);
if( major
{
printk("Register the device failed\n");
return major;
}
else
{
printk("%s device major number : %d\n", DEV_NAME, major);
}
rdmsr(MSR_IA32_PERF_STATUS, a, b);
return 0;
}
void cleanup_module()
{
if( unregister_chrdev(major, DEV_NAME)
printk("unregister failed\n");
else
printk( KERN_ALERT "unload task check module\n");
wrmsr(MSR_IA32_PERF_CTL, a, b);
}
==========================================
task_check_app.c ===>
#include stdio.h
#include fcntl.h
#include sys/time.h
#include unistd.h
#include signal.h
#define DEV_NAME "/dev/task_check_dev"
static struct itimerval itimer;
static void sig_handler(int);
int main()
{
int fd;
fd = open( DEV_NAME, O_RDWR );
loop:
ioctl(fd, 0, NULL);
sleep(3);
goto loop;
return 0;
}
=========================
Makefile ===>
obj-m += set_freq.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.ko
rm -rf *.mod.*
rm -rf .*.cmd
rm -rf *.o
댓글 달기