在编译自己编写的Linux内核驱动模块之前,通常需要通过make menuconfig命令来配置内核驱动模块的编译方式,在Mac下调用该命令时可能会出现一些错误,这里记录一下相关错误与解决办法。
借着这个机会,顺便先介绍一下Linux内核的配置机制。
Linux内核配置系统组成
Linux内核配置系统由三个部分组成,分别是:
- Makefile: 分布在Linux内核源代码根目录及各层目录中,定义Linux内核的编译规则。
- 配置文件(.config、Kconfig等):给用户提供配置选择的功能
- 配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置用户界面(提供基于字符界面、基于Ncurses图形界面以及基于Xwindows图形界面的用户配置界面,分别对应于:make config、make menuconfig、make xconfig)。
make menuconfig过程
- 根据Linux内核根目录下的Makefile文件中设置的ARCH环境变量决定读取arch/$ARCH/目录下Kconfig文件生成整个配置界面选项。
- 默认的配置选项来自于arch/$ARCH/configs/目录下的某一文件,在编译Android内核时,曾使用过make goldfish_armv7_defconfig命令,该命令实际就是根据arch/$ARCH/configs/goldfish_armv7_defconfig(需要在执行编译前根据开发版的类型从configs文件夹中选择一个与开发板最接近的系列)来生成默认配置选项,并将其保存为Linux内核根目录下的.config文件,默认选项配置来自于各个文件夹下的Kconfig编译选项文件。
- 根据Linux根目录下的.config文件生成配置界面。
- 当在配置界面进行了一系列配置并保存配置后,系统会更新Linux根目录下的.config文件,同时将所有选项以宏的形式保存在Linux内核的include/generated/autoconf.h文件中,内核中的源代码会包含该头文件,并根据宏的定义情况进行条件编译。
编译关系的建立
编译关系是根据Makefile文件建立起来的,当需要编译一个文件时,需要修改对应的Makefile编译脚本文件。例如有以下Makefile文件:
obj-$(CONFIG_FREG)+=freg.o
当我们选择是否需要编译freg.c这个文件时,会根据Makefile文件中的CONFIG_FREG来决定是否编译此文件,CONFIGFREG为上小节中介绍到的生成的宏,该宏的名称来自于相应的Kconfig编译选项文件中的第一条语句config FREG,系统在生成该宏时会自动加上CONFIG前缀。当CONFIG_FREG为y或m时会进行编译,否则不进行编译。Makefile文件中+=右边的.o文件的文件名必须与需要编译的.c文件的文件名相同。
错误一
|
|
在编译Linux内核之前,使用图形界面来进行配置最为直观与方便,所以需要使用make menuconfig命令,实际上该命令是使用mconf这个工具去解析config文件里的描述信息,进而转换为图形界面。
在第一次执行make menuconfig时,需要先生成mconf这个工具,在预编译Linux内核scripts/kconfig/mconf.c生成scripts/kconfig/mconf.o之后的连接阶段,需要ldflags参数给出所需要连接的库的位置(在这里为后缀为.a、.so、.dylib的ncursesw、ncurses、curses库,因为配置图形界面需要使用方向键来选择选项,所以需要用到ncurses库,如果Mac上没有该库,可以通过命令:brew install homebrew/ncurses来安装 ),而生成ldflags参数的脚本为Linux内核scripts/kconfig/lxdialog/check-lxdialog.sh。
上面报错的原因在于Mac系统下ncursesw、ncurses、curses这些库文件的位置不能通过check-lxdialog.sh里的脚本命令得到,所以生成的ldflags不对,进而无法生成mconf工具。
该错误的解决办法为:
打开Linux内核scripts/kconfig/lxdialog/check-lxdialog.sh,将ldflags()修改为以下内容:
