|
Posted on
2009-11-25 22:26
放飞自我
阅读( 532)
评论()
收藏
举报
代码分为: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 2 ifneq ($(KERNELRELEASE),) 3 #mymodule-objs := file1.o file2.o 4 obj-m := globalmem.o 5 6 else 7 PWD := $(shell pwd) 8 KVER := $(shell uname -r) 9 KDIR := /lib/modules/$(KVER)/build 10 all: 11 $(MAKE) -C $(KDIR) M=$(PWD) 12 clean: 13 rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions 14 15 endif 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 18 static int globalmem_major = GLOBALMEM_MAJOR; 19 20 //the struct of global 21 typedef 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 29 globalmem_dev * global; 30 31 typedef struct __arithmetic_st { 32 int buf[10]; 33 int len; 34 }arithmetic_st; 35 36 37 38 39 int 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\n"); 46 return -EBUSY; 47 } 48 return 0; 49 } 50 51 int globalmem_release(struct inode * inode, struct file * filp) 52  { 53 atomic_inc(&global->ato); 54 return 0; 55 } 56 57 58 //read 59 static 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\n", count, p); 84 } 85 //unlock 86 up(&dev->sem); 87 return ret; 88 } 89 90 //write 91 static 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\n", count , p); 113 } 114 //unlock 115 up(&dev->sem); 116 return ret; 117 } 118 119 //seek 120 static 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 } 154 static 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 176 static 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 !\n"); 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 !\n",i, q->buf[i]); 212 } 213 }else { 214 printk(KERN_INFO ">>>>>>>>>>len is zero [%d] [%s] !\n", __LINE__, __FUNCTION__); 215 } 216 kfree(q); 217 break; 218 219 default: 220 return -EINVAL; 221 } 222 return 0; 223 } 224 225 static 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 236 static 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 // 250 int 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!\n"); 271 //lock 272 init_MUTEX(&global->sem); 273 atomic_set(&global->ato, 1); 274 printk( KERN_NOTICE "init signl!\n"); 275 printk( KERN_INFO "the process is %s pid is %i \n", current->comm, current->pid); 276 return 0; 277 278 fail_kmalloc: 279 unregister_chrdev_region(devno, 1); 280 return result; 281 } 282 // 283 void 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!\n"); 289 } 290 291 MODULE_AUTHOR("xueby"); 292 MODULE_LICENSE("XBY/GPL"); 293 module_param(globalmem_major, int , S_IRUGO); 294 295 module_init(globalmem_init); 296 module_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 12 typedef struct __arithmetic_st { 13 int buf[10]; 14 int len; 15 }arithmetic_st; 16 17 18 19 int 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
|