【新手请看】Linux2.6内核模块和驱动程序框架
时间:2008-10-05
来源:互联网
virtual_char.c:内核模块源代码
test_virtual_char.c:测试源代码
作者: hanchao3c 发布时间: 2008-10-05
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/delay.h>
#define VIRTUAL_CHAR_MAJOR 240
#define VIRTUAL_CHAR_DEVICE_NAME "VirtualCharDevice"
static int virtual_char_open(struct inode *inode, struct file *file)
{
printk(KERN_EMERG"+++++++++++++++++++++\n");
printk(KERN_EMERG"virtual_char:device open\n");
printk(KERN_EMERG"pid=%d,comm=%s\n",current->pid,current->comm);
printk("device <%d,%d>\n",MAJOR(inode->i_rdev),MINOR(inode->i_rdev));
(file->private_data) = (void *)0x76543210;
return 0;
}
static int virtual_char_close(struct inode *inode, struct file *file)
{
printk(KERN_EMERG"virtual_char:device close\n");
printk(KERN_EMERG"----------------------\n");
return 0;
}
static ssize_t virtual_char_read(struct file *file, char *buf, size_t count, loff_t *offset)
{
printk(KERN_EMERG"virtual_char:device read=%d\n",count);
if(count >= sizeof(unsigned int)){
if(copy_to_user((void __user *)buf,(void *)(&file->private_data),sizeof(unsigned int)))
return -EFAULT;
}
return count;
}
static ssize_t virtual_char_write(struct file *file, const char *buf, size_t count, loff_t *offset)
{
printk(KERN_EMERG"virtual_char:device write=%d\n",count);
return count;
}
static loff_t virtual_char_llseek(struct file *file,loff_t offset,int whence)
{
printk(KERN_EMERG"virtual_char:device llseek: offset=%x whence=%x\n",(unsigned int)offset,whence);
return 0;
}
static int virtual_char_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
char argk[4];
argk[0] = 0;
argk[1] = 1;
argk[2] = 2;
argk[3] = 3;
printk(KERN_EMERG"virtual_char:device ioctl=%x\n",cmd);
switch(cmd)
{
case 0:
printk(KERN_EMERG"ctl NO.0\n");
if(copy_from_user(argk,(void __user *)arg,4))
return -EFAULT;
printk("arg=%x,%x,%x,%x\n",argk[0],argk[1],argk[2],argk[3]);
break;
case 1:
printk(KERN_EMERG"ctl NO.1\n");
if(copy_to_user((void __user *)arg,argk,4))
return -EFAULT;
break;
default:
break;
}
return 0;
}
static struct file_operations virtual_char_fops = {
.llseek = virtual_char_llseek,
.read = virtual_char_read,
.write = virtual_char_write,
.ioctl = virtual_char_ioctl,
.open = virtual_char_open,
.release = virtual_char_close,
};
static int virtual_char_init(void)
{
int res;
printk(KERN_EMERG"virtual_char register\n");
res = register_chrdev(VIRTUAL_CHAR_MAJOR, VIRTUAL_CHAR_DEVICE_NAME, &virtual_char_fops);
if (res < 0) {
printk(KERN_EMERG"virtual_char register fails\n");
return res;
}
// set_current_state(TASK_INTERRUPTIBLE);
// schedule_timeout(4000);
// mdelay(4000);
return 0;
}
static void virtual_char_cleanup(void)
{
printk(KERN_EMERG"virtual_char unregister\n");
unregister_chrdev(VIRTUAL_CHAR_MAJOR, VIRTUAL_CHAR_DEVICE_NAME);
return;
}
module_init(virtual_char_init);
module_exit(virtual_char_cleanup);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("HanChao");
//gcc -O2 -D__KERNEL__ -DMODULE -I/usr/include/ -c virtual_char.c -o m.ko
作者: hanchao3c 发布时间: 2008-10-05
#KDIR:=/lib/modules/2.6.18.2-34-default/build
KDIR:=/usr/src/linux
PWD:=$(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.o *.mod.o *.ko *.mod.c .*.o.cmd .*.mo.o.cmd .*.ko.cmd .tmp_versions
作者: hanchao3c 发布时间: 2008-10-05
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#define DEF_FILE_NAME "/dev/virtualchar"
int main(int argc,char* argv[])
{
int fd,size,i;
char readbuf[8];
char writebuf[8] = "writebuf";
char ioarg[4];
char* dev_file;
if(1 == argc){
dev_file = DEF_FILE_NAME;
}else{
dev_file = argv[1];
}
printf("<<<< testfile name=%s >>>>\n",dev_file);
printf("pid=%d ppid=%d\n",getpid(),getppid());
/* write */
printf("=====write test=====\n");
fd=open(dev_file,O_WRONLY);
size = write(fd,writebuf,sizeof(writebuf));
close(fd);
printf("write size=%d\n",size);
/* read */
printf("=====read test=====\n");
fd=open(dev_file,O_RDONLY);
size=read(fd,readbuf,sizeof(readbuf));
close(fd);
printf("read size=%d\n",size);
for(i=0;i<size;i++)
printf("readbuf[%d]=%x\n",i,(unsigned char)readbuf[i]);
close(fd);
/* ioctl */
printf("=====ioctl test=====\n");
fd=open(dev_file,O_RDWR);
ioarg[0] = 0xf0;
ioarg[1] = 0xf1;
ioarg[2] = 0xf2;
ioarg[3] = 0xf3;
printf("ioctl test 0\n");
ioctl(fd,0,ioarg);
printf("ioctl test 1\n");
ioctl(fd,1,ioarg);
printf("arg=%x,%x,%x,%x\n",ioarg[0],ioarg[1],ioarg[2],ioarg[3]);
close(fd);
return 0;
}
作者: hanchao3c 发布时间: 2008-10-05
make -C /usr/src/linux M=/home/hanchao/module modules
make[1]: Entering directory `/usr/src/linux-2.6.18.2-34'
CC [M] /home/hanchao/module/virtual_char.o
Building modules, stage 2.
MODPOST
CC /home/hanchao/module/virtual_char.mod.o
LD [M] /home/hanchao/module/virtual_char.ko
make[1]: Leaving directory `/usr/src/linux-2.6.18.2-34'
# mknod /dev/VirtualCharDevice c 240 0
# ls /dev/VirtualCharDevice -l
crw-r--r-- 1 root root 240, 0 04-25 06:46 /dev/VirtualCharDevice
# insmod virtual_char.ko
# ./test /dev/VirtualCharDevice
<<<< testfile name:/dev/VirtualCharDevice >>>>
pid:4671 ppid:4108
=====write test=====
write size:8
=====read test=====
read size:8
readbuf[0]:10
readbuf[1]:32
readbuf[2]:54
readbuf[3]:76
readbuf[4]:c9
readbuf[5]:87
readbuf[6]:4
readbuf[7]:8
=====ioctl test=====
ioctl test 0
ioctl test 1
arg:0,1,2,3
作者: hanchao3c 发布时间: 2008-10-05

ioarg[1] = 0xf1;
ioarg[2] = 0xf2;
ioarg[3] = 0xf3;
等语句为什么要用16进制来输出呢,是必须要这样做吗?
2.还有我认为语句

ioarg[1] = 0xf1;
ioarg[2] = 0xf2;
ioarg[3] = 0xf3;
但是结果为什么会输出0,1,2,3呢?
作者: txf1949 发布时间: 2008-10-06
作者: hanchao3c 发布时间: 2008-10-06
作者: hanchao3c 发布时间: 2008-10-06
作者: tempname 发布时间: 2008-10-15
作者: tempname
请问你这里的Makefile是内核代码中的Makefile还是自己写的makefile。
|
作者: hanchao3c 发布时间: 2008-10-20
作者: goldenfire 发布时间: 2008-11-14
作者: neubuffalo 发布时间: 2008-11-15
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28