看到驅動程序的實例就轉了,謝謝作者pzhsunxu的分享!
轉載地址:http://blog.csdn.net/pzhsunxu/article/details/7169800
通過UBUNTU10.10測試該驅動程序的,系統內核爲linux-2.6.35-22(可使用uname -r 命令來查看當前內核的版本號)
下載安裝LINUX內核,需要下載和本機一樣版本的內核源碼。
1,安裝編譯內核所需要的軟件並編譯內核(注:我在root下執行,如果其中有問題,換到普通用戶下用sudo試試)
apt-get install build-essential autoconf automake cvs subversion kernel-package libncurses5-dev
用 apt-cache search linux-source 可以知道需要下載什麼版本的內核源碼,我的是2.6.35
下載安裝內核源碼 apt-get install linux-source-2.6.35 下載完成後 cd /us/src 可以看見linux-source-2.6.35.tar.bz2,現在解壓 cd linux-source-2.6.35 cp /boot/config-`uname -r` ./.config #拷貝目前系統的配置文件 make menuconfig 終端會彈出一個配置界面 最後有兩項:load a kernel configuration... (.config) 接下來我們開始編譯 make #這步需要比較長時間 make bzImage 執行結束後,可以看到在當前目錄下生成了一個新的文件: vmlinux,
其屬性爲-rwxr-xr-x。
|
2,爲系統的include創建鏈接文件(這步好像不是必需的,默認就是這樣的)
cd /usr/include |
二,驅動程序測試代碼
在/root下建一個目錄,如:
cd
/root
mkdir firstdriver
touch memdev.c #建立文件驅動程序文件
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include
<linux/slab.h>
#include "memdev.h"
static 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
0;
}
int mem_release(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t mem_read(struct file *filp, char __user *buf, size_t
size, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count =
size;
int ret = 0;
struct mem_dev *dev =
filp->private_data;
if (p >=
MEMDEV_SIZE)
return
0;
if (count >
MEMDEV_SIZE - p)
count
= MEMDEV_SIZE - p;
if (copy_to_user(buf,
(void*)(dev->data + p), count))
{
ret
= - EFAULT;
}
else
{
*ppos
+= count;
ret
= count;
printk(KERN_INFO
"read %d bytes(s) from %d\n", count, p);
}
return ret;
}
static ssize_t mem_write(struct file *filp, const char __user *buf,
size_t size, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count =
size;
int ret = 0;
struct mem_dev *dev =
filp->private_data;
if (p >=
MEMDEV_SIZE)
return
0;
if (count >
MEMDEV_SIZE - p)
count
= MEMDEV_SIZE - p;
if
(copy_from_user(dev->data + p, buf, count))
ret
= - EFAULT;
else
{
*ppos
+= count;
ret
= count;
printk(KERN_INFO
"written %d bytes(s) from %d\n", count, p);
}
return ret;
}
static loff_t mem_llseek(struct file *filp, loff_t offset, int
whence)
{
loff_t
newpos;
switch(whence)
{
case
0:
newpos
= offset;
break;
case
1:
newpos
= filp->f_pos + offset;
break;
case
2:
newpos
= MEMDEV_SIZE -1 + offset;
break;