linux内核模块编程文件读,内核模块编程——通过proc文件系统读取内核xtime

#include

#include

#include

#include

//#include

#define procfs_name "xtime"

struct proc_dir_entry

*clock_proc_file;

static int procfile_read(char *page,char

**start,off_t offset,int count,int *eof,void *data)

{

int ret;

struct timespec x_time=current_kernel_time();

//struct timeval tv;

//do_gettimeofday(&tv);

printk(KERN_INFO"procfile_read(/proc/%s)called\n",procfs_name);

//判断offset,这是很重要的,因为来自库的标准读函数将持续发布读系统调用直到内核答复没有更多信息

//或它的缓冲区被填满。

if(offset>0){

ret=0;

}

else{

ret=sprintf(page,"tv_sec:%ld\ttv_nsec:%ld\n",x_time.tv_sec,x_time.tv_nsec);

}

return ret;

}

static int __init proc_init(void){

clock_proc_file=create_proc_entry(procfs_name,0644,NULL);

if(clock_proc_file==NULL){

remove_proc_entry(procfs_name,NULL);

printk(KERN_ALERT"Error:Could not initialize

/proc/%s\n",procfs_name);

return -ENOMEM;

}

clock_proc_file->read_proc=procfile_read;

clock_proc_file->owner=THIS_MODULE;

clock_proc_file->mode=S_IFREG|S_IRUGO;

clock_proc_file->uid=0;

clock_proc_file->gid=0;

printk(KERN_INFO"/proc/%s created\n",procfs_name);

return 0;

}

static void __exit proc_exit(void){

remove_proc_entry(procfs_name,NULL);

printk(KERN_INFO"/proc/%s removed\n",procfs_name);

}

module_init(proc_init);

module_exit(proc_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("WuYang");

proc_root未定义(未找到需添加的头文件,搜索结果有的说也没找到办法,目前只能设为NULL)

WARNING: "xtime" [/home/wuyang/procfs.ko]

undefined!

xtime是全局变量,在linux/time.h中有

extern struct timespec

xtime;但是在程序中并不能直接使用(不知道什么原因)。一种方法是利用current_kernel_time()函数来得到xtime。

函数定义如下:struct timespec current_kernel_time(void)

528{

529 struct timespec now;

530 unsigned long seq;

531

532 do {

533 seq = read_seqbegin(&xtime_lock); 534

535 now = xtime_cache;

536 } while (read_seqretry(&xtime_lock, seq));

537

538 return now;

539}

可用cat等命令测试或者自己编写小程序,如下:

#include

#include

#include

int main(){

FILE *fp;

struct timeval time;

char buffer[40];

fp=fopen("/proc/xtime","r");

fgets(buffer,40,fp);

//printf("%d\nsizeof(char)=%d\nsize of

buffer=%d\n",n,sizeof(char),strlen(buffer));

gettimeofday(&time,NULL);

printf("%stv_sec:%ld\ttv_usec:%ld\n",buffer,time.tv_sec,time.tv_usec);

}

奇怪的是buffer小到一定时(比如50)输出就会有乱码,不知道什么原因fread用起来还挺复杂!

加上输出strlen(buffer)当设为50时输出为55设为55时输出为60100时,输出为21(21为正确长度)现改由fgets实现

另外,xtime时timespec解构体,其定义为:

14struct timespec {

15 time_t

tv_sec; 16 long tv_nsec; }

通过gettimeofday()得到的时timeval结构体,定义为:

20struct timeval {

21 time_t tv_sec; 22 suseconds_t tv_usec; }

ret=sprintf(page,"%ld\t%ld",x_time.tv_sec,x_time.tv_nsec);

发现sprintf可以直接将内核数据输出到用户空间缓冲区,而不用copy_to_user!

更正:此处的page为内核空间缓冲区,无需copy_to_user

但是不把数据放到用户空间缓冲区,用户程序怎么取得该数据呢?!

data为proc_dir_entry的私有数据指针,data指向的也即是该proc文件的缓冲区(数据存储区),初始化时为结构体中的data指针初始化后,read_proc和write_proc函数参数中的data指针会自动传递为结构体中初始化的指针值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值