LINUX设备驱动

Linux设备驱动代码一枚,可用于练习各种漏洞利用。

一、设备驱动

/* demo.c */

#include <linux/cdev.h>

#include <linux/device.h>

#include <asm/uaccess.h>

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

MODULE_LICENSE("Dual BSD/GPL");

#define DEMO_MAJOR      255

#define DEMO_MINOR      0

#define DEMO_COUNT      1

dev_t dev = 0;

u32 demo_major = 0;

u32 demo_minor = 0;

struct cdev demo_cdev;

struct class *dev_class = NULL;

struct device *dev_device = NULL;

int demo_open(struct inode* inode, struct file *filp) {

printk("enter demo_open()\n");

return 0;

}

ssize_t demo_read(struct file *filp, char __user *buf, size_t count, loff_t *offset) {

char s[10] = {0};

printk("enter demo_read()\n");

/* ADD CODE HERE */

copy_from_user(s, buf, sizeof(s)-1);

printk("read from userspace = %s \n", s);

return 0;

}

ssize_t demo_write(struct file *filp, const char __user *buf, size_t count, loff_t *offset) {

printk("enter demo_write()\n");

return 0;

}

/*

int demo_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data)

{

printk("enter demo_ioctl()\n");

return 0;

}

*/

int demo_release(struct inode *inode, struct file *filp) {

printk("enter demo_release()\n");

return 0;

}

struct file_operations demo_fops = {

.owner = THIS_MODULE,

.open = demo_open,

.read = demo_read,

.write = demo_write,

/*.ioctl = demo_ioctl,*/

.release = demo_release,

};

int __init demo_init(void) {

int ret = 0;

printk("enter demo_init()\n");

if(demo_major) {

dev = MKDEV(DEMO_MAJOR, DEMO_MINOR);

ret = register_chrdev_region(dev, DEMO_COUNT, "demo_demo");

} else {

ret = alloc_chrdev_region(&dev, demo_minor, DEMO_COUNT, "demo_demo02");

}

if(ret < 0) {

printk("register_chrdev_region failed!\n");

goto fail_register_chrdev;

}

demo_major = MAJOR(dev);

printk("demo_major = %d\n", demo_major);

cdev_init(&demo_cdev, &demo_fops);

ret = cdev_add(&demo_cdev, dev, DEMO_COUNT);

if(ret < 0) {

printk("cdev_add failed!\n");

goto fail_cdev_add;

}

dev_class = class_create(THIS_MODULE, "demo_class");

if(IS_ERR(dev_class)) {

printk("class_create failed!\n");

ret = PTR_ERR("dev_class");

goto fail_class_create;

}

dev_device = device_create(dev_class, NULL, dev, NULL, "demo%d", demo_minor);

if(IS_ERR(dev_device)) {

printk("device_create failed!\n");

ret = PTR_ERR(dev_device);

goto fail_device_create;

}

return 0;

fail_device_create:

class_destroy(dev_class);

fail_class_create:

cdev_del(&demo_cdev);

fail_cdev_add:

unregister_chrdev_region(dev, DEMO_COUNT);

fail_register_chrdev:

return ret;

}

void __exit demo_exit(void) {

printk("enter demo_exit()\n");

device_destroy(dev_class, dev);

class_destroy(dev_class);

cdev_del(&demo_cdev);

unregister_chrdev_region(dev, DEMO_COUNT);

}

module_init(demo_init);

module_exit(demo_exit);

二、Makefile 文件

/* Makefile */

ifneq ($(KERNELRELEASE),)

obj-m := demo.o

else

KERNELDIR ?= /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

default:

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

endif

clean:

rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions modules.order Module.symvers

三、驱动安装脚本

/* setup.sh */

rmmod demo

insmod ./demo.ko

chmod 666 /dev/demo0

四、简单测试

/* client.c */

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <fcntl.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/ioctl.h>

int

main(int arg, char **argv) {

char *s = (char*)malloc(20);

memcpy(s, "hello driver.", 10);

int fd = -1;

if (-1 == (fd = open("/dev/demo0", O_RDONLY))) {

perror("open");

return (-1);

}

read(fd, s, 0, 0);

//system("/bin/sh");

return (0);

}

五、测试结果

kiiim@ubuntu :~/__demo_driver$ ./client
kiiim@ubuntu :~/__demo_driver$ dmesg

……

[ 4405.506553] enter demo_init()

[ 4405.506558] demo_major = 247

[ 4408.702358] enter demo_open()

[ 4408.702365] enter demo_read()

[ 4408.702366] read from userspace = hello dri

[ 4408.702527] enter demo_release()

kiiim@ubuntu :~/__demo_driver$

时间: 2024-12-06 13:35:26

LINUX设备驱动的相关文章

linux设备驱动第五篇:驱动中的并发与竟态

综述 在上一篇介绍了linux驱动的调试方法,这一篇介绍一下在驱动编程中会遇到的并发和竟态以及如何处理并发和竞争. 首先什么是并发与竟态呢?并发(concurrency)指的是多个执行单元同时.并行被执行.而并发的执行单元对共享资源(硬件资源和软件上的全局.静态变量)的访问则容易导致竞态(race conditions).可能导致并发和竟态的情况有: SMP(Symmetric Multi-Processing),对称多处理结构.SMP是一种紧耦合.共享存储的系统模型,它的特点是多个CPU使用共

Linux设备驱动中的阻塞和非阻塞I/O

[基本概念] 1.阻塞 阻塞操作是指在执行设备操作时,托不能获得资源,则挂起进程直到满足操作所需的条件后再进行操作.被挂起的进程进入休眠状态(不占用cpu资源),从调度器的运行队列转移到等待队列,直到条件满足. 2.非阻塞 非阻塞操作是指在进行设备操作是,若操作条件不满足并不会挂起,而是直接返回或重新查询(一直占用CPU资源)直到操作条件满足为止. 当用户空间的应用程序调用read(),write()等方法时,若设备的资源不能被获取,而用户又希望以阻塞的方式来访问设备,驱动程序应当在设备驱动层的

Linux设备驱动开发 - 平台设备驱动

Linux2.6的内核中引入了一种新的设备驱动模型-平台(platform)设备驱动,平台设备驱动分为平台设备(platform_device)和平台驱动(platform_driver),平台设备的引入使得Linux设备驱动更加便于移植. 一.平台设备平台设备结构体: 1 struct platform_device { 2 const char * name; /* 设备名 */ 3 int id; 4 struct device dev; /* 设备结构体 */ 5 u32 num_res

linux设备驱动第三篇:写一个简单的字符设备驱动

在linux设备驱动第一篇:设备驱动程序简介中简单介绍了字符驱动,本篇简单介绍如何写一个简单的字符设备驱动.本篇借鉴LDD中的源码,实现一个与硬件设备无关的字符设备驱动,仅仅操作从内核中分配的一些内存. 下面就开始学习如何写一个简单的字符设备驱动.首先我们来分解一下字符设备驱动都有那些结构或者方法组成,也就是说实现一个可以使用的字符设备驱动我们必须做些什么工作. 1.主设备号和次设备号 对于字符设备的访问是通过文件系统中的设备名称进行的.他们通常位于/dev目录下.如下: [plain] vie

Linux设备驱动开发学习(1):前言

虽然网络上已经有很多Linux设备驱动开发学习的文章和博客,更是有很多经典的Linux设备驱动开 发的书籍,写这些博文似乎意义不大,但把自己的学习过程.学习心得记录下来,一方面有着强化巩固的 意义,另一方面也是把所学知识转化为自己所得的必要途径之一,这是我写这些的博客的原始动力.

linux设备驱动中的并发控制

并发指的是多个执行单元同时.并行被执行,而并发的执行单元对共享资源的访问则很容易导致竞态 linux内核中主要竞态1.多对称处理器的多个CPU  2.单CPU内进程与抢占它的进程 3.中断(硬中断.软中断.Tasklet.下半部)与进程之间访问共享内存资源的代码区称为“临界区”,临界区需要被以某种互斥机制加以保护,中断屏蔽.原子操作.自旋锁和信号量等是linux设备驱动中可采用的互斥途径. 这几个互斥的介绍: 1.中断屏蔽,这个主要用于单CPU,中断屏蔽将使得中断和进程之间的并发不再发生.使用方

深入浅出~Linux设备驱动中的阻塞和非阻塞I/O

今天意外收到一个消息,真是惊呆我了,博客轩给我发了信息,说是俺的博客文章有特色可以出本书,,这简直让我受宠若惊,俺只是个大三的技术宅,写的博客也是自己所学的一些见解和在网上看到我一些博文以及帖子里综合起来写的,,总之这又给了额外的动力,让自己继续前进,,希望和大家能够分享一些自己的经验,,在最需要奋斗的年级以及在技术的领域踽踽独行的过程中有共同的伙伴继续前进~ 今天写的是Linux设备驱动中的阻塞和非阻塞I/0,何谓阻塞与非阻塞I/O?简单来说就是对I/O操作的两种不同的方式,驱动程序可以灵活的

linux设备驱动系列:如何处理竞态关系

综述 在上一篇介绍了linux驱动的调试方法,这一篇介绍一下在驱动编程中会遇到的并发和竟态以及如何处理并发和竞争. 首先什么是并发与竟态呢?并发(concurrency)指的是多个执行单元同时.并行被执行.而并发的执行单元对共享资源(硬件资源和软件上的全局.静态变量)的访问则容易导致竞态(race conditions).可能导致并发和竟态的情况有: SMP(Symmetric Multi-Processing),对称多处理结构.SMP是一种紧耦合.共享存储的系统模型,它的特点是多个CPU使用共

20150220 IMX257 linux设备驱动之Cdev结构

20150220 IMX257 linux设备驱动之Cdev结构 2015-02-20 21:17 李海沿 一.CDEV结构 /*   *内核源码位置   *linux2.6.38/include/linux/cdev.h   */        struct cdev {       struct kobject kobj;       struct module *owner;   //一般初始化为:THIS_MODULE       const struct file_operations

Linux设备驱动故障定位指引与实例

Linux设备驱动故障定位指引 Linux设备驱动种类繁多,涉及的知识点多,想写一个通用的故障定位方法指引,是个难度颇大且不容易做好的工作.限于笔者的经验,难以避免存在疏漏之处,欢迎大家留言指正补充. Linux设备驱动的知识点涉及硬件和软件,故障原因也各种各样,不过从笔者多年的维护经验来看,硬件相关问题导致的设备驱动故障还是占了较大的比例,而大部分的硬件问题特别是环境问题也是相对来说较容易排查的.下图是Linux设备驱动故障定位脑图(大图),图中按硬件和软件分为两类,硬件分类又细分为环境.芯片