參考資訊:
https://www.aps-web.jp/en/ca-en/21578/#anchor2
User Application可以透過read()、write()傳送資料給驅動程式,但是需要注意的地方是,在Linux Kernel中,如果要存取User Application傳送過來的資料時,必須使用copy_to_user()、copy_from_user(),而不是一般的memcpy()或者直接指標操作,否則會導致驅動程式崩潰,這是因為Linux Kernel和User Application是位於不同保護空間,因此,在存取User Application資料時,必須確保該資料已經被Map且位於記憶體
使用方式:
1. copy_to_user() 2. copy_from_user()
main.c
#include <linux/cdev.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/uaccess.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Steward Fu");
MODULE_DESCRIPTION("Linux Driver");
static int base = 0;
static struct cdev mycdev;
static char mybuf[255] = {0};
static struct class *myclass = NULL;
static int myopen(struct inode *inode, struct file *file)
{
printk("%s\n", __func__);
return 0;
}
static int myclose(struct inode *inode, struct file *file)
{
printk("%s\n", __func__);
return 0;
}
static ssize_t myread(struct file *flip, char __user *buf, size_t len, loff_t *off)
{
int r = 0;
r = copy_to_user(buf, mybuf, strlen(mybuf));
printk("%s, %s\n", __func__, mybuf);
return r;
}
static ssize_t mywrite(struct file *flip, const char __user *buf, size_t len, loff_t *off)
{
int r = 0;
r = copy_from_user(mybuf, buf, len);
printk("%s, %s\n", __func__, mybuf);
return r;
}
static const struct file_operations myfops = {
.owner = THIS_MODULE,
.open = myopen,
.read = myread,
.write = mywrite,
.release = myclose,
};
int ldd_init(void)
{
alloc_chrdev_region(&base, 0, 1, "myfile");
myclass = class_create(THIS_MODULE, "myfile");
device_create(myclass, NULL, base, NULL, "myfile");
cdev_init(&mycdev, &myfops);
cdev_add(&mycdev, base, 1);
return 0;
}
void ldd_exit(void)
{
device_destroy(myclass, base);
cdev_del(&mycdev);
class_destroy(myclass);
unregister_chrdev_region(base, 1);
}
module_init(ldd_init);
module_exit(ldd_exit);
ldd_init: 建立字元驅動程式
myopen: 僅列印字串
mywrite: 儲存並且列印User Application傳送的字串
myread: 複製儲存的字串給User Application並且列印出來
myclose: 僅列印字串
ldd_exit: 刪除字元驅動程式
寫入字串
# echo "test" > /dev/myfile
mywrite, test
P.S. 按下Ctrl+C停止
讀取字串
# cat /dev/myfile
myopen
myread, test
myclose