@ Memory Copy Interfaces from Kernel to User
: copy_to_user()
: copy_from_user()
: put_user()
: get_user()
@ 차이점
: 일반적으로 아래와 같이 사용
-. 4 byte 이하 작은 데이터를 다룰 경우 : put_user, get_user
-. 4 byte 이상 큰 데이터를 다룰 경우 : copy_to_user, copy_from_user
@ 참고사항
: copy_to_user, copy_from_user 함수를 사용하지 않아도
: parameter로 넘어온 buf 포인터를 통해 sprintf 라든지 = 대입이라든지 가능함
: 하지만 user <-> kernel 간 메모리 복사를 안전하게 하려면
: 검증된 방법(인터페이스)를 이용하여 구현하는 것을 권장
@ Example
: copy_to_user()
: copy_from_user()
: put_user()
: get_user()
@ 차이점
: 일반적으로 아래와 같이 사용
-. 4 byte 이하 작은 데이터를 다룰 경우 : put_user, get_user
-. 4 byte 이상 큰 데이터를 다룰 경우 : copy_to_user, copy_from_user
@ 참고사항
: copy_to_user, copy_from_user 함수를 사용하지 않아도
: parameter로 넘어온 buf 포인터를 통해 sprintf 라든지 = 대입이라든지 가능함
: 하지만 user <-> kernel 간 메모리 복사를 안전하게 하려면
: 검증된 방법(인터페이스)를 이용하여 구현하는 것을 권장
@ Example
/*
* @file test_mydrv.c
* @brief Application Program for copy_to_user, copy_from_user
*/
typedef struct
{
int age;
char name[30];
char address[20];
int phone_number;
char depart[20];
} __attribute__ ((packed)) mydrv_data;
int main()
{
mydrv_data data;
int fd = open("/dev/mydrv",O_RDWR);
data.age = 29;
strcpy(data.name, "seungin.cha");
strcpy(data.address, "hwagok-dong");
data.phone_number = 49104714;
strcpy(data.depart, "H&A");
// Send data from user to kernel (and then, Print data by Kernel)
write(fd, &data, sizeof(data));
// Receive data from kernel to user
read(fd, &data, sizeof(mydrv_data));
// Print data by User
printf("\n");
printf("u_age : %d\n", data.age);
printf("u_name : %s\n", data.name);
printf("u_address: %s\n", data.address);
printf("u_phoneno: %d\n", data.phone_number);
printf("u_depart : %s\n", data.depart);
printf("\n");
close(fd);
return 0;
}
/*
* @file mydrv.c
* @brief Module Program for copy_to_user, copy_from_user
*/
typedef struct
{
int age;
char name[30];
char address[20];
int phone_number;
char depart[20];
} __attribute__ ((packed)) mydrv_data;
...
static ssize_t mydrv_write(struct file *filp,const char __user *buf, size_t count, loff_t *f_pos)
{
mydrv_data* k_buf, u_buf;
k_buf = kmalloc(sizeof(mydrv_data), GFP_KERNEL);
if (copy_from_user(k_buf, buf, sizeof(mydrv_data)))
{
return -EFAULT;
}
// copy_from_user 함수를 이용하지 않아도 복사가 가능하나 권장하지 않음
// u_buf = (mydrv_data*) buf;
// k_buf->age = u_buf->age;
// sprintf(k_buf->name, u_buf->name);
// sprintf(k_buf->address, u_buf->address);
// k_buf->phone_number = u_buf->phone_number;
// sprintf(k_buf->depart, u_buf->depart);
printk("\n");
printk("k_age : %d\n", k_buf->age);
printk("k_name : %s\n", k_buf->name);
printk("k_address: %s\n", k_buf->address);
printk("k_phoneno: %d\n", k_buf->phone_number);
printk("k_depart : %s\n", k_buf->depart);
printk("\n");
kfree(k_buf);
return 0;
}
static ssize_t mydrv_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
mydrv_data k_struct;
k_struct.age = 31;
sprintf(&k_struct.name, "seungkil.cha");
sprintf(&k_struct.address, "bueon");
k_struct.phone_number = 26401717;
sprintf(&k_struct.depart, "shinjung");
if (copy_to_user(buf, &k_struct, sizeof(mydrv_data)))
{
return -EFAULT;
}
return 0;
}
No comments:
Post a Comment