招生熱線
0755-86191118 0755-86191118
我的位置: 首頁 > 學(xué)習(xí)專區(qū) > .NET技術(shù) > C語言一個簡單的字符驅(qū)動程序

C語言一個簡單的字符驅(qū)動程序

2013-05-25 09:02:04
來源:
[導(dǎo)讀] 代碼分為:makefile ,內(nèi)核態(tài)程序 globalmem c 用戶態(tài)程序 user c 功能是把一個數(shù)組排序,你也可以使用 read write函數(shù)往內(nèi)存里寫東
代碼分為:makefile ,內(nèi)核態(tài)程序 globalmem.c 用戶態(tài)程序 user.c 功能是把一個數(shù)組排序,你也可以使用 read write函數(shù)往內(nèi)存里寫東西。

運行方法:

make,產(chǎn)生globalmem.ko文件, Insmod globalmem.ko , 看一下 dmesg -c 是否有提示信息(也可以 lsmod | grep "glo"), 有的話說明加載上了,

然后 mknod /dev globalmem c 254 0 , 看一下 ls /proc/device/ | grep "glo" 有東西沒。

然后運行用戶態(tài)程序,數(shù)組被排序了。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

內(nèi)核模塊

1#include

2#include

3#include

4#include

5#include

6#include

7#include

8#include

9#include

10#include

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);

深圳北大青鳥

評論
2017年男生學(xué)什么技術(shù)好 在職轉(zhuǎn)行學(xué)什么好 2017年廣東女高中生畢業(yè)學(xué)什么專業(yè)好 高中畢業(yè)學(xué)什么 在職轉(zhuǎn)行 高中生學(xué)IT好嗎 高中生學(xué)習(xí)什么技術(shù)好就業(yè) 高中生學(xué)什么好 高中生學(xué)什么技能有出路 深圳教育盛典三好單位 職場前沿 高考200分學(xué)什么有前途? 高中畢業(yè)生學(xué)什么技術(shù)好 九零后學(xué)什么有前途 女生學(xué)什么有前途 300分可以上什么專科學(xué)校 300分可以上什么學(xué)校 300分可以上什么高校 300分可以上什么大學(xué) 初中生學(xué)什么好就業(yè)有前途 高中沒畢業(yè)不想讀書了怎么辦 專科院校錄取分數(shù)線 專科要多少分 學(xué)什么能賺錢 大學(xué)生創(chuàng)業(yè) 寶安北大青鳥 如何更好的學(xué)習(xí)軟件開發(fā) 軟件編程 女生學(xué)習(xí)什么技能好 跳槽轉(zhuǎn)行學(xué)什么好 學(xué)軟件編程就業(yè)前景怎么樣 讀什么專科比較好 高中畢業(yè)學(xué)什么好 高中畢業(yè)女生學(xué)什么就業(yè)前景好 高考300分學(xué)什么就業(yè)前景好 廣東高考300分學(xué)什么就業(yè)前景好 學(xué)什么就業(yè)前景好 廣東高考200多分學(xué)什么專業(yè)好找工作 高考200多分學(xué)什么專業(yè)好找工作 學(xué)什么好就業(yè) 深圳電腦培訓(xùn)學(xué)校哪家好 高中生畢業(yè)學(xué)什么好 選哪個IT培訓(xùn)學(xué)校學(xué)技術(shù)好 女生學(xué)什么好 高中畢業(yè)學(xué)什么專業(yè)好
好吊妞免费视频在线观看,久久亚洲国产人成综合网,久久精品国产2020,欧美精品综合在线
亚洲国产一区二区三区 | 在线观看片a免费不卡看片 麻豆91青青国产在线观看 | 一道日本亚洲香蕉 | 日韩25区中文字幕 | 一区二区欧美日韩动漫精品 | 亚洲欧洲美洲在线观看 |