在通过交叉编译的Debian GNU/Linux上进行设备驱动程序的自编译时需要注意的事项
首先在https://github.com/ikwzm/FPGA-SoC-Linux中,提供了针对Zynq(ARMv7+FPGA)的Debian GNU/Linux。该存储库中提供的Linux Kernel和Debian Package是在Ubuntu(x86-64)上进行交叉编译的。本文将讨论在尝试在目标系统上进行设备驱动程序自编译时遇到的问题和(暂时的)解决方法。
2019年10月17日 补充说明这里所解释的是针对 Linux Kernel 4.x 的情况。对于 Linux Kernel 5.x,需要另外一种方法。请参考以下文章获取更多详细信息。
「クロスコンパイルした Debian GNU/Linux でデバイスドライバをセルフコンパイルする際の注意点(Linux Kernel 5.x編)」@Qiita
安装标头包为了在目标上自行编译设备驱动程序,需要在目标上安装头文件包。在 https://github.com/ikwzm/FPGA-SoC-Linux 上,会提供像 linux-headers-4.14.21-armv7-fpga_4.14.21-armv7-fpga-1_armhf.deb 这样的文件名,其中包含了类似 linux-headers-*_*_?_armhf.deb 的格式(*代表Linux内核的版本号标签,?代表软件包的版本号)。
- 「クロスコンパイルした Debian GNU/Linux でデバイスドライバをセルフコンパイルする際の注意点(Linux Kernel 5.x編)」@Qiita
安装标头包为了在目标上自行编译设备驱动程序,需要在目标上安装头文件包。在 https://github.com/ikwzm/FPGA-SoC-Linux 上,会提供像 linux-headers-4.14.21-armv7-fpga_4.14.21-armv7-fpga-1_armhf.deb 这样的文件名,其中包含了类似 linux-headers-*_*_?_armhf.deb 的格式(*代表Linux内核的版本号标签,?代表软件包的版本号)。
首先安装此头文件包(可能已经安装)。
正在选择先前未选择的软件包 linux-headers-4.14.21-armv7-fpga。
(正在读取数据库…当前已安装了 62256 个文件和目录。)
准备解包 linux-headers-4.14.21-armv7-fpga_4.14.21-armv7-fpga-1_armhf.deb…
正在解包 linux-headers-4.14.21-armv7-fpga (4.14.21-armv7-fpga-1)…
正在设置 linux-headers-4.14.21-armv7-fpga (4.14.21-armv7-fpga-1) …
自编译失败的例子
下载我們以 udmabuf (一個將內核空間保留的緩衝區讓用戶空間可以使用的設備驅動程式) 作為例子來進行編譯。
root@debian-fpga:~/work# git clone https://github.com/ikwzm/udmabuf.git
正在克隆到 ‘udmabuf’…
远程: 正在计数对象: 212, 完成.
远程: 正在压缩对象: 100% (6/6), 完成.
远程: 总共 212 (差异 0), 重用 3 (差异 0), 压缩 206
接收对象: 100% (212/212), 160.13 KiB | 0 bytes/s, 完成.
正在解决差异: 100% (115/115), 完成.
root@debian-fpga:~/work# cd udmabuf
失败时的日志如果使用make命令来构建udmabuf,会出现以下失败的情况。
root@debian-fpga:~/work/udmabuf# make
make -C /lib/modules/4.14.21-armv7-fpga/build ARCH=arm CROSS_COMPILE= M=/root/work/udmabuf modules
make[1]: Entering directory '/usr/src/linux-headers-4.14.21-armv7-fpga'
CC [M] /root/work/udmabuf/udmabuf.o
/bin/sh: 1: scripts/basic/fixdep: Exec format error
scripts/Makefile.build:326: recipe for target '/root/work/udmabuf/udmabuf.o' failed
make[2]: *** [/root/work/udmabuf/udmabuf.o] Error 2
Makefile:1508: recipe for target '_module_/root/work/udmabuf' failed
make[1]: *** [_module_/root/work/udmabuf] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.14.21-armv7-fpga'
Makefile:19: recipe for target 'all' failed
make: *** [all] Error 2
失败的原因查看日志,似乎在执行 scripts/basic/fixdep 时发现执行格式不同。scripts/basic/fixdep 位于 /usr/src/linux-headers-*/scripts/basic/fixdep 。确认文件类型时,发现它是主机计算机架构(这里是 x86-64)的二进制文件。
文件/usr/src/linux-headers-4.14.21-armv7-fpga/scripts/basic/fixdep的日志root@debian-fpga:~/work/udmabuf# file /usr/src/linux-headers-4.14.21-armv7-fpga/scripts/basic/fixdep
/usr/src/linux-headers-4.14.21-armv7-fpga/scripts/basic/fixdep:64位LSB可执行文件,x86-64架构,版本1(SYSV),动态链接,解释器/lib64/ld-linux-x86-64.so.2,用于GNU/Linux 2.6.32,未剥离。
临时处理方案
因此,我们将重新构建在/usr/src/linux-headers-*/ 目录中安装的各种脚本,以适应目标架构。
在debian-fpga的终端中,通过以下命令执行日志:root@debian-fpga:~/work/udmabuf# cd /usr/src/linux-headers-4.14.21-armv7-fpga/
root@debian-fpga:/usr/src/linux-headers-4.14.21-armv7-fpga# 执行脚本命令
HOSTCC scripts/basic/fixdep
HOSTCC scripts/basic/bin2c
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
scripts/kconfig/conf –silentoldconfig Kconfig
HOSTCC scripts/dtc/dtc.o
HOSTCC scripts/dtc/flattree.o
HOSTCC scripts/dtc/fstree.o
HOSTCC scripts/dtc/data.o
HOSTCC scripts/dtc/livetree.o
HOSTCC scripts/dtc/treesource.o
HOSTCC scripts/dtc/srcpos.o
HOSTCC scripts/dtc/checks.o
HOSTCC scripts/dtc/util.o
HOSTCC scripts/dtc/dtc-lexer.lex.o
HOSTCC scripts/dtc/dtc-parser.tab.o
HOSTLD scripts/dtc/dtc
HOSTCC scripts/genksyms/genksyms.o
HOSTCC scripts/genksyms/parse.tab.o
HOSTCC scripts/genksyms/lex.lex.o
HOSTLD scripts/genksyms/genksyms
CC scripts/mod/empty.o
HOSTCC scripts/mod/mk_elfconfig
MKELF scripts/mod/elfconfig.h
HOSTCC scripts/mod/modpost.o
CC scripts/mod/devicetable-offsets.s
CHK scripts/mod/devicetable-offsets.h
HOSTCC scripts/mod/file2alias.o
HOSTCC scripts/mod/sumversion.o
HOSTLD scripts/mod/modpost
HOSTCC scripts/kallsyms
HOSTCC scripts/conmakehash
HOSTCC scripts/sortextable
scripts/sortextable.c:31:32: fatal error: tools/be_byteshift.h: No such file or directory
#include <tools/be_byteshift.h>
^
compilation terminated.
scripts/Makefile.host:102: recipe for target ‘scripts/sortextable’ failed
make[1]: *** [scripts/sortextable] Error 1
Makefile:558: recipe for target ‘scripts’ failed
make: *** [scripts] Error 2
正在克隆到 ‘udmabuf’…
远程: 正在计数对象: 212, 完成.
远程: 正在压缩对象: 100% (6/6), 完成.
远程: 总共 212 (差异 0), 重用 3 (差异 0), 压缩 206
接收对象: 100% (212/212), 160.13 KiB | 0 bytes/s, 完成.
正在解决差异: 100% (115/115), 完成.
root@debian-fpga:~/work# cd udmabuf
失败时的日志如果使用make命令来构建udmabuf,会出现以下失败的情况。
root@debian-fpga:~/work/udmabuf# make
make -C /lib/modules/4.14.21-armv7-fpga/build ARCH=arm CROSS_COMPILE= M=/root/work/udmabuf modules
make[1]: Entering directory '/usr/src/linux-headers-4.14.21-armv7-fpga'
CC [M] /root/work/udmabuf/udmabuf.o
/bin/sh: 1: scripts/basic/fixdep: Exec format error
scripts/Makefile.build:326: recipe for target '/root/work/udmabuf/udmabuf.o' failed
make[2]: *** [/root/work/udmabuf/udmabuf.o] Error 2
Makefile:1508: recipe for target '_module_/root/work/udmabuf' failed
make[1]: *** [_module_/root/work/udmabuf] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.14.21-armv7-fpga'
Makefile:19: recipe for target 'all' failed
make: *** [all] Error 2
失败的原因查看日志,似乎在执行 scripts/basic/fixdep 时发现执行格式不同。scripts/basic/fixdep 位于 /usr/src/linux-headers-*/scripts/basic/fixdep 。确认文件类型时,发现它是主机计算机架构(这里是 x86-64)的二进制文件。
文件/usr/src/linux-headers-4.14.21-armv7-fpga/scripts/basic/fixdep的日志root@debian-fpga:~/work/udmabuf# file /usr/src/linux-headers-4.14.21-armv7-fpga/scripts/basic/fixdep
/usr/src/linux-headers-4.14.21-armv7-fpga/scripts/basic/fixdep:64位LSB可执行文件,x86-64架构,版本1(SYSV),动态链接,解释器/lib64/ld-linux-x86-64.so.2,用于GNU/Linux 2.6.32,未剥离。
临时处理方案
因此,我们将重新构建在/usr/src/linux-headers-*/ 目录中安装的各种脚本,以适应目标架构。
在debian-fpga的终端中,通过以下命令执行日志:root@debian-fpga:~/work/udmabuf# cd /usr/src/linux-headers-4.14.21-armv7-fpga/
root@debian-fpga:/usr/src/linux-headers-4.14.21-armv7-fpga# 执行脚本命令
HOSTCC scripts/basic/fixdep
HOSTCC scripts/basic/bin2c
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
scripts/kconfig/conf –silentoldconfig Kconfig
HOSTCC scripts/dtc/dtc.o
HOSTCC scripts/dtc/flattree.o
HOSTCC scripts/dtc/fstree.o
HOSTCC scripts/dtc/data.o
HOSTCC scripts/dtc/livetree.o
HOSTCC scripts/dtc/treesource.o
HOSTCC scripts/dtc/srcpos.o
HOSTCC scripts/dtc/checks.o
HOSTCC scripts/dtc/util.o
HOSTCC scripts/dtc/dtc-lexer.lex.o
HOSTCC scripts/dtc/dtc-parser.tab.o
HOSTLD scripts/dtc/dtc
HOSTCC scripts/genksyms/genksyms.o
HOSTCC scripts/genksyms/parse.tab.o
HOSTCC scripts/genksyms/lex.lex.o
HOSTLD scripts/genksyms/genksyms
CC scripts/mod/empty.o
HOSTCC scripts/mod/mk_elfconfig
MKELF scripts/mod/elfconfig.h
HOSTCC scripts/mod/modpost.o
CC scripts/mod/devicetable-offsets.s
CHK scripts/mod/devicetable-offsets.h
HOSTCC scripts/mod/file2alias.o
HOSTCC scripts/mod/sumversion.o
HOSTLD scripts/mod/modpost
HOSTCC scripts/kallsyms
HOSTCC scripts/conmakehash
HOSTCC scripts/sortextable
scripts/sortextable.c:31:32: fatal error: tools/be_byteshift.h: No such file or directory
#include <tools/be_byteshift.h>
^
compilation terminated.
scripts/Makefile.host:102: recipe for target ‘scripts/sortextable’ failed
make[1]: *** [scripts/sortextable] Error 1
Makefile:558: recipe for target ‘scripts’ failed
make: *** [scripts] Error 2
root@debian-fpga:~/work/udmabuf# make
make -C /lib/modules/4.14.21-armv7-fpga/build ARCH=arm CROSS_COMPILE= M=/root/work/udmabuf modules
make[1]: Entering directory '/usr/src/linux-headers-4.14.21-armv7-fpga'
CC [M] /root/work/udmabuf/udmabuf.o
/bin/sh: 1: scripts/basic/fixdep: Exec format error
scripts/Makefile.build:326: recipe for target '/root/work/udmabuf/udmabuf.o' failed
make[2]: *** [/root/work/udmabuf/udmabuf.o] Error 2
Makefile:1508: recipe for target '_module_/root/work/udmabuf' failed
make[1]: *** [_module_/root/work/udmabuf] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.14.21-armv7-fpga'
Makefile:19: recipe for target 'all' failed
make: *** [all] Error 2
/usr/src/linux-headers-4.14.21-armv7-fpga/scripts/basic/fixdep:64位LSB可执行文件,x86-64架构,版本1(SYSV),动态链接,解释器/lib64/ld-linux-x86-64.so.2,用于GNU/Linux 2.6.32,未剥离。
临时处理方案
因此,我们将重新构建在/usr/src/linux-headers-*/ 目录中安装的各种脚本,以适应目标架构。
在debian-fpga的终端中,通过以下命令执行日志:root@debian-fpga:~/work/udmabuf# cd /usr/src/linux-headers-4.14.21-armv7-fpga/
root@debian-fpga:/usr/src/linux-headers-4.14.21-armv7-fpga# 执行脚本命令
HOSTCC scripts/basic/fixdep
HOSTCC scripts/basic/bin2c
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
scripts/kconfig/conf –silentoldconfig Kconfig
HOSTCC scripts/dtc/dtc.o
HOSTCC scripts/dtc/flattree.o
HOSTCC scripts/dtc/fstree.o
HOSTCC scripts/dtc/data.o
HOSTCC scripts/dtc/livetree.o
HOSTCC scripts/dtc/treesource.o
HOSTCC scripts/dtc/srcpos.o
HOSTCC scripts/dtc/checks.o
HOSTCC scripts/dtc/util.o
HOSTCC scripts/dtc/dtc-lexer.lex.o
HOSTCC scripts/dtc/dtc-parser.tab.o
HOSTLD scripts/dtc/dtc
HOSTCC scripts/genksyms/genksyms.o
HOSTCC scripts/genksyms/parse.tab.o
HOSTCC scripts/genksyms/lex.lex.o
HOSTLD scripts/genksyms/genksyms
CC scripts/mod/empty.o
HOSTCC scripts/mod/mk_elfconfig
MKELF scripts/mod/elfconfig.h
HOSTCC scripts/mod/modpost.o
CC scripts/mod/devicetable-offsets.s
CHK scripts/mod/devicetable-offsets.h
HOSTCC scripts/mod/file2alias.o
HOSTCC scripts/mod/sumversion.o
HOSTLD scripts/mod/modpost
HOSTCC scripts/kallsyms
HOSTCC scripts/conmakehash
HOSTCC scripts/sortextable
scripts/sortextable.c:31:32: fatal error: tools/be_byteshift.h: No such file or directory
#include <tools/be_byteshift.h>
^
compilation terminated.
scripts/Makefile.host:102: recipe for target ‘scripts/sortextable’ failed
make[1]: *** [scripts/sortextable] Error 1
Makefile:558: recipe for target ‘scripts’ failed
make: *** [scripts] Error 2
root@debian-fpga:/usr/src/linux-headers-4.14.21-armv7-fpga# 执行脚本命令
HOSTCC scripts/basic/fixdep
HOSTCC scripts/basic/bin2c
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
scripts/kconfig/conf –silentoldconfig Kconfig
HOSTCC scripts/dtc/dtc.o
HOSTCC scripts/dtc/flattree.o
HOSTCC scripts/dtc/fstree.o
HOSTCC scripts/dtc/data.o
HOSTCC scripts/dtc/livetree.o
HOSTCC scripts/dtc/treesource.o
HOSTCC scripts/dtc/srcpos.o
HOSTCC scripts/dtc/checks.o
HOSTCC scripts/dtc/util.o
HOSTCC scripts/dtc/dtc-lexer.lex.o
HOSTCC scripts/dtc/dtc-parser.tab.o
HOSTLD scripts/dtc/dtc
HOSTCC scripts/genksyms/genksyms.o
HOSTCC scripts/genksyms/parse.tab.o
HOSTCC scripts/genksyms/lex.lex.o
HOSTLD scripts/genksyms/genksyms
CC scripts/mod/empty.o
HOSTCC scripts/mod/mk_elfconfig
MKELF scripts/mod/elfconfig.h
HOSTCC scripts/mod/modpost.o
CC scripts/mod/devicetable-offsets.s
CHK scripts/mod/devicetable-offsets.h
HOSTCC scripts/mod/file2alias.o
HOSTCC scripts/mod/sumversion.o
HOSTLD scripts/mod/modpost
HOSTCC scripts/kallsyms
HOSTCC scripts/conmakehash
HOSTCC scripts/sortextable
scripts/sortextable.c:31:32: fatal error: tools/be_byteshift.h: No such file or directory
#include <tools/be_byteshift.h>
^
compilation terminated.
scripts/Makefile.host:102: recipe for target ‘scripts/sortextable’ failed
make[1]: *** [scripts/sortextable] Error 1
Makefile:558: recipe for target ‘scripts’ failed
make: *** [scripts] Error 2
脚本/scripts/sortextable的编译错误。它似乎在寻找<tools/be_byteshift.h>并未找到。但无论如何,脚本/basic/fixdep的构建似乎已经完成。我会尝试重新构建设备驱动程序。
root@debian-fpga:/usr/src/linux-headers-4.14.21-armv7-fpga# cd ~/work/udmabuf
root@debian-fpga:~/work/udmabuf# make
make -C /lib/modules/4.14.21-armv7-fpga/build ARCH=arm CROSS_COMPILE= M=/root/work/udmabuf modules
make[1]: Entering directory '/usr/src/linux-headers-4.14.21-armv7-fpga'
CC [M] /root/work/udmabuf/udmabuf.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: modpost: Found 1 section mismatch(es).
To see full details build your kernel with:
'make CONFIG_DEBUG_SECTION_MISMATCH=y'
CC /root/work/udmabuf/udmabuf.mod.o
LD [M] /root/work/udmabuf/udmabuf.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.14.21-armv7-fpga'
这次成功编译了。
修改标题包。
我认为正确的方法是将针对目标架构编译的可执行文件包含在头文件包中。然而,在我调查的范围内,我没有找到构建头文件包的方法。如果有任何了解的人,请告诉我,谢谢。
作为次好的解决方案,当在目标上安装了头文件包时,会自动重新构建各种脚本,重新创建头文件包。具体而言,我们会对生成头文件包的脚本应用以下补丁。
323行
如果 [ -f /usr/src/linux-headers-$version/scripts/package/builddeb.mk ]; then
host-progs = $(realpath $srctree/scripts/package/builddeb)
else
host-progs = $(realpath $srctree/scripts/package/mkdebian)
endif
如果存在 /usr/src/linux-headers-$version/scripts/package/builddeb.mk 文件,则主要程序设为 $(realpath $srctree/scripts/package/builddeb),否则设为 $(realpath $srctree/scripts/package/mkdebian)
323行
if [ -f /usr/src/linux-headers-$version/scripts/package/builddeb.mk ]; then
host-progs = $(realpath $srctree/scripts/package/builddeb)
else
host-progs = $(realpath $srctree/scripts/package/mkdebian)
endif
如果存在 /usr/src/linux-headers-$version/scripts/package/builddeb.mk 文件,则主要程序设为 $(realpath $srctree/scripts/package/builddeb),否则设为 $(realpath $srctree/scripts/package/mkdebian)
这个补丁文件是为了 builddeb,以包括 tools/include 目录下的文件。这使得 scripts/sortextable 的构建能够正常完成。
然后,将 postinst 脚本添加到头文件包中,以重新构建脚本以供目标使用。这样,当安装头文件包时,会自动重新构建脚本。
升级头部包时,直接安装新版本的头部包即可。
(读取数据库…当前已安装了81503个文件和目录。)
准备解包linux-headers-4.14.21-armv7-fpga_4.14.21-armv7-fpga-2_armhf.deb …
正在解包linux-headers-4.14.21-armv7-fpga (4.14.21-armv7-fpga-2),覆盖 (4.14.21-armv7-fpga-1) …
设置linux-headers-4.14.21-armv7-fpga (4.14.21-armv7-fpga-2) …
make: 进入目录 ‘/usr/src/linux-headers-4.14.21-armv7-fpga’
HOSTCC scripts/basic/fixdep
HOSTCC scripts/basic/bin2c
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
scripts/kconfig/conf –silentoldconfig Kconfig
HOSTCC scripts/dtc/dtc.o
HOSTCC scripts/dtc/flattree.o
HOSTCC scripts/dtc/fstree.o
HOSTCC scripts/dtc/data.o
HOSTCC scripts/dtc/livetree.o
HOSTCC scripts/dtc/treesource.o
HOSTCC scripts/dtc/srcpos.o
HOSTCC scripts/dtc/checks.o
HOSTCC scripts/dtc/util.o
HOSTCC scripts/dtc/dtc-lexer.lex.o
HOSTCC scripts/dtc/dtc-parser.tab.o
HOSTLD scripts/dtc/dtc
HOSTCC scripts/genksyms/genksyms.o
HOSTCC scripts/genksyms/parse.tab.o
HOSTCC scripts/genksyms/lex.lex.o
HOSTLD scripts/genksyms/genksyms
CC scripts/mod/empty.o
HOSTCC scripts/mod/mk_elfconfig
MKELF scripts/mod/elfconfig.h
HOSTCC scripts/mod/modpost.o
CC scripts/mod/devicetable-offsets.s
CHK scripts/mod/devicetable-offsets.h
HOSTCC scripts/mod/file2alias.o
HOSTCC scripts/mod/sumversion.o
HOSTLD scripts/mod/modpost
HOSTCC scripts/kallsyms
HOSTCC scripts/conmakehash
HOSTCC scripts/sortextable
make: 离开目录 ‘/usr/src/linux-headers-4.14.21-armv7-fpga’