Linux内核---54.一个非常简单的字符设备
2016-07-09 10:40
295 查看
1. ldd3上的scull太难了,俺一个新手怎么能看得懂呢?没办法,自己写一个非常非常简单的字符设备。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/cdev.h>
dev_t scull_dev_num;
struct cdev* p_scull_dev;
static int scull_open(struct inode* node, struct
file *filp)
{
printk(KERN_ALERT "scull open!\n");
return 0;
}
static ssize_t scull_read(struct file* filp, char __user *buf, size_t
count, loff_t *f_pos)
{
printk(KERN_ALERT "scull read!\n");
return 0;
}
static ssize_t scull_write(struct file* filp, const char
__user *buf, size_t count, loff_t *f_pos)
{
printk(KERN_ALERT "scull write!\n");
return 0;
}
static int scull_release(struct inode *node, struct
file* filp)
{
printk(KERN_ALERT "scull release!\n");
return 0;
}
static const struct file_operations scull_fops =
{
.owner = THIS_MODULE,
.open = scull_open,
.read = scull_read,
.write = scull_write,
.release = scull_release,
};
static int __init scull_init(void)
{
int ret;
printk(KERN_ALERT "in scull driver\n");
//动态分配一个设备号,从0开始分配一个从设备号
ret = alloc_chrdev_region(&scull_dev_num, 0, 1, "scull");
if(ret < 0)
{
printk(KERN_ALERT "alloc_chrdev_region error!\n");
}
//字符设备注册
p_scull_dev = cdev_alloc();
p_scull_dev->owner = THIS_MODULE;
p_scull_dev->ops = &scull_fops;
cdev_add(p_scull_dev, scull_dev_num, 1);
return 0;
}
static void __exit scull_exit(void)
{
printk(KERN_ALERT "goodbye scull dirver\n");
unregister_chrdev_region(scull_dev_num, 1);
cdev_del(p_scull_dev);
return ;
}
MODULE_LICENSE("GPL");
module_init(scull_init);
module_exit(scull_exit);
2. Makefile
ARCH=x86
ifeq ($(ARCH), x86)
CROSS_COMPILE=
KDIR = /lib/modules/$(shell
uname -r)/build
else
CROSS_COMPILE= /opt/EmbedSky/4.3.3/bin/arm-none-linux-gnueabi-
KDIR =/root/kernel/linux-2.6.30.4
endif
PWD = $(shell pwd)
obj-m := scull.o
all:
make -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -f *.ko *.o *.mod.o *.mod.c .*.cmd *.symvers *.order
3. test程序
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main ( int argc, char *argv[] )
{
int fd;
fd = open("/dev/scull", O_RDWR);
if(fd < 0)
{
perror("open");
}
return EXIT_SUCCESS;
}
4. 测试
4.1 创建设备文件
root@ubuntu:~/driver/2scull# cat /proc/devices | grep "scull"
250 scull
root@ubuntu:~/driver/2scull# mknod /dev/scull c 250 0
//动态分配的主设备号250
root@ubuntu:~/driver/2scull/test# ll /dev/scull
crw-r--r-- 1 root root 250, 0 2012-08-28 15:19 /dev/scull
4.2 运行测试程序
root@ubuntu:~/driver/2scull/test# ./scull_test
root@ubuntu:~/driver# dmesg
[ 2110.894651] in scull driver
[ 2114.160516] scull open!
[ 2114.160679] scull release!
2scull.zip
(下载后改名为: 2scull.tar.gz)
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/cdev.h>
dev_t scull_dev_num;
struct cdev* p_scull_dev;
static int scull_open(struct inode* node, struct
file *filp)
{
printk(KERN_ALERT "scull open!\n");
return 0;
}
static ssize_t scull_read(struct file* filp, char __user *buf, size_t
count, loff_t *f_pos)
{
printk(KERN_ALERT "scull read!\n");
return 0;
}
static ssize_t scull_write(struct file* filp, const char
__user *buf, size_t count, loff_t *f_pos)
{
printk(KERN_ALERT "scull write!\n");
return 0;
}
static int scull_release(struct inode *node, struct
file* filp)
{
printk(KERN_ALERT "scull release!\n");
return 0;
}
static const struct file_operations scull_fops =
{
.owner = THIS_MODULE,
.open = scull_open,
.read = scull_read,
.write = scull_write,
.release = scull_release,
};
static int __init scull_init(void)
{
int ret;
printk(KERN_ALERT "in scull driver\n");
//动态分配一个设备号,从0开始分配一个从设备号
ret = alloc_chrdev_region(&scull_dev_num, 0, 1, "scull");
if(ret < 0)
{
printk(KERN_ALERT "alloc_chrdev_region error!\n");
}
//字符设备注册
p_scull_dev = cdev_alloc();
p_scull_dev->owner = THIS_MODULE;
p_scull_dev->ops = &scull_fops;
cdev_add(p_scull_dev, scull_dev_num, 1);
return 0;
}
static void __exit scull_exit(void)
{
printk(KERN_ALERT "goodbye scull dirver\n");
unregister_chrdev_region(scull_dev_num, 1);
cdev_del(p_scull_dev);
return ;
}
MODULE_LICENSE("GPL");
module_init(scull_init);
module_exit(scull_exit);
2. Makefile
ARCH=x86
ifeq ($(ARCH), x86)
CROSS_COMPILE=
KDIR = /lib/modules/$(shell
uname -r)/build
else
CROSS_COMPILE= /opt/EmbedSky/4.3.3/bin/arm-none-linux-gnueabi-
KDIR =/root/kernel/linux-2.6.30.4
endif
PWD = $(shell pwd)
obj-m := scull.o
all:
make -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -f *.ko *.o *.mod.o *.mod.c .*.cmd *.symvers *.order
3. test程序
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main ( int argc, char *argv[] )
{
int fd;
fd = open("/dev/scull", O_RDWR);
if(fd < 0)
{
perror("open");
}
return EXIT_SUCCESS;
}
4. 测试
4.1 创建设备文件
root@ubuntu:~/driver/2scull# cat /proc/devices | grep "scull"
250 scull
root@ubuntu:~/driver/2scull# mknod /dev/scull c 250 0
//动态分配的主设备号250
root@ubuntu:~/driver/2scull/test# ll /dev/scull
crw-r--r-- 1 root root 250, 0 2012-08-28 15:19 /dev/scull
4.2 运行测试程序
root@ubuntu:~/driver/2scull/test# ./scull_test
root@ubuntu:~/driver# dmesg
[ 2110.894651] in scull driver
[ 2114.160516] scull open!
[ 2114.160679] scull release!
2scull.zip
(下载后改名为: 2scull.tar.gz)
相关文章推荐
- Linux内核---53.安装kernel API的man手册
- Linux内核---52.ioremap过程
- Linux内核---51.驱动程序的hello world
- Linux内核---50.各个平台下内核模块的编译
- Linux下mysql基本操作
- linux开发---2.汇编语言arm-linux下的打印
- Linux系统中查看日志的常用命令
- Redhat使用CentOS的yum
- Linux内核---49.i2s驱动分析1测试
- Linux内核---48.spi驱动修改
- Linux内核---47.关于clk_get与clk_enable
- Linux内核---46.关于mem_map
- Linux内核---45.关于initcall
- Linux内核---44.关于中断号与中断引脚
- Linux内核---43.文件系统的挂载
- Linux内核---42.arm 内存初始化2
- [CentOS7]安装mysql遇到的问题
- Linux内核---41.arm 内存初始化
- Linux内核---40.模块加载过程分析
- Linux内核---39.ELF 结构分析