#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
MODULE_LICENSE("GPL");
#define MAJOR_NUM 254 //主設(shè)備號(hào)
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*);
//初始化字符設(shè)備驅(qū)動(dòng)的file_operations結(jié)構(gòu)體
struct file_operations globalvar_fops =
{
read: globalvar_read, write: globalvar_write,
};
static int global_var = 0; //"globalvar"設(shè)備的全局變量
static int __init globalvar_init(void)
{
int ret;
//注冊(cè)設(shè)備驅(qū)動(dòng)
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;
//注銷設(shè)備驅(qū)動(dòng)
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從內(nèi)核空間復(fù)制到用戶空間
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)
{
//將用戶空間的數(shù)據(jù)復(fù)制到內(nèi)核空間的global_var
if (copy_from_user(&global_var, buf, sizeof(int)))
{
return - EFAULT;
}
return sizeof(int);
}
module_init(globalvar_init);
module_exit(globalvar_exit);
運(yùn)行:
gcc -D__KERNEL__ -DMODULE -DLINUX -I /usr/local/src/linux2.4/include -c -o globalvar.o globalvar.c
編譯代碼,運(yùn)行:
inmod globalvar.o
加載globalvar模塊,再運(yùn)行:
cat /proc/devices
發(fā)現(xiàn)其中多出了"254 globalvar"一行,如下圖:
接著我們可以運(yùn)行:
mknod /dev/globalvar c 254 0
創(chuàng)建設(shè)備節(jié)點(diǎn),用戶進(jìn)程通過/dev/globalvar這個(gè)路徑就可以訪問到這個(gè)全局變量虛擬設(shè)備了。
我們寫一個(gè)用戶態(tài)的程序globalvartest.c來驗(yàn)證上述設(shè)備:
#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);
//關(guān)閉"/dev/globalvar"
close(fd);
}
else
{
printf("Device open failure\n");
}
}
編譯上述文件:
gcc -o globalvartest.o globalvartest.c
運(yùn)行
./globalvartest.o
可以發(fā)現(xiàn)"globalvar"設(shè)備可以正確的讀寫。 |