測試代碼實作
memdev.h
#ifndef _MEMDEV_H_
#define _MEMDEV_H_
#include
#ifndef MEMDEV_MAJOR
#define MEMDEV_MAJOR 0
#endif
#ifndef MEMDEV_NR_DEVS
#define MEMDEV_NR_DEVS 2
#endif
#ifndef MEMDEV_SIZE
#define MEMDEV_SIZE 4096
#endif
struct mem_dev
{
char *data;
unsigned long size;
};
#define MEMDEV_IOC_MAGIC 'k'
#define MEMDEV_IOCPRINT _IO(MEMDEV_IOC_MAGIC,0)
#define MEMDEV_IOCGETDATA _IOR(MEMDEV_IOC_MAGIC,1,int)
#define MEMDEV_IOC_MAXNR 3
#endif
memdev.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "memdev.h"
static int mem_major = MEMDEV_MAJOR;
module_param(mem_major,int,S_IRUGO);
struct mem_dev *mem_devp;
struct cdev cdev;
int mem_open(struct inode *inode,struct file *filp)
{
struct mem_dev *dev;
int num = MINOR(inode->i_rdev);
if(num >= MEMDEV_NR_DEVS)
return -ENODEV;
dev = &mem_devp[num];
filp->private_data = dev;
return ;
}
int mem_release(struct inode *inode,struct file *filp)
{
return ;
}
long memdev_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
{
int err = ;
int ret = ;
int ioarg = ;
printk("kernel cmd is : %ld\n",cmd);
switch(cmd)
{
case MEMDEV_IOCPRINT:
printk("CMD MEMDEV_IOCPRINT DONE\n\n");
break;
case MEMDEV_IOCGETDATA:
ioarg = ;
if(copy_to_user((int *)arg,&ioarg,sizeof(int)))
return -EFAULT;
break;
default:
return -EINVAL;
}
return ret;
}
static const struct file_operations mem_fops =
{
.owner = THIS_MODULE,
.open = mem_open,
.release = mem_release,
.unlocked_ioctl = memdev_ioctl,
};
static int memdev_init(void)
{
int result;
int i;
dev_t devno = MKDEV(mem_major,);
if (mem_major)
{
result = register_chrdev_region(devno,,"memdev");
printk("first mem_major is : %ld\n",mem_major);
}
else
{
result = alloc_chrdev_region(&devno,,,"memdev");
mem_major = MAJOR(devno);
printk("second mem_major is : %ld\n",mem_major);
}
if(result < )
return result;
cdev_init(&cdev,&mem_fops);
cdev.owner = THIS_MODULE;
cdev.ops = &mem_fops;
cdev_add(&cdev,MKDEV(mem_major,),MEMDEV_NR_DEVS);
mem_devp = kmalloc(MEMDEV_NR_DEVS * sizeof(struct mem_dev),GFP_KERNEL);
if(!mem_devp)
{
result = -ENOMEM;
goto fail_malloc;
}
memset(mem_devp,,sizeof(struct mem_dev));
for(i=;i
{
mem_devp[i].size = MEMDEV_SIZE;
mem_devp[i].data = kmalloc(MEMDEV_SIZE,GFP_KERNEL);
memset(mem_devp[i].data,,MEMDEV_SIZE);
}
return ;
fail_malloc:
unregister_chrdev_region(devno,);
return result;
}
static void memdev_exit(void)
{
cdev_del(&cdev);
kfree(mem_devp);
unregister_chrdev_region(MKDEV(mem_major,),);
}
MODULE_LICENSE("GPL");
module_init(memdev_init);
module_exit(memdev_exit);
Makefile
obj-m += memdev.o
CURRENT_PATH := $(shell pwd)
LINUX_KERNEL := $(shell uname -r)
LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL)
all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
app-ioctl.c
#include
#include
#include
#include
#include "memdev.h"
int main(void)
{
int fd = ;
int cmd;
int arg = ;
char Buf[];
fd = open("/dev/memdev0",O_RDWR);
if(fd < )
{
printf("Open Dev Mem Erro\n");
return -;
}
printf("call memdev_iocprint\n");
cmd = MEMDEV_IOCPRINT;
printf("userspace cmd is : %ld\n",cmd);
if(ioctl(fd,cmd,&arg) < )
{
printf("call cmd MEMDEV_IOCPRINT fail\n");
return -;
}
printf("call MEMDEV_IOCGETDATA\n");
cmd = MEMDEV_IOCGETDATA;
if(ioctl(fd,cmd,&arg) < )
{
printf("call cmd MEMDEV_IOCGETDATA fail\n");
return -;
}
printf("in user space MEMDEV_IOCGETDATA get data is %d\n\n",arg);
close(fd);
return ;
}
編譯memdev,對應的裝置驅動
make
insmod memdev.ko
在dmesg中會有輸出結果init,在/proc/devices中生成對應的裝置驅動号249
建立裝置節點
cat /proc/devices中生成的memdev節點編号249
mknod /dev/memdev0 c 249 0建立裝置節點,并将對應的裝置節點與裝置驅動号進行綁定。當打開該裝置節點進行後續操作時,将會由裝置驅動檔案進行具體實作
編譯app ioctl測試檔案
gcc -o app-ioctl app-ioctl.c
./app-ioctl
正常執行結果會顯示,dmesg也會顯示核心結果
linux 進階字元裝置驅動 ioctl操作介紹 例程分析實作【轉】
轉自:http://my.oschina.net/u/274829/blog/285014 1,ioctl介紹 ioctl控制裝置讀寫資料以及關閉等. 使用者空間函數原型:int ioctl(int f ...
linux裝置驅動第三篇:如何實作一個簡單的字元裝置驅動
在linux裝置驅動第一篇:裝置驅動程式簡介中簡單介紹了字元驅動,本篇簡單介紹如何寫一個簡單的字元裝置驅動.本篇借鑒LDD中的源碼,實作一個與硬體裝置無關的字元裝置驅動,僅僅操作從核心中配置設定的一些記憶體 ...
linux裝置驅動第三篇:如何寫一個簡單的字元裝置驅動?
在linux裝置驅動第一篇:裝置驅動程式簡介中簡單介紹了字元驅動,本篇簡單介紹如何寫一個簡單的字元裝置驅動.本篇借鑒LDD中的源碼,實作一個與硬體裝置無關的字元裝置驅動,僅僅操作從核心中配置設定的一些記憶體 ...
linux裝置驅動第三篇:寫一個簡單的字元裝置驅動
在linux裝置驅動第一篇:裝置驅動程式簡介中簡單介紹了字元驅動,本篇簡單介紹如何寫一個簡單的字元裝置驅動.本篇借鑒LDD中的源碼,實作一個與硬體裝置無關的字元裝置驅動,僅僅操作從核心中分 ...
Linux核心分析(五)----字元裝置驅動實作
原文:Linux核心分析(五)----字元裝置驅動實作 Linux核心分析(五) 昨天我們對linux核心的子系統進行簡單的認識,今天我們正式進入驅動的開發,我們今後的學習為了避免大家沒有硬體的缺陷, ...
Linux字元裝置驅動架構
字元裝置是Linux三大裝置之一(另外兩種是塊裝置,網絡裝置),字元裝置就是位元組流形式通訊的I/O裝置,絕大部分裝置都是字元裝置,常見的字元裝置包括滑鼠.鍵盤.顯示器.序列槽等等,當我們執行ls -l ...
深入了解Linux字元裝置驅動
文章從上層應用通路字元裝置驅動開始,一步步地深入分析Linux字元裝置的軟體層次.組成架構和互動.如何編寫驅動.裝置檔案的建立和mdev原理,對Linux字元裝置驅動有全面的講解.本文整合之前發表的& ...
Linux驅動設計——字元裝置驅動(一)
Linux字元設别驅動結構 cdev結構體 struct cdev { struct kobject kobj; struct module *owner; const struct file_ope ...
字元裝置驅動、平台裝置驅動、裝置驅動模型、sysfs的比較和關聯
轉載自:http://www.kancloud.cn/yueqian_scut/emlinux/106829 學習Linux裝置驅動開發的過程中自然會遇到字元裝置驅動.平台裝置驅動.裝置驅動模型和sy ...
随機推薦
MySQL索引的Index method中btree和hash的優缺點
MySQL索引的Index method中btree和hash的差別 在MySQL中,大多數索引(如 PRIMARY KEY,UNIQUE,INDEX和FULLTEXT)都是在BTREE中存儲,但使用 ...
開始研究tigase和android用戶端的實作
2015.7.5. 昨晚總算把tigaase7.0的開發環境搭起來了.稍微看了下代碼結構. 主要是auth,db,compnent,cluster,server,xmpp,這幾塊,準備先發點時間看看開 ...
關于WPF中RichTextBox失去焦點後如何保持高亮顯示所選擇的内容
其實很簡單,隻要将容器控件中的附加屬性FocusManager.IsFocusScope設為True就可以了 下面是個簡單的用例:
format格式化和函數
{[name][:][[fill]align][sign][#][0][width][,][.precision][type]}用{ }包裹name命名傳遞給format以命名=值 寫法, 非字典映射 ...
SUSE Enterprise Server 12 SP3 64 設定防火牆開放8080端口
SUSE Enterprise Server 12 SP3 64 設定防火牆開放8080端口 第一種方式: 1.sudo chmod a+w /etc/sysconfig/SuSEfirewall2 ...