#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
MODULE_LICENSE("GPL");
#define MAJOR_NUM 254 //主設備號
static ssize_t globalvar_read(struct file *, char *, size_t, loff_t*);
static ssize_t globalvar_write(struct file *, const char *, size_t, loff_t*);
//初始化字符設備驅動的file_operations結構體
struct file_operations globalvar_fops =
{
read: globalvar_read, write: globalvar_write,
};
static int global_var = 0; //"globalvar"設備的全局變量
static int __init globalvar_init(void)
{
int ret;
//注冊設備驅動
ret = register_chrdev(MAJOR_NUM, "globalvar", &globalvar_fops);
if (ret)
{
printk("globalvar register failure");
}
else
{
printk("globalvar register success");
}
return ret;
}
static void __exit globalvar_exit(void)
{
int ret;
//注銷設備驅動
ret = unregister_chrdev(MAJOR_NUM, "globalvar");
if (ret)
{
printk("globalvar unregister failure");
}
else
{
printk("globalvar unregister success");
}
}
static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t *off)
{
//將global_var從內核空間復制到用戶空間
if (copy_to_user(buf, &global_var, sizeof(int)))
{
return - EFAULT;
}
return sizeof(int);
}
static ssize_t globalvar_write(struct file *filp, const char *buf, size_t len, loff_t *off)
{
//將用戶空間的數據復制到內核空間的global_var
if (copy_from_user(&global_var, buf, sizeof(int)))
{
return - EFAULT;
}
return sizeof(int);
}
module_init(globalvar_init);
module_exit(globalvar_exit);
運行:
gcc -D__KERNEL__ -DMODULE -DLINUX -I /usr/local/src/linux2.4/include -c -o globalvar.o globalvar.c
編譯代碼,運行:
inmod globalvar.o
加載globalvar模塊,再運行:
cat /proc/devices
發現其中多出了"254 globalvar"一行,如下圖:
接著我們可以運行:
mknod /dev/globalvar c 254 0
創建設備節點,用戶進程通過/dev/globalvar這個路徑就可以訪問到這個全局變量虛擬設備了。
我們寫一個用戶態的程序globalvartest.c來驗證上述設備:
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
main()
{
int fd, num;
//打開"/dev/globalvar"
fd = open("/dev/globalvar", O_RDWR, S_IRUSR | S_IWUSR);
if (fd != -1 )
{
//初次讀globalvar
read(fd, &num, sizeof(int));
printf("The globalvar is %d\n", num);
//寫globalvar
printf("Please input the num written to globalvar\n");
scanf("%d", &num);
write(fd, &num, sizeof(int));
//再次讀globalvar
read(fd, &num, sizeof(int));
printf("The globalvar is %d\n", num);
//關閉"/dev/globalvar"
close(fd);
}
else
{
printf("Device open failure\n");
}
}
編譯上述文件:
gcc -o globalvartest.o globalvartest.c
運行
./globalvartest.o
可以發現"globalvar"設備可以正確的讀寫。 |