这是我在内核级别的模块:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/miscdevice.h>
static struct miscdevice my_dev;
struct time_check
{
time_t tv_sec_ker;
time_t tv_sec_nsday;
long int tv_nsec_ker;
long int tv_nsec_nsday;
}time;
ssize_t read_function(struct file *file_pointer, char *buffer, size_t count, loff_t *offset);
int open_function(struct inode *node_pointer,struct file *file_pointer);
static const struct file_operations file_op = {
.read = read_function,
.open = open_function,
};
int open_function(struct inode *node_pointer,struct file *file_pointer)
{
printk(" opened the file module\n");
return 0;
}
ssize_t read_function(struct file *file_pointer,char *buffer,size_t count,loff_t *offset)
{
int error_no=0;
struct timespec gets_time;
struct time_check time_s;
if(access_ok(VERIFY_READ,buffer,2*sizeof(struct timespec)))
{
struct timespec cur_time=current_kernel_time();
printk("current_kernel_time:\n%lld %lld\n",(long long)(cur_time.tv_sec),(long long)(cur_time.tv_nsec));
getnstimeofday(&gets_time);
printk("getnstimeofday:\n%lld %lld\n",(long long)(gets_time.tv_sec),(long long)(gets_time.tv_nsec));
time_s.tv_sec_ker=cur_time.tv_sec;
time_s.tv_nsec_ker=cur_time.tv_nsec;
time_s.tv_sec_nsday=gets_time.tv_sec;
time_s.tv_nsec_nsday=gets_time.tv_nsec;
printk("current_kernel_time_copied:\n%lld %lld\n",(long long)(time_s.tv_sec_ker),(long long)(time_s.tv_nsec_ker));
printk("getnstimepfday_copied:\n%lld %lld\n",(long long)(time_s.tv_sec_nsday),(long long)(time_s.tv_nsec_nsday));
if(copy_to_user(buffer,&time_s,sizeof(time_s)))
error_no=-EFAULT;
}
else
{
error_no=-EFAULT;
}
return error_no;
}
int init_function(void)
{
int retval;
my_dev.minor = MISC_DYNAMIC_MINOR;
my_dev.name = "mytime";
my_dev.fops = &file_op;
retval = misc_register(&my_dev);
if (retval) return retval;
printk("got minor %i\n",my_dev.minor);
return 0;
}
void exit_function(void)
{
misc_deregister(&my_dev);
}
module_init(init_function);
module_exit(exit_function);
这是我的用户级功能:
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include <sys/stat.h>
struct time_check
{
time_t tv_sec_ker;
time_t tv_sec_nsday;
long int tv_nsec_ker;
long int tv_nsec_nsday;
}ti;
int main()
{
FILE *fd;
int count;
struct time_check time;
/* open device */
fd = fopen("/dev/mytime","r");
/* read from device */
count =fread(&time,sizeof(time),1,fd);
printf("Return value %d\n", count);
printf("size of time:%ld\n",sizeof(time));
printf("ker_sec:%ld\nker_nsec:%ld\nnsday_sec:%ld\nnsday_nsec:%ld\n",time.tv_sec_ker,time.tv_nsec_ker,time.tv_sec_nsday,time.tv_nsec_nsday);
/* close device */
fclose(fd);
return 0;
}
但我无法复制结构。我无法理解我哪里做错了。 它在用户级别打印一些垃圾值。
返回值0
时间大小:32
ker_sec:0
ker_nsec:4196144
nsday_sec:0
nsday_nsec:4195696
任何人都可以告诉我应该做些什么更改才能成功复制结构
答案 0 :(得分:0)
您给出错误的返回值。
read_function应返回您复制到用户空间的确切数字。
你返回error_no,所以如果复制成功,它应该是struct“time_s”的大小。
输出:
Return value 1
size of time:32
ker_sec:1508833722
ker_nsec:745536502
nsday_sec:1508833722
nsday_nsec:746151801
源代码:
ssize_t read_function(struct file *file_pointer,char *buffer,size_t count,loff_t *offset)
{
int error_no=0;
struct timespec gets_time;
struct time_check time_s;
if(access_ok(VERIFY_READ,buffer,2*sizeof(struct timespec)))
{
struct timespec cur_time=current_kernel_time();
printk("current_kernel_time:\n%lld %lld\n",(long long)(cur_time.tv_sec),(long long)(cur_time.tv_nsec));
getnstimeofday(&gets_time);
printk("getnstimeofday:\n%lld %lld\n",(long long)(gets_time.tv_sec),(long long)(gets_time.tv_nsec));
time_s.tv_sec_ker=cur_time.tv_sec;
time_s.tv_nsec_ker=cur_time.tv_nsec;
time_s.tv_sec_nsday=gets_time.tv_sec;
time_s.tv_nsec_nsday=gets_time.tv_nsec;
printk("current_kernel_time_copied:\n%lld %lld\n",(long long)(time_s.tv_sec_ker),(long long)(time_s.tv_nsec_ker));
printk("getnstimepfday_copied:\n%lld %lld\n",(long long)(time_s.tv_sec_nsday),(long long)(time_s.tv_nsec_nsday));
if(!copy_to_user(buffer,&time_s,sizeof(time_s)))
{
error_no = sizeof(time_s);
}
else
{
error_no=-EFAULT;
}
}
else
{
error_no=-EFAULT;
}
printk("=== copy number ====%d", error_no);
return error_no;
}