我想要在Linux下驱动摄像头ov5640,使用的SoC是NXP的IMX6ULL,内核版本4.1.15。我想要一个比较纯净的嵌入Linux环境,所以打算自己裁剪和移植uboot+linux内核+rootfs。
在配置内核以后的编译过程中出现了问题,我配置内核的步骤如下:
一、使用NXP提供的Linux内核,make clean清理了一下工程,然后使用其默认的配置文件imx_v7_mfg_defconfig来生成.config文件。
二、make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig对内核进行个性化配置,我使用的是csi接口的ov5640,所以主要配置的选项是Device Driver选项中的v4l设备驱动的相关内容。
三、配置完成后,make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j6进行内核的编译,编译过程报错如下:
我配置内核V4L驱动的情况如图:
如果按照默认的配置文件,不去配置V4L的相关驱动,就能顺利编译通过;只要配置了V4L就报上图错误。
网上嵌入式Linux内核编译配置编译报错的帖子不多,由于硬件平台,内核版本的不同,和自己遇到的错误相关的帖子就更少了。经过长时间的踩坑摸索,报这种错的原因主要有两个:
1.报错的函数或者变量本身没有使用EXPORT_SYMBOL进行符号导出,所以在链接过程中就会找不到相应的函数和变量而报未定义的引用这种错误。
2.配置内核过程中自己配置的有些选项有它自己的依赖选项,这些依赖选项没有选上,导致报错。
所以首先去查找这些报错函数是否进行了符号导出。进入内核源码的顶层目录,使用grep命令进行查找,以这一条报错信息为例:
使用命令: grep -rnR “mipi_csi2_get_info” * ,得到如下信息:
可以看到该函数已经用进行了导出,其他函数也一样,所以排除这个原因。
那么现在排查第二个原因,排查这个原因有技巧,还是以“mipi_csi2_get_info”这个函数为例,按照如下的步骤排查:
第一,使用命令:grep -rnR “mipi_csi2_get_info” *,查找到该函数的定义源文件在drivers/mxc/mipi目录下。
第二,进入目录,使用命令 vim Makefile,查看哪个变量控制该源文件的编译,如图:
可以看到是否编译该文件由变量CONFIG_MXC_MIPI_CSI2控制其编译与否。
第三,在该目录下使用命令 vim Kconfig查看在Linux内核的编译选项中对应的选项:
可以看到,在内核的menuconfig中,该编译选项在目录MXC MIPI Support下,默认是n,不编译。至此,我们找到了问题所在,就是因为之前我们自己配置的编译选项依赖这个选项,而这个选项没默认是不编译的,因此我们在配置内核时把这个选项设置成y即可解决报错问题。如图:
至此问题得到了解决,内核可以成功编译。