IMX257实现Ramblock驱动程序编写

发布时间:2024-08-13  

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


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


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

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.png3挂载文件系统到/mnt/blk/上

1dc20a1b19fc6f86fcbb4d25b898d06f_151502157296094.png

4读写测试:


建立一个hello.c文件

 

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

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    动离线裸片式烧录到全自动在板在线式烧录等全场景的需求,支持Nor/Nand Flash、eMMC、UFS、MCU、FPGA、CPLD等各种可编程器件。目前昂科技术已开发支持100多家全球头部半导体厂家的数万种可编程器件。 对于......
    迈斯威志编程器更新支持极海半导体的​APM32F405/407系列; 【导读】APM32F405/407系列MCU,基于Arm®Cortex®-M4内核,全面兼顾高运算、高实时、易用......
    要使用一些特殊设备,接入汽车OBD接口,一番简单操作即可,几乎0成本,有些车就麻烦点,需要拆车把仪表取下,然后将EEPROM焊下来,放到专用的编程器里面调整好再焊回车上。 对于宝马这个品牌的汽车来说,不敢......
    RTL8139如何改制AT89C51编程器;  想玩89C51,但没有编程器,于是便想自制编程器,找了很多自制的资料,大多都是使用89C51做控制逻辑,需要有编程器才能制作,电路一般也比较复杂(最......
    Microchip发布升级版编程器和调试器开发工具; 【导读】对于嵌入式设计人员来说,编程和调试仍然是至关重要的,但人工操作耗时较长,Microchip Technology Inc......
    Microchip发布升级版编程器和调试器开发工具;新一代MPLAB® ICD 5和MPLAB® PICkit™ 5在线调试器/编程器提供了全新的编程和 连接方式 对于嵌入式设计人员来说,编程......
    Microchip发布升级版编程器和调试器开发工具;新一代MPLAB® ICD 5和MPLAB® PICkit™ 5在线调试器/编程器提供了全新的编程和连接方式对于嵌入式设计人员来说,编程......
    PLC的结构及各部分的作用;可编程控制器的结构多种多样,但其组成的一般原理基本相同,都是以微处理器为核心的结构。通常由中央处理单元(CPU)、存储器(RAM、ROM)、输入输出单元(I/O)、电源和编程器......
    统程序赋予的功能,接收并存储从编程器键入的用户程序和数据;用扫描方式查询现场输入装置的各种信号状态或数据,并存入输入过程状态寄存器或数据寄存器中;诊断电源及PLC内部电路工作状态和编程......
    该根据系统的大小合理选用PLC产品。 4、编程器的选购PLC编程可采用三种方式: 是用一般的手持编程器编程,它只能用商家规定语句表中的语句编程。这种方式效率低,但对于系统容量小,用量......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>