centos 3.10.0 内核使用 rpmbuild 进行编译,rpmbuild 目录中的子目录信息如下:
BUILD BUILDROOT RPMS SOURCES SPECS SRPMS
SOURCES 目录下存放 centos 内核代码与不同平台的 config 文件。进入到 SOURCES 目录中查看 config 配置信息,有如下输出:
[longyu@localhost SOURCES]$ ls *.config
cpupower.config kernel-3.10.0-ppc64le.config kernel-3.10.0-s390x-debug.config kernel-3.10.0-x86_64-debug.config
kernel-3.10.0-ppc64.config kernel-3.10.0-ppc64le-debug.config kernel-3.10.0-s390x-kdump.config
kernel-3.10.0-ppc64-debug.config kernel-3.10.0-s390x.config kernel-3.10.0-x86_64.config
合入三方代码到内核源码树中
因产品需要使用三方内核模块,单独编译不便于管理,故考虑将这些模块合入到内核源码树中,与其它内核模块统一发布。
为了区别合入的模块代码与其它内核源码,我选择在内核源码根目录中创建 third_party 目录,将三方模块的代码都放到这个目录的子目录中。
合入后的目录结构如下:
[longyu@localhost linux-3.10.0]$ ls -lR ./third_party/
./third_party/:
total 12
-rw-rw-r-- 1 longyu longyu 84 Aug 6 15:50 Kconfig
-rw-rw-r-- 1 longyu longyu 100 Aug 6 15:50 Makefile
drwxrwxr-x 5 longyu longyu 4096 Aug 6 15:50 cryptography_module
./third_party/cryptography_module:
total 20
-rw-rw-r-- 1 longyu longyu 1310 Aug 6 15:50 Kconfig
-rw-rw-r-- 1 longyu longyu 150 Aug 6 15:50 Makefile
drwxrwxr-x 2 longyu longyu 4096 Aug 6 15:50 cryptone
drwxrwxr-x 2 longyu longyu 4096 Aug 6 15:50 crypttwo
drwxrwxr-x 2 longyu longyu 4096 Aug 6 15:50 cryptthree
./third_party/cryptography_module/:
total 8
-rw-rw-r-- 1 longyu longyu 90 Aug 6 15:50 Makefile
-rw-rw-r-- 1 longyu longyu 2213 Aug 6 15:50 cryptone.c
./third_party/cryptography_module/cryptthree:
total 8
-rw-rw-r-- 1 longyu longyu 90 Aug 6 15:50 Makefile
-rw-rw-r-- 1 longyu longyu 2131 Aug 6 15:50 cryptthree.c
./third_party/cryptography_module/crypttwo:
total 8
-rw-rw-r-- 1 longyu longyu 90 Aug 6 15:50 Makefile
-rw-rw-r-- 1 longyu longyu 2213 Aug 6 15:50 crypttwo.c
可以看到除了最里面的源码目录中没有 Kconfig 外,其它的目录中都有一个 Kconfig 与 Makefile。第一层的 Kconfig 文件内容与 Makefile 内容如下:
[longyu@localhost linux-3.10.0]$ cat ./third_party/Kconfig
menu "Third Party Module"
source "third_party/cryptography/Kconfig"
endmenu
[longyu@localhost linux-3.10.0]$ cat ./third_party/Makefile
#
# Makefile for the third party module
#
obj-$(CONFIG_STATE_CRYPTOGRAPHY) += cryptography/
第一层的 Kconfig 配置调用子目录 cryptography 中的 Kconfig,cryptography 中的 Kconfig 文件内容如下:
#
# cryptone crypttwo cryptthree algo configuration
#
menuconfig CRYPTOGRAPHY
default n
bool "cryptography"
---help---
if CRYPTOGRAPHY
config THIRD_PARTY_CRYPTONE
tristate "cryptone algorithm"
default m
---help---
cryptone modules
config THIRD_PARTY_CRYPTTOW
tristate "crypttwo algorithm"
default m
---help---
crypttwo module
config THIRD_PARTY_CRYPTTHREE
tristate "cryptthree algorithm"
default m
---help---
cryptthree module
endif
Makefile 文件也要逐层添加,并依赖 Kconfig 文件中的配置 CONFIG_xxx 配置项目进行配置。完成了 third_party 目录中 Kconfig 与 Makefile 文件的构建后,还需要修改内核源码顶层的 Makefile 与 arch 中不同架构子目录中的 Kconfig 文件。
顶层 Makefile 修改内容如下:
# Objects we will link into vmlinux / subdirs we need to visit
init-y := init/
drivers-y := drivers/ sound/ firmware/ third_party/
net-y := net/
libs-y := lib/
core-y := usr/
virt-y := virt/
在 drivers-y 中添加了一个 third_party/ 目录。由于我只需要编译 x86 的版本, 我只修改 arch/x86/Kconfig 文件。在 arch/x86/Kconfig 中添加如下行:
source "third_party/Kconfig"
完成了这两个步骤后 make menuconfig 能够看到相应的配置项目,修改 .config 文件后直接 make 进行编译,相关的模块能够正常编译。
config 文件的第一行
拷贝内核源码中的 .config 文件,覆盖旧的 x86_64 config 文件,重新执行 rpmbuild 却发现会报错。根据报错信息看应该是没有找到 ARCH 变量内容。
研究了下,发现 centos 标准内核 config 文件的写法与一般的 config 文件有所区别。它需要在 config 文件的第一行添加
# ARCHNAME
rpmbuild 在编译时会使用 cut -c 来从这一行取得 ARCH 的值。我使用 make menuconfig 生成的 .config 第一行并没有这样写,拷贝此 config 文件覆盖旧的 config 后获取 ARCH 的值失败,从而导致编译失败。
SOURCES 目录中现有的 config 文件第一行的内容截取如下:
[longyu@localhost SOURCES]$ head -n 1 *.config
==> cpupower.config <==
# See 'cpupower help' and cpupower(1) for more info
==> kernel-3.10.0-ppc64.config <==
# powerpc
==> kernel-3.10.0-ppc64-debug.config <==
# powerpc
==> kernel-3.10.0-ppc64le.config <==
# powerpc
==> kernel-3.10.0-ppc64le-debug.config <==
# powerpc
==> kernel-3.10.0-s390x.config <==
# s390
==> kernel-3.10.0-s390x-debug.config <==
# s390
==> kernel-3.10.0-s390x-kdump.config <==
# s390
==> kernel-3.10.0-x86_64.config <==
# x86_64
==> kernel-3.10.0-x86_64-debug.config <==
# x86_64
我在修改后的 config 文件的第一行添加 # x86_64 这一行,重新用 rpmbuild 进行编译,这次编译正常了。
最后找到与这个问题相关的编译命令如下:
+ mv kernel-3.10.0-x86_64-debug.config .config
++ head -1 .config
++ cut -b 3-
+ Arch=x86_64
+ make ARCH=x86_64 listnewconfig
这是 centos 标准内核的 config 文件与其它内核 config 文件的区别之处,第一次搞不免被整的手忙脚乱。