C语言一个简单的字符驱动程序_C/C++语言_黑客防线网安服务器维护基地--Powered by WWW.RONGSEN.COM.CN

C语言一个简单的字符驱动程序

作者:黑客防线网安C/C++教程基地 来源:黑客防线网安C/C++教程基地 浏览次数:0

本篇关键词:字符简单一个语言
黑客防线网安网讯:    代码分为:makefile ,内核态程序 globalmem.c 用户态程序 user.c 功能是把一个数组排序,你也可以使用 read write函数往内存里写东西。  运行方法:  make,产生globalmem.ko文件...
    代码分为:makefile 内核态程序 globalmem.c 用户态程序 user.c 功能是把一个数组排序你也可以使用 read write函数往内存里写东西
  运行方法:
  make,产生globalmem.ko文件, Insmod globalmem.ko , 看一下 dmesg -c 是否有提示信息(也可以 lsmod | grep "glo"), 有的话说明加载上了,
  然后 mknod /dev globalmem c 254 0 , 看一下 ls /proc/device/ | grep "glo" 有东西没
  然后运行用户态程序,数组被排序了。dmesg -c 可以看到提示信息, 在模块中排序了。
  上代码(是带锁的代码,顺便练练手)
  makefile
  1# makefile for kernel 2.6
  2ifneq ($(KERNELRELEASE),)
  3#mymodule-objs := file1.o file2.o
  4obj-m := globalmem.o
  5
  6else
  7PWD := $(shell pwd)
  8KVER := $(shell uname -r)
  9KDIR := /lib/modules/$(KVER)/build
  10all:
  11 $(MAKE) -C $(KDIR) M=$(PWD)
  12clean:
  13 rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions
  14
  15endif
  16
  内核模块
  1#include <linux/module.h>
  2#include <linux/types.h>
  3#include <linux/errno.h>
  4#include <linux/mm.h>
  5#include <linux/sched.h>
  6#include <linux/version.h>
  7#include <linux/cdev.h>
  8#include <asm/io.h>
  9#include <asm/system.h>
  10#include <asm/uaccess.h>
  11#include "mem.h"
  12
  13#define GLOBALMEM_SIZE 0x1000
  14#define MEM_CLEAR 0x1
  15#define ARRAY_INSTER 0x2
  16#define GLOBALMEM_MAJOR 254
  17
  18static int globalmem_major = GLOBALMEM_MAJOR;
  19
  20//the struct of global
  21typedef struct __globalmem_dev{
  22 struct cdev cdev;
  23 unsigned char mem[GLOBALMEM_SIZE];
  24 //add lock, signal
  25 struct semaphore sem;
  26 atomic_t ato;
  27}globalmem_dev;
  28
  29globalmem_dev * global;
  30
  31typedef struct __arithmetic_st{
  32 int buf[10];
  33 int len;
  34}arithmetic_st;
  35
  36
  37
  38
  39int globalmem_open(struct inode *inode, struct file * filp)
  40{
  41 filp->private_data = global;
  42 //you can only open one file
  43 if(!atomic_dec_and_test(&global->ato))
  44 {
  45 printk( KERN_NOTICE "atomic is lock ");
  46 return -EBUSY;
  47 }
  48 return 0;
  49}
  50
  51int globalmem_release(struct inode * inode, struct file * filp)
  52{
  53 atomic_inc(&global->ato);
  54 return 0;
  55}
  56
  57
  58//read
  59static ssize_t globalmem_read(struct file * filp, char __user *buf, size_t size, loff_t *ppos)
  60{
  61 unsigned long p = *ppos;
  62 unsigned int count = size;
  63 int ret = 0;
  64
  65 globalmem_dev *dev = filp->private_data;
  66
  67 if(p > GLOBALMEM_SIZE)
  68 return count ? -ENXIO : 0;
  69 if(count > GLOBALMEM_SIZE - p)
  70 count = GLOBALMEM_SIZE - p;
  71//add the lock
  72 if(down_interruptible(&dev->sem))
  73 {
  74 return -ERESTARTSYS;
  75 }
  76
  77
  78 if(copy_to_user(buf, (void *)(dev->mem + p), count)){
  79 ret = -EFAULT;
  80 }else{
  81 *ppos += count;
  82 ret = count;
  83 printk(KERN_INFO "read %d bytes from %u ", count, p);
  84 }
  85//unlock
  86 up(&dev->sem);
  87 return ret;
  88}
  89
  90//write
  91static ssize_t globalmem_write(struct file * filp, const char __user * buf,
  92 size_t size, loff_t *ppos)
  93{
  94 unsigned long p = *ppos;
  95 unsigned int count = size;
  96 int ret = 0;
  97 globalmem_dev *dev = filp->private_data;
  98
  99 if(p >= GLOBALMEM_SIZE)
  100 return count ? -ENXIO : 0;
  101 if(count > GLOBALMEM_SIZE - p)
  102 count = GLOBALMEM_SIZE - p;
  103//lock
  104 if(down_interruptible(&dev->sem)){
  105 return -ERESTARTSYS;
  106 }
  107 if(copy_from_user((dev->mem + p), buf, count))
  108 ret = -EFAULT;
  109 else{
  110 *ppos += count;
  111 ret = count;
  112 printk( KERN_INFO "written %d bytes from %u ", count , p);
  113 }
  114//unlock
  115 up(&dev->sem);
  116 return ret;
  117}
  118
  119//seek
  120static loff_t globalmem_llseek(struct file * filp, loff_t offset, int orig)
  121{
  122 loff_t ret = 0;
  123 switch(orig){
  124 case 0:
  125 if(offset < 0){
  126 ret = -EINVAL;
  127 break;
  128 }
  129 if((unsigned int) offset > GLOBALMEM_SIZE){
  130 ret = -EINVAL;
  131 break;
  132 }
  133 filp->f_pos = (unsigned int)offset;
  134 ret = filp->f_pos;
  135 break;
  136 case 1:
  137 if((filp->f_pos + offset) > GLOBALMEM_SIZE){
  138 ret = -EINVAL;
  139 break;
  140 }
  141 if((filp->f_pos + offset) < 0){
  142 ret = -EINVAL;
  143 break;
  144 }
  145 filp->f_pos += offset;
  146 ret = filp->f_pos;
  147 break;
  148 default :
  149 ret = -EINVAL;
  150 break;
  151 }
  152 return ret;
  153}
  154static int inster_arithmetic(int * buf, int len)
  155{
  156 int i;
  157 int j;
  158 int key;
  159
  160 if(len < 2){
  161 return -1;
  162 }
  163 for( j = 1; j < len; j++){
  164 key = *(buf + j);
  165 i = j -1;
  166
  167 while(i >= 0 && *(buf + i) > key){
  168 *(buf + i + 1) = *(buf + i);
  169 i = i - 1;
  170 }
  171 *(buf + i + 1) = key;
  172 }
  173}
  174
  175//ioctl
  176static int globalmem_ioctl(struct inode * inode, struct file * filp,
  177 unsigned int cmd, unsigned long arg)
  178{
  179 globalmem_dev * dev = filp->private_data;
  180 arithmetic_st * p;
  181 arithmetic_st * q;
  182 int i;
  183
  184 switch(cmd){
  185 case MEM_CLEAR:
  186 //lock
  187 if(down_interruptible(&dev->sem)){
  188 return -ERESTARTSYS;
  189 }
  190 memset(dev->mem, 0, GLOBALMEM_SIZE);
  191 printk(KERN_INFO "glbalmem is set to zero ! ");
  192 //unlock
  193 up(&dev->sem);
  194 break;
  195 case ARRAY_INSTER:
  196 p = (arithmetic_st *)arg;
  197 q = (arithmetic_st *)kmalloc(sizeof(arithmetic_st), GFP_KERNEL);
  198 memset(q->buf, 0, 10);
  199 if(down_interruptible(&dev->sem)){
  200 return -ERESTARTSYS;
  201 }
  202 if(copy_from_user(q, p, sizeof(arithmetic_st))){
  203 return -EFAULT;
  204 }
  205 if(q->len != 0){
  206 inster_arithmetic(q->buf, q->len);
  207 if(copy_to_user(p, q, sizeof(arithmetic_st))){
  208 return -EFAULT;
  209 }
  210 for(i = 0; i < q->len; i++){
  211 printk(KERN_INFO ">>>>>>>>>>buf%d:%d ! ",i, q->buf[i]);
  212 }
  213 }else{
  214 printk(KERN_INFO ">>>>>>>>>>len is zero [%d] [%s] ! ", __LINE__, __FUNCTION__);
  215 }
  216 kfree(q);
  217 break;
  218
  219 default:
  220 return -EINVAL;
  221 }
  222 return 0;
  223}
  224
  225static const struct file_operations globalmem_fops =
  226{
  227 .owner = THIS_MODULE,
  228 .llseek = globalmem_llseek,
  229 .read = globalmem_read,
  230 .write = globalmem_write,
  231 .ioctl = globalmem_ioctl,
  232 .open = globalmem_open,
  233 .release = globalmem_release,
  234};
  235//register cdev
  236static void globalmem_setup_cdev(globalmem_dev * dev, int index)
  237{
  238 int err;
  239 int devno = MKDEV(globalmem_major, index);
  240
  241 cdev_init(&dev->cdev, &globalmem_fops);
  242 dev->cdev.owner = THIS_MODULE;
  243// dev->cdev.ops = &globalmem_fops;
  244 err = cdev_add(&dev->cdev, devno, 1);
  245 if(err)
  246 printk( KERN_NOTICE "error %d adding LED %d" , err, index);
  247}
  248
  249//
  250int globalmem_init(void)
  251{
  252 int result;
  253 dev_t devno = MKDEV(globalmem_major, 0);
  254
  255 if(globalmem_major){
  256 result = register_chrdev_region(devno, 1, "globalmem");
  257 }else{
  258 result = alloc_chrdev_region(&devno, 0, 1, "globalmem");
  259 globalmem_major = MAJOR(devno);
  260 }
  261 if(result < 0)
  262 return result;
  263 global = kmalloc(sizeof(globalmem_dev), GFP_KERNEL);
  264 if(!global){
  265 result = -ENOMEM;
  266 goto fail_kmalloc;
  267 }
  268 memset(global, 0, sizeof(globalmem_dev));
  269 globalmem_setup_cdev(global, 0);
  270 printk( KERN_NOTICE "init over! ");
  271 //lock
  272 init_MUTEX(&global->sem);
  273 atomic_set(&global->ato, 1);
  274 printk( KERN_NOTICE "init signl! ");
  275 printk( KERN_INFO "the process is %s pid is %i ", current->comm, current->pid);
  276 return 0;
  277
  278fail_kmalloc:
  279 unregister_chrdev_region(devno, 1);
  280 return result;
  281}
  282//
  283void globalmem_exit(void)
  284{
  285 cdev_del(&global->cdev);
  286 kfree(global);
  287 unregister_chrdev_region(MKDEV(globalmem_major, 0), 1);
  288 printk( KERN_NOTICE "exit over! ");
  289}
  290
  291MODULE_AUTHOR("xueby");
  292MODULE_LICENSE("XBY/GPL");
  293module_param(globalmem_major, int , S_IRUGO);
  294
  295module_init(globalmem_init);
  296module_exit(globalmem_exit);
  297
  用户态
  1#include<stdio.h>
  2#include<string.h>
  3#include<stdlib.h>
  4#include<unistd.h>
  5#include<sys/stat.h>
  6#include<fcntl.h>
  7#include<sys/types.h>
  8
  9#define MEM_CLEAR 0x1
  10#define ARRAY_INSTER 0x2
  11
  12typedef struct __arithmetic_st{
  13 int buf[10];
  14 int len;
  15}arithmetic_st;
  16
  17
  18
  19int main()
  20{
  21 int ret;
  22 int fd;
  23 int buf[10] = {2, 5, 1, 9, 3, 12, 0,15, 11, 23};
  24 char rbuf[100] = {0, };
  25 arithmetic_st *a;
  26
  27 a = (arithmetic_st*)malloc(sizeof(arithmetic_st));
  28 if(!a)
  29 return -1;
  30 memcpy(a->buf, buf, sizeof(buf));
  31 a->len = 10;
  32
  33 fd = open("/dev/globalmem", O_RDWR , S_IRWXU);
  34 ioctl(fd, ARRAY_INSTER, (unsigned long)a);
  35 for(ret = 0; ret < 10; ret++){
  36 printf("%d ;",a->buf[ret]);
  37 }
  38 return 0;
  39}
  40
  41
    黑客防线网安服务器维护方案本篇连接:http://www.rongsen.com.cn/show-15437-1.html
网站维护教程更新时间:2012-04-04 22:54:44  【打印此页】  【关闭
我要申请本站N点 | 黑客防线官网 |  
专业服务器维护及网站维护手工安全搭建环境,网站安全加固服务。黑客防线网安服务器维护基地招商进行中!QQ:29769479

footer  footer  footer  footer