课程:信息安全系统设计基础
班级:1452 1453
姓名:黄志远 王亦徐
学号:20145211 20145311
实验日期:2016.11.24node实验时间:10:10-12:25linux
实验名称:外设驱动程序设计安全
实验目的与要求:markdown
1.掌握实时系统应用和驱动程序的编写
2.选择某个接口电路框架实验仪器:函数
实验仪器 型号 数量 计算机 Lenovo 1 虚拟Linux环境 Redhat 9.0 1 Arm开发板 UP-NETARM2410-CL 1
#define DEVICE_NAME "demo" static ssize_t demo_write(struct file *filp,const char * buffer, size_t count) { char drv_buf[]; copy_from_user(drv_buf , buffer, count); … } static ssize_t demo_read(struct file *filp,char *buffer,size_t count,loff_t *ppos) { char drv_buf[]; copy_to_user(buffer, drv_buf,count); …. } static int demo_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg) { } static int demo_open(struct inode *inode, struct file *file) { } static int demo_release(struct inode *inode, struct file *filp) { MOD_DEC_USE_COUNT; DPRINTK("device release\n"); return 0; } static struct file_operations demo_fops = { owner: THIS_MODULE, write:demo_write, read: demo_read, ioctl: demo_ioctl, open: demo_open, release:demo_release, }; #ifdef CONFIG_DEVFS_FS static devfs_handle_t devfs_demo_dir, devfs_demoraw; #endif static int __init demo_init(void) { int result; #ifdef CONFIG_DEVFS_FS devfs_demo_dir = devfs_mk_dir(NULL, "demo", NULL); devfs_demoraw = devfs_register(devfs_demo_dir, "0", DEVFS_FL_DEFAULT, demo_Major, demo_MINOR, S_IFCHR | S_IRUSR | S_IWUSR,&demo_fops, NULL); #else SET_MODULE_OWNER(&demo_fops); result = register_chrdev(demo_Major, "scullc", &demo_fops); if (result < 0) return result; if (demo_Major == 0) demo_Major = result; /* dynamic */ #endif printk(DEVICE_NAME " initialized\n"); return 0; } static void __exit demo_exit(void) { unregister_chrdev(demo_major, "demo"); kfree(demo_devices); printk(DEVICE_NAME " unloaded\n"); } module_init(demo_init); module_exit(demo_exit);
Open 方法提供给驱动程序初始化设备的能力,从而为之后的设备操做作好准备,此外open操做通常还会递增使用计数,用以防止文件关闭前模块被卸载出内核。测试
- 递增使用计数 - 检查特定设备错误。 - 若是设备是首次打开,则对其进行初始化。 - 识别次设备号,若有必要修改 f_op 指针。 - 分配并填写 filp->private_data 中的数据。
与 open 方法相反,release 方法应完成以下功能:ui
- 释放由 open 分配的 filp->private_data 中的全部内容 - 在最后一次关闭操做时关闭设备 - 使用计数减一
ssize_t demo_write(struct file *filp,const char * buffer, size_t count,loff_t *ppos) ssize_t demo_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
因为用户空间和内核空间的内存映射方式彻底不一样,因此不能使用象 memcpy 之类的函数,
必须使用以下函数:spa
unsigned long copy_to_user (void *to,const void *from,unsigned long count); unsigned long copy_from_user(void *to,const void *from,unsigned long count);
中断处理程序与普通C代码没有太大不一样,不一样的是中断处理程序在中断期间运行,它有以下限制:debug
不能向用户空间发送或接受数据 不能执行有睡眠操做的函数 不能调用调度函数
上面介绍了在 Makefile 中有两种编译方法,能够在本机上使用 gcc 也可使用交叉编译器进行编译,这里咱们只介绍用交叉编译器进行编译的结果。
注意:若是编译的时候出现问题,多是在/usr/src 下没有创建一个 linux 链接,可使用下面的命令:
[root@zxt 01_demo]# cd /usr/src/ [root@zxt src]# ln –sf linux-2.4.20-8 linux [root@zxt src]# ls debug linux linux-2.4 linux-2.4.20-8 redha
附:
- ln指令的用法是链接,使用格式是ln [options] source dist,这里咱们用到的sf参数的含义是:
-f:连接时先将与dist同档名的档案删除 -s:进行软连接。(软连接,又称符号连接,这个文件包含了另外一个文件的路径名,特色是能够连接不一样文件系统的文件,甚至能够连接不存在的文件。)
若是使用 gcc 编译的话,须要经过下面的命令来创建设备节点,若是使用交叉编译器的话,不须要创建设备节点。
#mknod /dev/demo c 254 0
能够用 lsmod 命令来查看模块是否已经被插入,在不使用该模块的时候还能够用 rmmod 命令来将模块卸载。
[root@zxt 01_demo]# insmod demo.o Warning: loading demo.o will taint the kernel: no license See http://www.tux.org/lkml/#export-tainted for information about tainted modules Module demo loaded, with warnings
- 成功后会出现下面的结果:
若是模块没有成功插入的话,会出现下面的状况: [root@zxt 01_demo]# ./test_demo ####DEMO device open fail####
在驱动模块成功插入后,会在/dev 下面创建一个叫作 demo 的设备文件,咱们也可使用 cat 命令来直接调用 read 函数,来测试读过程。 [root@zxt demo]# cat /dev/demo/0 device open success!
makefile中两行宏变量定义用于使用armv4l-unknown-linux-gcc编译器编译驱动:
#KERNELDIR = /arm2410cl/ kernel/linux-2.4.18-2410cl/ #CROSS_COMPILE= armv4l-unknown-linux-
因为makefile文件中KERNEL_PATH设置和真实环境有点不一样,修改makefile文件中的路径就行了。
修改后:
KERNELDIR = /usr/src/linux #KERNELDIR = /arm2410cl/ kernel/linux-2.4.18-2410cl/ INCLUDEDIR = $(KERNELDIR)/include #CROSS_COMPILE=armv41-unknown-linux-
编译经过:

此次实验咱们尝试了不少遍。一开始配置环境时一路顺风让咱们小小的得意了一下。可是后面当咱们好不容易能够编译驱动又怎么也make不出来。在多方研究下,咱们发现makefile有问题,与实验书中不一样。因而咱们俩人配合,将makefile用按照实验书中一个个修改了路径。才使得编译成功。以后,咱们用gcc测试,又发现没有创建节点。创建好节点以后,insmod一下才终于能够运行。这一次实验,出现问题之后,咱们没有互相埋怨,而是不断努力寻找问题缘由,询问同窗。在改makefile时也体现了团队合做的默契度。最终成功完成了实验四的内容。