今天做到如何自己编写第一个Helloworld驱动,结果遇到一些问题。。可是花了一个晚上,找遍了论坛的帖子,还是没有找到一个清楚明白的解决方案。
这里就先小小的抱怨一下吧。呵呵
不过,在经过其它地方查找资料之后,总算解决了这些问题。现在就先总结一下,希望后面大家再遇到类似问题的时候,可以少走弯路,有所收获吧
第一点、如果输入make modules后,发现没有编译出相应的xxx.ko文件,请看
解决方法:如何把设备驱动文件添加到Linux内核编译选项配置的menuconfig中
【目的】
把一个字符设备驱动文件,添加到内核中,希望编译成模块,而非build-in。
【参考资料】
内核的源码树目录下一般都会有两个文件:Kconfig和Makefile。
http://blog.sina.com.cn/s/blog_4a377e150100c896.html
【具体步骤】
1.首先保证已经有驱动源文件了:as352x_afe_charger.c
放在和其他你所要添加的模块放在一个目录下,此处是drivers\i2c\chips下。
2.在drivers\i2c\chips\makefile中,添加:
obj-$(CONFIG_AS352X_AFE_CHG) += as352x_afe_charger.o
3.在drivers\i2c\chips\Kconfig
中,添加如下内容:
----------------------------------------------
config AS352X_AFE_CHG
tristate "AS352X AFE Charger Driver"
depends on I2C_AS352X && AS352X_AFE
help
If you say yes here you get support for AS352X AFE Charger.
This driver can also be built as a module. If so, the module
will be called AS352X AFE Charger.
----------------------------------------------
解释如下:
(1)AS352X_AFE_CHG是自己定义的名字,当然要尽量保证有意义。
同时,你会注意到,在上面的makefile中添加的
obj-$(CONFIG_AS352X_AFE_CHG) += as352x_afe_charger.o
中的CONFIG_AS352X_AFE_CHG,是CONFIG_加上我们在kconfig下写的config变量。
这两个要匹配,才能实现你在menconfig定义的结果,传递到makefile中,
以便决定编译的时候是如何编译:不编译/编译进内核/编译成模块
(2)tristate 表示我此处添加的模块,可以
在make ARCH=arm menuconfig中看到的,选择之后:
* 编译到内核中
M 编译成模块,即生成XXX.ko
不选中,就不编译该文件
(3)depends on I2C_AS352X && AS352X_AFE
是前面自己找到的,表示此编译选项只有当I2C_AS352X 和AS352X_AFE都选中,才会出现。
当然,如果此模块不依赖于其他模块,则不需要加上这个depends on了。
【附录】
1.如果设置成M,module模式,则要用
make ARCH=arm
编译出as352x_afe_charger.ko
而
make ARCH=arm uImage
只能编译内核,而不编译模块。
第二点、好了,现在相信大家已经可以进行编译工作了。但是,这时候,可能大家还会遇上诸如这样的错误
drivers/char/EmbedSky_hello.c:12:32: error: asm/arch/regs-gpio.h: No such file or directory
[root@localhost linux-2.6.30.4]# clear
[root@localhost linux-2.6.30.4]# ky_hello.o] Error 1
make[1]: *** [drivers/char] Error 2
make: *** [drivers] Error 2
这是因为,
对于Linux2.6.25.8的内核,这三个头文件存放的路径是
#include <asm/irqs.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
但是,对于Linux2.6.30.4的内核,它的存放路径在
#include <mach/irqs.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
因此,需要这样修改一下。。
写到这里,也许大家会说,那不如,直接把它注释掉就好了嘛,这个方法可以,但是,它不是解决问题的根本方法。
最后,这几份文件到底真正的存放在哪里的,这里以我的Linux2.6.30.4的内核为例,他是实际存放在
Linux2.6.30.4/arch/arm/mach-s3c2410/include/mach/hardware.h中
这样,以后我们在写驱动时,就知道他调用的头文件实际存放在哪里了,这样就可以举一反三的解决问题了。。。
好了,这是我的简单总结,作抛砖引玉之用,如果大家还有什么不同的见解,或者新的地方,欢迎继续补充!!!
不过,在经过其它地方查找资料之后,总算解决了这些问题。现在就先总结一下,希望后面大家再遇到类似问题的时候,可以少走弯路,有所收获吧
第一点、如果输入make modules后,发现没有编译出相应的xxx.ko文件,请看
解决方法:如何把设备驱动文件添加到Linux内核编译选项配置的menuconfig中
【目的】
把一个字符设备驱动文件,添加到内核中,希望编译成模块,而非build-in。
【参考资料】
内核的源码树目录下一般都会有两个文件:Kconfig和Makefile。
http://blog.sina.com.cn/s/blog_4a377e150100c896.html
【具体步骤】
1.首先保证已经有驱动源文件了:as352x_afe_charger.c
放在和其他你所要添加的模块放在一个目录下,此处是drivers\i2c\chips下。
2.在drivers\i2c\chips\makefile中,添加:
obj-$(CONFIG_AS352X_AFE_CHG) += as352x_afe_charger.o
3.在drivers\i2c\chips\Kconfig
中,添加如下内容:
----------------------------------------------
config AS352X_AFE_CHG
tristate "AS352X AFE Charger Driver"
depends on I2C_AS352X && AS352X_AFE
help
If you say yes here you get support for AS352X AFE Charger.
This driver can also be built as a module. If so, the module
will be called AS352X AFE Charger.
----------------------------------------------
解释如下:
(1)AS352X_AFE_CHG是自己定义的名字,当然要尽量保证有意义。
同时,你会注意到,在上面的makefile中添加的
obj-$(CONFIG_AS352X_AFE_CHG) += as352x_afe_charger.o
中的CONFIG_AS352X_AFE_CHG,是CONFIG_加上我们在kconfig下写的config变量。
这两个要匹配,才能实现你在menconfig定义的结果,传递到makefile中,
以便决定编译的时候是如何编译:不编译/编译进内核/编译成模块
(2)tristate 表示我此处添加的模块,可以
在make ARCH=arm menuconfig中看到的,选择之后:
* 编译到内核中
M 编译成模块,即生成XXX.ko
不选中,就不编译该文件
(3)depends on I2C_AS352X && AS352X_AFE
是前面自己找到的,表示此编译选项只有当I2C_AS352X 和AS352X_AFE都选中,才会出现。
当然,如果此模块不依赖于其他模块,则不需要加上这个depends on了。
【附录】
1.如果设置成M,module模式,则要用
make ARCH=arm
编译出as352x_afe_charger.ko
而
make ARCH=arm uImage
只能编译内核,而不编译模块。
第二点、好了,现在相信大家已经可以进行编译工作了。但是,这时候,可能大家还会遇上诸如这样的错误
drivers/char/EmbedSky_hello.c:12:32: error: asm/arch/regs-gpio.h: No such file or directory
[root@localhost linux-2.6.30.4]# clear
[root@localhost linux-2.6.30.4]# ky_hello.o] Error 1
make[1]: *** [drivers/char] Error 2
make: *** [drivers] Error 2
这是因为,
对于Linux2.6.25.8的内核,这三个头文件存放的路径是
#include <asm/irqs.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
但是,对于Linux2.6.30.4的内核,它的存放路径在
#include <mach/irqs.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
因此,需要这样修改一下。。
写到这里,也许大家会说,那不如,直接把它注释掉就好了嘛,这个方法可以,但是,它不是解决问题的根本方法。
最后,这几份文件到底真正的存放在哪里的,这里以我的Linux2.6.30.4的内核为例,他是实际存放在
Linux2.6.30.4/arch/arm/mach-s3c2410/include/mach/hardware.h中
这样,以后我们在写驱动时,就知道他调用的头文件实际存放在哪里了,这样就可以举一反三的解决问题了。。。
好了,这是我的简单总结,作抛砖引玉之用,如果大家还有什么不同的见解,或者新的地方,欢迎继续补充!!!