声明
以下都是我刚开始看驱动视频的个人强行解读,如果有误请指出,共同进步。
本节目标
- 学会仿写注册设备
正文
学习Linux,很大程度上感觉就是学习各种各样的API和思想。
上一节有提到过,我们注册设备的时候需要用到一个结构体platform_device,里面存放了name,id等信息。这个结构体在头文件platform_device.h里,我们打开看看:
vim include/linux/platform_device.h
一进来就看到结构体的定义
struct platform_device {
const char * name;
int id;
struct device dev;
u32 num_resources;
struct resource * resource;
const struct platform_device_id *id_entry;
/* MFD cell pointer */
struct mfd_cell *mfd_cell;
/* arch specific additions */
struct pdev_archdata archdata;
};
看着结构体里的参数很多,实际上本节我们只用name和id这两个参数。
我们之前提到过两个概念,一个是设备和驱动的匹配,另一个是主次设备号。设备和驱动的匹配,就是根据结构体中的name来匹配的,name一致,则匹配成功。
匹配成功的设备并不是具体指某一个设备,而是指一类设备(就像主设备号和次设备号的概念),本节只是简单的注册,所以这一类设备里只放一个设备,那么主设备号就可以直接指向这一个具体的设备了。对于一类里只有一个设备的情况,我们把id设置为-1,表示这一类设备只有一个设备(因为设备号是0-255,0和255系统保留不使用,填0不允许,填整数表示肯定还有其他的设备,所以设置-1表示只有一个设备是比较合理的)。
对于注册设备而言,有这么几个步骤
- 编写一个设备的结构体
- 把结构体存入数组,编译进内核
现在开始注册设备
我们先要打开平台文件,里面写着注册设备的代码。而平台文件全部在 arch下,我们用的是arm芯片,4412属于三星mach-exynos,平台文件是迅为写好的,名字叫mach-itop4412.c,所以打开:
vim arch/arm/mach-exynos/mach-itop4412.c
1. 编写注册设备的结构体
打开之后,显然不用我们自己造轮子,找一个已有的拿来改就行了,以leds为例,就在leds下面仿照着写一个吧,我起的名字也与迅为的不一样,迅为的宏定义是CONFIG_HELLO_CTL,我的叫CONFIG_MRYANG_CTL。
(这里的宏定义CONFIG_MRYANG_CTL源自笔记2仿写Kconfig的时候写的)
#ifdef CONFIG_MRYANG_CTL
struct platform_device s3c_device_mryang_ctl = {
.name = "mryang_ctl",
.id = -1,
};
#endif
2. 把结构体存入数组,编译进内核
不知道大家还记不记得,我们之前提到过强制编译和条件编译长什么样,我们之前做的都类似是个开关(Kconfig是图形界面开关,这里是定义了这个结构体),你编译勾选了也没用,因为他们根本没联系起来,而我们要把他们联系起来,肯定是要用C语言的条件编译的,我们继续在这个文件中搜索leds
#ifdef CONFIG_LEDS_CTL
&s3c_device_leds_ctl,
#endif
其实这就很清楚了,定义了CONFIG_LEDS_CTL,就传参这个结构体,为了让我们写的也生效,我们把这里也要仿写一下。
#ifdef CONFIG_MRYANG_CTL
&s3c_device_mryang_ctl,
#endif
然后保存退出就可以进行下一步了
为了保证正确,我们还是回过头检查一下之前我们定义的宏定义吧
vim drivers/char/Kconfig
搜索我定义的宏定义的关键词 MRYANG
啥?没搜到?那就搜一下LEDS,因为我们就是照着LEDS仿写的,搜到了,我之前定义了忘记保存了,难怪没搜到,重新补上吧…
config MRYANG_CTL
bool "Enable MRYANG config"
default y
help
Study Kconfig
因为我是仿写的,所以我写的就跟着LEDS后面,其实在哪都行。记得保存!!!
仿写结构体和宏变量完成,准备编译
我们查看一下图形界面,我们写的是否被选中编译进内核
make menuconfig
还是老地方,Device Drivers/Character devices 下(再次说明:因为我们是仿照字符设备LED写的,所以在这)
检查 Enable MRYANG config 前面确实有个星号,表示被编译进内核,那么就开始编译吧!
make zImage
我在 make zImage 的时候有提示问我 Enable MRYANG config (MRYANG_CTL) [Y/n/?] (NEW) ,我在后面输入了个y回车,表示确定编译进内核。
我去 怎么报错了,仔细一看,原来是定义结构体platform_device的s3c_device_mryang_ctl最后少了个 ; 号(上面已重新添加),这错误犯的真2…
修改之后 编译完成
生成的zImage路径是 /arch/arm/boot下,以后就不再叙述了
把编译生成的zImage烧写进板子
我们用命令查看虚拟总线platform是否挂载了我们仿写的驱动
ls /sys/devices/platform
果然看到了我们编写的 mryang_ctl (第一列倒数第7个)
当然,你也可以直接用 ls sys/devices/platform |grep mryang,免得显示这么多。
[root@iTOP-4412]# ls sys/devices/platform |grep mryang
mryang_ctl
至此,我们已经成功注册了设备,名字name叫 mryang_ctl,因为只有一个没有重名,所以id是-1。(文章开头定义结构体的时候写的)