代码分为: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 可以看到提示信息, 在模块中排序了。
上代码(是带锁的代码,顺便练练手)
1
# makefile for kernel 2.62
ifneq ($(KERNELRELEASE),)3
#mymodule-objs := file1.o file2.o4
obj-m := globalmem.o5

6
else7
PWD := $(shell pwd)8
KVER := $(shell uname -r)9
KDIR := /lib/modules/$(KVER)/build10
all:11
$(MAKE) -C $(KDIR) M=$(PWD)12
clean:13
rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions14

15
endif16

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 0x100014
#define MEM_CLEAR 0x115
#define ARRAY_INSTER 0x216
#define GLOBALMEM_MAJOR 25417

18
static int globalmem_major = GLOBALMEM_MAJOR;19

20
//the struct of global21

typedef struct __globalmem_dev
{22
struct cdev cdev;23
unsigned char mem[GLOBALMEM_SIZE];24
//add lock, signal25
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 file43
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
//read59
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 lock72
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
//unlock86
up(&dev->sem);87
return ret;88
}89

90
//write91
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
//lock104

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
//unlock115
up(&dev->sem);116
return ret;117
}118

119
//seek120
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
//ioctl176
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
//lock187

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
//unlock193
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 cdev236
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
//lock272
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 0x110
#define ARRAY_INSTER 0x211

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

浙公网安备 33010602011771号