IMX257实现Ramblock驱动程序编写

发布者:HeavenlyWhisper最新更新时间:2024-08-13 来源: cnblogs关键字:驱动程序 手机看文章 扫描二维码
随时随地手机看文章

今天,我们再内存中申请一片内存,模拟作为块设备,程序如下:


程序一:简单的一个小程序


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模块

e5dfefd8f5f66f016894127ead1a43a4_151448291513652.png?imageView2/2/w/550

2.5编译安装


配置好之后,运行编译命令:make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-


安装入文件系统:make install

2.6 利用busybox的命令格式化


不必挂载文件系统,只需要利用nfs进入busybox创建的文件系统中,拷贝格式化的mkfs命令到/sbin/下,然后就可以开始格式化了

2.6.1格式化文件系统

f76501e31a125a8a00deafc29d573c59_151448421206657.png?imageView2/2/w/5503挂载文件系统到/mnt/blk/上

1dc20a1b19fc6f86fcbb4d25b898d06f_151502157296094.png?imageView2/2/w/550

4读写测试:


建立一个hello.c文件

 

5退出/mnt/blk/目录之后,卸载/mnt/blk/,运行sync是为了同步读写,防止设备忙

[1] [2] [3] [4] [5]
关键字:驱动程序 引用地址:IMX257实现Ramblock驱动程序编写

上一篇:S3C2440 nor_flash驱动程序
下一篇:LRF020 DRIVER FOR LINUX(BASED ON TQ2440/ARM9)

推荐阅读最新更新时间:2026-03-12 05:08

IMX257 BEEP驱动程序实现
1.确定相关寄存器基址 确定IOMUX地址 0x43fa_c000 0x43fa_ffff GPIO1的地址 0x53fc_c000 0x53fc_ffff MUX_CTL寄存器偏移地址 0x011c PAD-CTL 寄存器偏移 0x0314 GPIO寄存器偏移地址 2.编译测试 本驱动程序亲测成功: 附上驱动程序代码: 1 #include linux/cdev.h 2 #include linux/module.h 3 #include linux/types.h 4 #include linux/fs.h 5 #include linux/errno.h 6 #in
[单片机]
<font color='red'>IMX257</font> BEEP<font color='red'>驱动程序</font>实现
IMX257 linux设备驱动之Cdev结构
一、CDEV结构 /* *内核源码位置 *linux2.6.38/include/linux/cdev.h */ struct cdev { struct kobject kobj; struct module *owner; //一般初始化为:THIS_MODULE const struct file_operations *ops; //字符设备用到的例外一个重要的结构体file_operations,cdev初始化时与之绑定 struct list_head list; dev_t dev; //主设备号24位 与次设备号8位,dev_t为32
[单片机]
<font color='red'>IMX257</font> linux设备驱动之Cdev结构
IMX257 总线设备驱动模型编程之总线篇
从现在开始,我们开始来实现 总线-设备-驱动模型中的总线。、 我们这个程序的目标是在 sysfs文件系统的/sys/bus/ 目录下面建立一个文件夹。 一、总线介绍 1. 总线数据结构bus_type struct bus_type 结构体的定义如下: struct bus_type { const char *name; --总线名 struct bus_attribute *bus_attrs; --总线属性 struct device_attribute *dev_attrs; --总线设备属性 struct driver_attribute *drv_attrs; --总线驱动属性 以下的函数会在设备注册或驱动注册
[单片机]
<font color='red'>IMX257</font> 总线设备驱动模型编程之总线篇
IMX257 总线设备驱动模型编程之总线篇(二)
前面我们讲解了一个简单的总线驱动程序,目的就是在/sys/bus/下面创建文件,但是这还是不够的,因为总线也是一个设备,如果想让系统认识的话,必须要用device_register进行注册。 此处,我们就开始来注册一个总线,让总线下即可以包含属性文件,也包含设备文件,和驱动程序。 让驱动程序 和设备文件之间互联,这才是总线真正的用途。 一、程序解析 前面已经将的很详细,我们这儿在前面的基础上加上一下: 1. 定义总体设备结构体 并且实现 设备的release函数; 2. 导出总线设备 3. 注册设备驱动 4. 卸载设备 二、编译测试: 加载成功后,因为总线也是一个设备,所以在 /sys/bu
[单片机]
<font color='red'>IMX257</font> 总线设备驱动模型编程之总线篇(二)
IMX257 总线设备驱动模型编程之设备篇
一、程序分析 1. 包含总线 既然我们的设备在总线上,自然我们既要包含总线了 如图所示,使用外部声明将我们的总线的结构体包含进来 2. 定义设备结构体 父目录为 my_bus 3. 定义属性文件结构体 属性文件结构体可以有一下得到: //产生后面的 bus_attr_version 结构体 static DEVICE_ATTR(dev,S_IRUGO,mydev_show,NULL); 如图所示: 4. 在初始化函数中 如图所示: 在初始化函数中, 先初始化设备的名字,这个名字用于于驱动名字进行匹配 然后注册设备,让系统认识这个设备,在/sys/device/my_bus0 下面就会有my_dev这个设备 最
[单片机]
<font color='red'>IMX257</font> 总线设备驱动模型编程之设备篇
STM32:打造高效且小巧的I2C驱动程序
在嵌入式系统开发中,STM32系列微控制器凭借其强大的性能和丰富的外设接口,成为了众多开发者的首选。其中,I2C(Inter-Integrated Circuit)接口作为一种常用的串行通信协议,广泛应用于各种传感器、存储器等外设的连接。本文旨在介绍如何为STM32设计一款高效且小巧的I2C驱动程序,以满足嵌入式系统中对资源利用和性能优化的双重需求。 一、STM32 I2C接口概述 STM32系列微控制器内置了多个I2C接口,如STM32F411CEx型号就配备了I2C1、I2C2和I2C3三个模块。这些模块支持7位和10位地址的发送与接收,能够生成100KHz、400KHz的时钟频率,并可在特定条件下提升至1MHz。ST
[单片机]
ARM架构处理器RTOS内核及驱动程序编写
随着计算机技术、通信技术、集成电路技术和控制技术的发展,传统的工业控制领域正经历着一场前所未有的变革,开始向网络化方向发展。本文即从未来工业控制网络发展的需要出发,设计并实现了以S3C2410微处理器为核心的嵌入式网络控制器。 本文以S3C2410—32位微处理为核心,设计并实现了具有1路以太网接口、1路USB Host接口、1路USB Device接口、3路RS232串口、1个CAN总线扩展卡、1个RS485扩展卡、1个RS422扩展卡使用、8路A/D、1路D/A、4路PWM、一个240×320TFT LCD显示触摸屏的功能强大的嵌入式网络控制器。并在此基础上,结合嵌入式操作系统Windows CE建立了一个嵌入式软件开发平台。
[单片机]
专题3-串口驱动程序设计-第2课串口驱动分析-初始化
1、概述 (1)串口驱动程序结构 (2)串口驱动中的重要数据结构体 用户态发生write时- VFS中的sys_write,先经过file_operation中的tty_write,这个tty_fops是在哪里注册的? 2、回溯-初始化分析 两个重要的文件: samsung.c:注册串口驱动程序 s5pv210.c (2)串口驱动中重要的数据结构: uart驱动程序结构:struct uart_driver --对应串口驱动 使用场景实例: static uart_driver s3c24xx_uart_ddrv = {   .owner = THIS_MODULE,   .dev_name= s3c2440_s
[单片机]
专题3-串口<font color='red'>驱动程序</font>设计-第2课串口驱动分析-初始化
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved