Estou tentando compilar um módulo de driver proprietário de terceiros e falhando nisso. Instalei o linux-headers-5.4.0
pacote, mas não sei como escrever uma linha de comando gcc que o usará com sucesso.
Como um exemplo mínimo, considere test.c
, que literalmente não faz nada além de incluir cabeçalhos de kernel.
#include <asm/linkage.h>
#include <linux/module.h>
Como o kernel inclui esses dois arquivos e pode ser compilado, certamente deve haver alguma combinação de sinalizadores do GCC que resultará na test.c
compilação. O .c
arquivo do driver proprietário inclui esses dois arquivos entre muitos outros, mas eles são suficientes para demonstrar meu problema.
eyes=(
-I/usr/src/linux-headers-5.4.0-21/include # for linux/module.h
-I/usr/src/linux-headers-5.4.0-21/arch/x86/include # for asm/linkage.h
)
gcc -c "${eyes[@]}" test.c
resulta em
In file included from /usr/src/linux-headers-5.4.0-21/include/linux/seqlock.h:36,
from /usr/src/linux-headers-5.4.0-21/include/linux/time.h:6,
from /usr/src/linux-headers-5.4.0-21/include/linux/stat.h:19,
from /usr/src/linux-headers-5.4.0-21/include/linux/module.h:10,
from test.c:2:
/usr/src/linux-headers-5.4.0-21/include/linux/spinlock.h:60:10: fatal error: asm/mmiowb.h: No such file or directory
60 | #include <asm/mmiowb.h>
| ^~~~~~~~~~~~~~
dpkg -L linux-headers-5.4.0-21 | grep mmiowb.h
mostra este arquivo include/asm-generic
tanto em arch/{ia64,mips,powerpc,riscv,sh}/include/asm
. Ajustando meu -I
adicional para incluir um desses e o erro se move para:
In file included from /usr/src/linux-headers-5.4.0-21/include/linux/mmzone.h:19,
from /usr/src/linux-headers-5.4.0-21/include/linux/gfp.h:6,
from /usr/src/linux-headers-5.4.0-21/include/linux/umh.h:4,
from /usr/src/linux-headers-5.4.0-21/include/linux/kmod.h:9,
from /usr/src/linux-headers-5.4.0-21/include/linux/module.h:13,
from test.c:2:
/usr/src/linux-headers-5.4.0-21/include/linux/page-flags-layout.h:6:10: fatal error: generated/bounds.h: No such file or directory
6 | #include <generated/bounds.h>
| ^~~~~~~~~~~~~~~~~~~~
e esse arquivo simplesmente não existe no meu sistema, mas existe um arquivo chamado /usr/src/linux-headers-5.4.0-21/KBuild
que se parece com um makefile que o criaria, embora eu não consiga descobrir como invocar esse makefile.
Como posso proceder aqui? Existe um comando que preciso executar após a instalação linux-headers-*
para preencher as generated
pastas? Existe um guia para esse tipo de coisa online em algum lugar?
O kernel Linux possui seu próprio sistema de compilação baseado em
make
, que gera as opções corretasgcc
para uma compilação bem-sucedida dos componentes e módulos do kernel. OKbuild
arquivo incluído nos módulos de kernel externos destina-se ao uso com esse sistema de compilação do kernel. Além disso, os módulos externos do kernel também devem incluir umMakefile
que invoca o sistema de compilação do kernel. Um mínimoMakefile
para um módulo externo pode ser assim:Como você pode ver, o principal
Makefile
do sistema de compilação do kernel reside na pasta/lib/modules/$(KVERSION)/build
, onde$(KVERSION)
está o número da versão do kernel para o qual você está compilando. Se você estiver curioso, pode tentar refazer o que a malha de Makefiles faz e com qual conjunto de opções ele acaba chamandogcc
.