今天,我们再内存中申请一片内存,模拟作为块设备,程序如下:
程序一:简单的一个小程序
1.定义gendisk结构体与request_queue请求队列结构体,以及file-operation结构体
gendisk结构体,主要是用于定义与内核,硬件有关的一些重要信息,还有就是,告诉内核定义请求队列的结构体以及操作函数的结构体。
请求队列:主要是提供读写能力,实现读写请求的存储,然后自己调用do_rambloc_request函数来实现读写操作。
操作函数:如字符设备的操作函数一样,不过此处的操作函数暂时不需定义任何函数,但是必须要有.MODULE属性,否则会报错
2.入口函数实现
如图所示,在入口函数中主要包含了以下几个操作。
1):分般gendisk结构体,并且设备此设备个数为16个
2):分配、初始化队列,并且指定队列读写函数do_ramblock_request函数。
3):设置以下虚拟块设备的一些属性,包括主设备号,次设备号,名字,操作函数,队列,设备容量等。
4):最后就是注册gendisk结构体。
3.读写函数实现
一些都准备就绪之后,当用户对虚拟块设备发出请求时,系统会调用读写函数do_ramblock_request来实现读写功能。但是刚开始,还是简单点,所以此处,我们的函数主要的功能就是打印信息,告诉我们是否进入了这个读写函数。
4.出口函数实现
和入口函数相反,出口函数主要负责的就是释放前面申请的内存,反注册前面注册的一些信息。
5.程序测试
加载成功:
附上驱动程序ramblock1:
1 /* 参考
2 * driversblockxd.c
3 * driversblockz2ram.c
4 */
5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 #include 14 #include 15 #include 16 #include 17 #include 18 #include 19 #include 20 #include 21 22 #include 23 #include 24 #include 25 26 static struct gendisk *ramblock_disk; //定义gendisk结构体 27 static struct request_queue *ramblock_queue; //定义请求队列结构体 28 static DEFINE_SPINLOCK(ramblock_lock); //定义一个自旋锁 29 static int major; //主设备号 30 #define RAMBLOCK_SIZE (1024*1024) //块设备的容量 31 32 33 //file_operation结构体 34 static struct block_device_operations ramblock_fops ={ 35 .owner = THIS_MODULE, 36 }; 37 38 //读写处理函数 39 static void do_ramblock_request(struct request_queue *q) 40 { 41 static int cnt = 0; 42 struct request *req; 43 44 printk('enter do_ramblock_request %dn',++cnt); 45 46 req = blk_fetch_request(q); 47 while(req){ 48 printk('enter while req %dn',++cnt); 49 break; 50 } 51 52 __blk_end_request_cur(req, 0); 53 printk('leave do_ramblock_request %dn',++cnt); 54 } 55 56 static int ramblock_init(void) 57 { 58 printk('ramblock_initn'); 59 /* 1.分配一个gendisk结构体 */ 60 ramblock_disk = alloc_disk(16); //次设备号个数:分区个数,若为1的话,则意思是只有一个分区 61 62 /* 2.设置 */ 63 /* 2.1 分配/设置队列:函数do_ramblock_request提供读写能力 */ 64 ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock); 65 66 /* 2.2 设置其他属性:比如容量 */ 67 major = register_blkdev(0,'ramblock'); //cat /proc/device 动态申请一个主设备号 68 69 ramblock_disk->major = major; //主设备号 70 ramblock_disk->first_minor = 0; //第一个次设备号 71 sprintf(ramblock_disk->disk_name, 'ramblock'); 72 ramblock_disk->fops = &ramblock_fops; //操作函数 73 ramblock_disk->queue = ramblock_queue; //队列 74 set_capacity(ramblock_disk,RAMBLOCK_SIZE/512); //设置容量,以扇区为单位 75 76 /* 3.注册 */ 77 add_disk(ramblock_disk); 78 79 return 0; 80 } 81 82 static void ramblock_exit(void) 83 { 84 printk('ramblock_exitn'); 85 unregister_blkdev(major, 'ramblock'); //卸载主设备号 86 del_gendisk(ramblock_disk); 87 put_disk(ramblock_disk); 88 blk_cleanup_queue(ramblock_queue); 89 } 90 91 module_init(ramblock_init); 92 module_exit(ramblock_exit); 93 MODULE_LICENSE('GPL'); 程序二:增加读写方向,实现挂载等功能 接着前面实现的驱动程序,我们来在它的基础是来实现读写功能以及挂载等功能, 1.分配、释放申请内存 很明显,实现读写的话,那必要要有内存来存储,所以我们必须要入口函数中增加申请内粗的函数。 既然在入口函数中申请了内存,自然就要在出口函数中实现释放内存的操作。 2.在读写函数中实现读写操作。 由于2.6内核的改动,读写函数中的一些对象的名称有点不太一样,不过总体的思路还是一模一样的。参考内核中其他代码的读写函数, 1):实现引入请求队列,并且遍历请求队列 2):当请求队列为真的时候,计算出请求队列的起始地址及长度 3):通过其实地址和长度判读请求是否有效是否超出内存 4):如果以上都通过之后,接下来就是关键了,判断读写方向,接着实现内存的memcpy 5):读写成功后,调用__blk_end_request_cur来返回读写成功与否 3.程序测试 加载驱动: 读写测试: 4.往开发板中增加mkfs命令 接下来就是使用使用mkfs来格式化,但是发现imx257开发板自带的2.6内核里面没有mkfs的命令. 解决办法:使用busybox来创建一个根文件,然后从那个根文件系统中把mkfs命令拷贝到开发板的sbin目录下,就可以了,步骤如下: 1.首先下载busybox-1.23.1.tar.bz2 2.编译busybox 2.1配置busybox 执行命令:make menuconfig ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- Busybox Settings ---> //BusyBox的通用配置,一般采用默认值即可。 ---Applets Archival Utilities ---> //压缩、解压缩相关工具。 Coreutils ---> //最基本的命令,如cat、cp、ls等。 Console Utilities ---> //控制台相关命令。 Debian Utilities ---> //Debian操作系统相关命令。 Editors ---> //编辑工具,如vi、awk、sed等。 Finding Utilities ---> //查找工具,如find、grep、xargs。 Init Utilities ---> //BusyBox init相关命令。 Login/Password Management Utilities ---> //登陆、用户账号/密码等方面的命令。 Linux Ext2 FS Progs ---> //ext2文件系统的一些工具。 Linux Module Utilities ---> //加载/卸载模块等相关的命令。 Linux System Utilities ---> //一些系统命令。 Miscellaneous Utilities ---> //一些不好分类的命令,如crond、crontab。 Networking Utilities ---> //网络相关的命令和工具。 Print Utilities ---> //print spool服务及相关工具。 Mail Utilities ---> //mail相关命令。 Process Utilities ---> //进程相关命令,如ps、kill等。 Runit Utilities ---> //runit程序。 Shells ---> //shell程序。 System Logging Utilities ---> //系统日志相关工具,如syslogd、klogd。 2.2创建文件系统目录 2.2.1.创建文件系统的目录 1 #mkdir /home/study/nfs_home/rootfs_imx257/ 2 #cd /nfs_home/rootfs_imx25 3 #mkdir bin dev etc lib sbin proc sys var mnt tmp usr 4 #mkdir usr/bin usr/lib usr/sbin lib/modules 2.2.2.创建设备节点 #cd dev/ #mknod -m 666 console c 5 1 #mknod -m 666 null c 1 3 2.3配置选项 必须选中和修改的项: 1.'Build Busybox as a static binary(no share libs)' 2.'Don't use /usr' 3.'cross compiler prefix'--------->arm-none-linux-gnueabi- 4.'Busybox Installation prefix'--->/home/study/nfs_home/rootfs_imx257/ ****注意此处为你的文件系统目录的路径 (1选择的是静态连接库的方式,如果不选就是使用动态连接库的方式) (采用动态连接库的方式,在lib目录中添加应用程序所需的库文件) (Archival Utilities-->gzip这个选项一定不能掉) 找不到的话可以按下/进行搜索. 如图所示: 2.4错误解决 2.4.1错误一 root@Lover雪:/home/study/nfs_home/system/busybox-1.23.1# make CC miscutils/ubi_tools.o miscutils/ubi_tools.c:67:26: error: mtd/ubi-user.h: No such file or directory miscutils/ubi_tools.c: In function 'ubi_tools_main': miscutils/ubi_tools.c:106: error: 'UBI_DEV_NUM_AUTO' undeclared (first use in this function) miscutils/ubi_tools.c:106: error: (Each undeclared identifier is reported only once miscutils/ubi_tools.c:106: error: for each function it appears in.) miscutils/ubi_tools.c:107: error: 'UBI_VOL_NUM_AUTO' undeclared (first use in this function) miscutils/ubi_tools.c:114: error: field 'attach_req' has incomplete type miscutils/ubi_tools.c:115: error: field 'mkvol_req' has incomplete type miscutils/ubi_tools.c:116: error: field 'rsvol_req' has incomplete type miscutils/ubi_tools.c:177: error: 'UBI_IOCATT' undeclared (first use in this function) miscutils/ubi_tools.c:190: error: 'UBI_IOCDET' undeclared (first use in this function) miscutils/ubi_tools.c:233: error: 'UBI_DYNAMIC_VOLUME' undeclared (first use in this function) miscutils/ubi_tools.c:235: error: 'UBI_STATIC_VOLUME' undeclared (first use in this function) miscutils/ubi_tools.c:238: error: 'UBI_MAX_VOLUME_NAME' undeclared (first use in this function) miscutils/ubi_tools.c:243: error: 'UBI_IOCMKVOL' undeclared (first use in this function) miscutils/ubi_tools.c:256: error: 'UBI_IOCRMVOL' undeclared (first use in this function) miscutils/ubi_tools.c:274: error: 'UBI_IOCRSVOL' undeclared (first use in this function) miscutils/ubi_tools.c:290: error: 'UBI_IOCVOLUP' undeclared (first use in this function) scripts/Makefile.build:197: recipe for target 'miscutils/ubi_tools.o' failed make[1]: *** [miscutils/ubi_tools.o] Error 1 Makefile:741: recipe for target 'miscutils' failed make: *** [miscutils] Error 2 解决方法 拷贝linux内核中的ubi-user.h到busybox下的mtd目录中 mkdir ./include/mtd;cp ../linux-2.6.31/include/mtd/ubi-user.h ./include/mtd/ 2.4.2错误二: networking/udhcp/dhcpc.c: In function 'udhcp_recv_raw_packet': networking/udhcp/dhcpc.c:852: error: invalid application of 'sizeof' to incomplete type 'struct tpacket_auxdata' networking/udhcp/dhcpc.c:915: error: 'PACKET_AUXDATA' undeclared (first use in 解决方法:不要编译dhcp模块 2.5编译安装 配置好之后,运行编译命令:make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- 安装入文件系统:make install 2.6 利用busybox的命令格式化 不必挂载文件系统,只需要利用nfs进入busybox创建的文件系统中,拷贝格式化的mkfs命令到/sbin/下,然后就可以开始格式化了 2.6.1格式化文件系统 3挂载文件系统到/mnt/blk/上 4读写测试: 建立一个hello.c文件 5退出/mnt/blk/目录之后,卸载/mnt/blk/,运行sync是为了同步读写,防止设备忙
上一篇:S3C2440 nor_flash驱动程序
下一篇:LRF020 DRIVER FOR LINUX(BASED ON TQ2440/ARM9)
推荐阅读最新更新时间:2024-11-12 22:53
设计资源 培训 开发板 精华推荐
- 适用于工业应用的 C8051F911 MCU 的 C8051F912-DK、8051 开发系统
- LTC1265CS 演示板,高效降压型 DC/DC 转换器,5V@1A
- LTC2207 和 LTC6401-14 的组合演示板 (14dB)
- 具有基本抑制功能的 LF50ACP 5V 极低压降稳压器的典型应用
- 使用 Microchip Technology 的 TC28C47EPE 的参考设计
- 具有 2.5V LDO 输出的 LTC3633AEFE-1 3.3V/1.8V 降压稳压器的典型应用电路
- AM2G-4824DZ ±24V 2 瓦 DC-DC 转换器的典型应用,适用于开/关控制应用
- 智能平衡小车-蓝精灵
- AD7262、1 Msps、12 位、同步采样 SAR ADC 在控制寄存器模式下的典型应用,具有 PGA 和四个比较器
- 使用 Microchip Technology 的 MIC5326 的参考设计