北京电子科技学院(BESTI)
              
课程:信息安全系统设计基础 班级:1353 姓名:郑伟、吴子怡
学号:20135322、20135313 指导教师: 娄嘉鹏 实验日期:2015年11月17日
必修/选修:必修 实验序号:exp4 实验时间:15:30-18:00
实验名称:  exp4_外设驱动程序设计
实验内容:在PC机上编写简单的虚拟硬件驱动程序并进行调试,实验驱动的各个接口函数的实现,分析并理解驱动与应用程序的交互过程。
实验目的与要求 1.学习在LINUX下进行驱动设计的原理;   
2.掌握使用模块方式进行驱动开发调试的过程 。 
实验器材 1、Lenovo计算机一台
2、ARM实验箱一个

配置实验环境:同实验一。若不能熟练掌握,可点击如下链接查看详细步骤:

http://www.cnblogs.com/zhengwei0712/p/4960130.html <<exp1实验报告

一、实验步骤

1.阅读和理解源代码

进入/01_demo,使用vi编辑器阅读理解源代码。

2.编译驱动模块及测试程序

在 Makefile 中有两种编译方法,可以在本机上使用gcc 也可以使用交叉编译器进行编译,我们组采用交叉编译器进行编译。如下图:


注意:如果编译的时候出现问题,可能是在/usr/src 下没有建立一个linux 连接,可以使用下面的命令:

  1. [root@zxt 01_demo]# cd /usr/src/
  2. [root@zxt src]# ln -sf linux-2.4.20-8 linux
  3. [root@zxt src]# ls
  4. debug linux linux-2.4 linux-2.4.20-8 redhat

3.测试驱动程序

如果使用 gcc 编译的话,需要通过下面的命令来建立设备节点,如果使用交叉编译器的话,不需要建立设备节点。

  1. #mknod /dev/demo c 254 0

首先要插入驱动模块demo.o,然后可以用lsmod 命令来查看模块是否已经被插入,在不使用该模块的时候还可以用rmmod 命令来将模块卸载。

我们使用交叉编译器,不需要建立设备节点。下图为步骤成功的结果。

驱动模块成功插入后,在/dev下面建立一个demo的审文件,使用cat来直接调用read函数,测试读过程。

  1. 如果模块没有成功插入的话,会出现下面的情况:
  2. [root@zxt 01_demo]# ./test_demo
  3. ####DEMO device open fail####

在驱动模块成功插入后,会在/dev 下面建立一个叫做demo 的设备文件,我们也可以使用cat 命令
来直接调用read 函数,来测试读过程。

  1. [root@zxt demo]# cat /dev/demo/0
  2. device open success!

二、遇到的问题与解决方法

在编译驱动模块的时候,makefile 有两种编译方法,可以用gcc,也可以用交叉编译器编译。当我们使用编译器进行编译的时候,出现了问题Error 1,如下图:

第一次,可能是/usr/src下没有建立 linux连接,所以使用命令,如下图:

第二次,经过研究,发现是makefile里的编写文件,与实验指导书里的不一样,通过进入makefile文件,修改了路径,才编译通过,如下图:

附:代码分析

  1. 参考驱动代码 demo.c 如下,其中的 demo_read,demo_write 函数完成驱动的读写接口功能,do_write 函数实现将用户写入的数据逆序排列,通过读取函数读取转换后的数据。
  2.  
  3. 这里只是演示接口的实现过程和内核驱动对用户的数据的处理。 Demo_ioctl函数演示ioctl调用接口的实现过程。
  4.  
  5. test_demo.c
  6.  
  7. #include <stdio.h>
  8.  
  9. #include <stdlib.h>
  10.  
  11. #include <fcntl.h>//其中定义了很多宏和诸如open,close函数
  12.  
  13. #include <unistd.h>
  14.  
  15. #include <sys/ioctl.h>//ioctl函数的头文件
  16.  
  17. void showbuf(char *buf);
  18.  
  19. int MAX_LEN=32;
  20.  
  21. int main()
  22.  
  23. {
  24.  
  25. int fd;
  26.  
  27. int i;
  28.  
  29. char buf[255];
  30.  
  31. for(i=0; i<MAX_LEN; i++){//给数组元素依次赋值
  32.  
  33. buf[i]=i;
  34.  
  35. }
  36.  
  37. fd=open("/dev/demo",O_RDWR);//以既可以读又可以写的方式打开文件
  38.  
  39. if(fd < 0){
  40.  
  41. printf("####DEMO device open fail####\n");
  42.  
  43. return (-1);
  44.  
  45. }
  46.  
  47. printf("write %d bytes data to /dev/demo \n",MAX_LEN);
  48.  
  49. showbuf(buf);//先显示一下要写入什么,然后写入
  50.  
  51. write(fd,buf,MAX_LEN);
  52.  
  53. printf("Read %d bytes data from /dev/demo \n",MAX_LEN);
  54.  
  55. read(fd,buf,MAX_LEN);
  56.  
  57. showbuf(buf);//先读出来字符串到buf中,再显示
  58.  
  59. ioctl(fd,1,NULL);
  60.  
  61. ioctl(fd,4,NULL);
  62.  
  63. close(fd);
  64.  
  65. return 0;
  66.  
  67. }
  68.  
  69. void showbuf(char *buf)
  70.  
  71. {
  72.  
  73. int i,j=0;
  74.  
  75. for(i=0;i<MAX_LEN;i++){
  76.  
  77. if(i%4 ==0)
  78.  
  79. printf("\n%4d: ",j++);
  80.  
  81. printf("%4d ",buf[i]);
  82.  
  83. }
  84.  
  85. printf("\n*****************************************************\n");
  86.  
  87. }
  88.  
  89. /**************************************************************
  90. demo.c
  91. linux driver example for UP-netarm3000 & UP-netarm2410
  92. It can be compiled for x86 PC
  93. author: zou jian-guo <ah_zou@163.com>
  94. date: 2004-8-20
  95.  
  96. ***************************************************************/
  97.  
  98. //#define CONFIG_DEVFS_FS
  99.  
  100. #ifndef __KERNEL__
  101. # define __KERNEL__
  102. #endif
  103. #ifndef MODULE
  104. # define MODULE
  105. #endif
  106.  
  107. #include <linux/config.h>
  108. #include <linux/module.h>
  109. #include <linux/devfs_fs_kernel.h>
  110.  
  111. #include <linux/init.h>
  112. #include <linux/kernel.h> /* printk() */
  113. #include <linux/slab.h> /* kmalloc() */
  114. #include <linux/fs.h> /* everything... */
  115. #include <linux/errno.h> /* error codes */
  116. #include <linux/types.h> /* size_t */
  117. #include <linux/proc_fs.h>
  118. #include <linux/fcntl.h> /* O_ACCMODE */
  119. #include <linux/poll.h> /* COPY_TO_USER */
  120. #include <asm/system.h> /* cli(), *_flags */
  121.  
  122. #define DEVICE_NAME "demo"
  123. #define demo_MAJOR 254
  124. #define demo_MINOR 0
  125. static int MAX_BUF_LEN=1024;
  126. static char drv_buf[1024];
  127. static int WRI_LENGTH=0;
  128.  
  129. /*************************************************************************************/
  130. /*逆序排列缓冲区数据*/
  131. static void do_write()
  132. {
  133.  
  134. int i;
  135. int len = WRI_LENGTH;
  136. char tmp;
  137. for(i = 0; i < (len>>1); i++,len--){
  138. tmp = drv_buf[len-1];
  139. drv_buf[len-1] = drv_buf[i];
  140. drv_buf[i] = tmp;
  141. }
  142. }
  143. /*************************************************************************************/
  144. static ssize_t demo_write(struct file *filp,const char *buffer, size_t count)
  145. {
  146. if(count > MAX_BUF_LEN)count = MAX_BUF_LEN;
  147. copy_from_user(drv_buf , buffer, count);
  148. WRI_LENGTH = count;
  149. printk("user write data to driver\n");
  150. do_write();
  151. return count;
  152. }
  153. /*************************************************************************************/
  154. static ssize_t demo_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
  155. {
  156. if(count > MAX_BUF_LEN)
  157. count=MAX_BUF_LEN;
  158. copy_to_user(buffer, drv_buf,count);
  159. printk("user read data from driver\n");
  160. return count;
  161. }
  162. /*************************************************************************************/
  163. static int demo_ioctl(struct inode *inode, struct file *file,
  164. unsigned int cmd, unsigned long arg)
  165. {
  166. printk("ioctl runing\n");
  167. switch(cmd){
  168. case 1:printk("runing command 1 \n");break;
  169. case 2:printk("runing command 2 \n");break;
  170. default:
  171. printk("error cmd number\n");break;
  172. }
  173. return 0;
  174. }
  175. /*************************************************************************************/
  176. static int demo_open(struct inode *inode, struct file *file)
  177. {
  178. sprintf(drv_buf,"device open sucess!\n");
  179. printk("device open sucess!\n");
  180. return 0;
  181. }
  182. /*************************************************************************************/
  183. static int demo_release(struct inode *inode, struct file *filp)
  184. {
  185. MOD_DEC_USE_COUNT;
  186. printk("device release\n");
  187. return 0;
  188. }
  189.  
  190. /*************************************************************************************/
  191. static struct file_operations demo_fops = {
  192. owner: THIS_MODULE,
  193. write: demo_write,
  194. read: demo_read,
  195. ioctl: demo_ioctl,
  196. open: demo_open,
  197. release: demo_release,
  198. };
  199. /*************************************************************************************/
  200.  
  201. #ifdef CONFIG_DEVFS_FS
  202. static devfs_handle_t devfs_demo_dir, devfs_demoraw;
  203. #endif
  204.  
  205. /*************************************************************************************/
  206. static int __init demo_init(void)
  207. {
  208. #ifdef CONFIG_DEVFS_FS
  209. devfs_demo_dir = devfs_mk_dir(NULL, "demo", NULL);
  210. devfs_demoraw = devfs_register(devfs_demo_dir, "0", DEVFS_FL_DEFAULT,
  211. demo_MAJOR, demo_MINOR, S_IFCHR | S_IRUSR | S_IWUSR,
  212. &demo_fops, NULL);
  213. #else
  214. int result;
  215. SET_MODULE_OWNER(&demo_fops);
  216. result = register_chrdev(demo_MAJOR, "demo", &demo_fops);
  217. if (result < 0) return result;
  218. // if (demo_MAJOR == 0) demo_MAJOR = result; /* dynamic */
  219. #endif
  220. printk(DEVICE_NAME " initialized\n");
  221. return 0;
  222. }
  223.  
  224. /*************************************************************************************/
  225. static void __exit demo_exit(void)
  226. {
  227. unregister_chrdev(demo_MAJOR, "demo");
  228. //kfree(demo_devices);
  229. printk(DEVICE_NAME " unloaded\n");
  230. }
  231.  
  232. /*************************************************************************************/
  233. module_init(demo_init);
  234. module_exit(demo_exit);

  

三、exp4学习摘要

1.在 Makefile 中有两种编译方法,可以在本机上使用gcc。也可以使用交叉编译器进行编译,但是gcc的编译方法还有后续操作。如下:

如果使用 gcc 编译的话,在测试驱动程序时需要通过下面的命令来建立设备节点,如果使用交叉编译器的话,不需要建立设备节点。

  1. #mknod /dev/demo c 254 0

2.当make出现问题时,可尝试打开makefile文件查看编译程序的所在路径是否正确,是否能够成功链接,若不能,则应该加以修改,这一点在实验五中也会涉及。修改是一个难度较大的操作,也没有学习过。可以多加留意学习。

四、实验体会

通过这次实验,虽然操作不难,但我们觉得注重在于对代码的理解,以及实验遇到问题时的解决。Makefile的路径修改成功,让我们很开心,但是也深深感到了自己对理论知识的掌握还不够,makefile学得还不够精,遇到问题的时候要学会一个个地寻找问题,如果不是这个问题,就排除它,寻找下一个问题原因的可能性。由于多番尝试,最终的成功解决,不仅能使我们尝到成功的喜悦,还能使我们对问题理解和记忆地更加深刻,今后再次遇到此类问题也就不用再担心。同时还帮助同学们解决了这个问题,加深了团队合作的意识。

实验依然是使用上次实验的环境,多次操作使得我们对ARM和REDHAT的搭建更加熟练。

在本次实验中,我负责查找实验指导书中对问题的剖析和预测。重点关注问题的解决方法,还有上网搜查问题的结症所在和解决方案。郑伟则是负责操作和调试。在遇到问题时,我们各司其职,她对自己的操作进行检查,我积极提出问题的可能根源。合作得很高效。

五、搭档博客传送门

http://www.cnblogs.com/zhengwei0712/20135322郑伟

信息安全系统设计基础exp_4的更多相关文章

  1. 20145213《信息安全系统设计基础》实验一 Linux开发环境的配置

    北京电子科技学院(BESTI) 实 验 报 告 课程:信息安全系统设计基础 班级:1452 姓名: 黄亚奇 祁玮 学号:20145213 20145222 成绩: 指导教师:娄嘉鹏 实验日期:2016 ...

  2. 20145215&20145307《信息安全系统设计基础》实验二 固件设计

    20145215&20145307<信息安全系统设计基础>实验二 固件设计 实验目的与要求 了解多线程程序设计的基本原理,学习 pthread 库函数的使用. 了解在 linux ...

  3. 20145215&20145307《信息安全系统设计基础》实验五 网络通信

    小组成员:20145215卢肖明.20145307陈俊达 实验报告链接:信息安全系统设计基础--实验五实验报告

  4. 20145223《信息安全系统设计基础》 GDB调试汇编堆栈过程分析

    20145223<信息安全系统设计基础> GDB调试汇编堆栈过程分析 分析的c语言源码 生成汇编代码--命令:gcc -g example.c -o example -m32 进入gdb调 ...

  5. 20145216 20145330 《信息安全系统设计基础》 实验五 简单嵌入式WEB 服务器实验

    20145216 20145330 <信息安全系统设计基础> 实验五 简单嵌入式WEB 服务器实验 实验报告封面 实验步骤 1.阅读理解源码 进入/arm2410cl/exp/basic/ ...

  6. 20145208《信息安全系统设计基础》实验五 简单嵌入式WEB 服务器实验

    20145208<信息安全系统设计基础>实验五 简单嵌入式WEB 服务器实验 20145208<信息安全系统设计基础>实验五 简单嵌入式WEB 服务器实验

  7. 2016-2017-1 《信息安全系统设计基础》 学生博客及Git@OSC 链接

    2016-2017-1 <信息安全系统设计基础> 学生博客及Git@OSC 链接 博客 1452 20145201李子璇 20145202马 超 20145203盖泽双 20145204张 ...

  8. 20145215&20145307信息安全系统设计基础实验报告

    20145215&20145307信息安全系统设计基础实验报告 PART1 一.实验原理 交叉编译,简单地说,就是在一个平台上生成另一个平台上的可执行代码.同一个体系结构可以运行不同的操作系统 ...

  9. 20145315&20145307《信息安全系统设计基础》实验五

    20145315&20145307<信息安全系统设计基础>实验五 北京电子科技学院(BESTI) 实 验 报 告 课程:信息安全系统设计基础 班级:1453 1452 姓名:陈俊达 ...

随机推荐

  1. 故障时自动重启Apache

    最近不知道为什么博客总是莫名其妙地挂掉, 重启Apache就好了,我也懒得去研究到底是哪里出了问题. 只是每次都需要手工SSH上去重启Apache,有点麻烦. 而且有时候在夜里挂掉,一晚上博客就都不能 ...

  2. 一步步学敏捷开发:6、Scrum的3种工件

    Scrum的3种工件包括:Product Blacklog.Sprint Backlog.完成标准. 1.产品待办事项列表(Product Backlog) 产品Blacklog是Scrum中的核心工 ...

  3. android JSON解析之JSONObject与GSON

    1.写在前面 JSON数据是android网络开发中常见的数据格式,JSON最常见的传输方法是使用HTTP协议,关于android开发中HTTP协议的使用方法可参考我的另一篇随笔android网络编程 ...

  4. 如何延长windows评估版的方法

    在软件的开发测试,通常使用的是windows评估版本.但是有时候它的使用期限不满足你的需求.所以你可以用一下方法来延长评估版的时间. 延長使用期限 跟 Windows Server 2008 延長使用 ...

  5. 史上最全的MSSQL复习笔记 (转连接)

    http://www.cnblogs.com/gameworld/p/4790881.html

  6. HDU 4050 wolf5x(动态规划-概率DP)

    wolf5x Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  7. 升级了win10后开启wifi热点出现iphone&macbook连接断线的问题(win7也一样)

    升级了win10后开启wifi热点出现iphone&macbook连接 不间断 断线的问题 文后附上开启虚拟wifi的办法 百度参考了别人也出现这种问题,解决办法是修改信道,默认信道是11,修 ...

  8. 《JavaScript修炼之道》读书笔记

    1.参考书目 入门:<JavaScript DOM编程艺术>第二版 进阶:<JavaScript高级程序设计>第二版.<JavaScript编程精粹> <Ja ...

  9. python中BeautifulSoup库中find函数

    http://www.crummy.com/software/BeautifulSoup/bs3/documentation.zh.html#contents 简单的用法: find(name, at ...

  10. zstu-3769 数回文子串

    思路:用manacher求出每个位置的半径,相加即可. 代码:[rad[i]/2]即i这个位置的回文半径,添加的'#'代表长度为偶数的串. #include<stdio.h> #inclu ...