Como incluir arquivos de cabeçalho local no módulo do kernel do linux
17
Digamos que eu tenha um módulo mymodcom arquivos de origem da seguinte maneira:
src / mod / mymod.c
src / inc / mymod.h
Eu tento incluir mymod.h da seguinte maneira
#include <mymod.h>
Meu makefile contém EXTRA_CFLAGS= -I$(shell pwd)/../inc/mas quando o kernel é criado, recebo um erro informando:
mymod.h não encontrado
A razão parece ser que, quando os módulos do kernel são criados, esse comando é executado a partir do makefile: (usando makeV1):
make -C <path/to/linux/src> M=<path/to/mymod> modules
Em outros trabalhos, $(shell pwd)fui expandido para <path/to/linux>. Não é isso que eu quero. Como posso especificar o -Iparâmetro para apontar para a src/incminha mymodárvore de origem?
Os makefiles do kernel Linux usam a estrutura Kbuild. Embora estes sejam interpretados pelo GNU make, o Kbuild consiste em um grande conjunto de macros com convenções de uso peculiares, portanto as diretrizes típicas do makefile não se aplicam. O bom do Kbuild é que você precisa de muito pouco clichê, considerando a complexidade da tarefa.
O Kbuild está documentado na fonte do kernel, em Documentation/kbuild. Como criador de módulos, você deve ler especialmente modules.txt(e pelo menos examinar os outros).
O que você está fazendo agora não está funcionando porque $(shell pwd)é expandido quando a EXTRA_CFLAGSvariável é usada. Como o makefile é executado a partir da árvore de fontes do kernel, e não do diretório do módulo (este é um dos muitos aspectos não óbvios do Kbuild), ele está escolhendo o diretório errado.
O idioma oficial para especificar diretórios de inclusão em um módulo fora da árvore está em §5.3 de modules.txt. A srcvariável é configurada para o diretório de nível superior do seu módulo. Portanto:
EXTRA_CFLAGS := -I$(src)/src/inc
Observe que esta declaração deve estar em um arquivo chamado Kbuildna raiz da sua árvore de módulos. (Você pode considerar o srcdiretório como a raiz da sua árvore de módulos; nesse caso, coloque Kbuild-o e substitua o valor acima por -I$(src)/inc). Também é possível colocá-los em a Makefile, mas lembre-se de que essa definição (desde que qualquer outra coisa que se aplique apenas ao criar um módulo do kernel) deve estar dentro de uma diretiva condicional ifeq ($(KERNELRELEASE),). Veja §4.1 de modules.txt.
Se você ainda não possui um Kbuildarquivo e deseja mudar para um, leia §4.1 de modules.txt. Ter um Kbuildarquivo separado é um pouco mais claro. Não coloque nada que se aplique ao kernel no seu makefile principal, exceto uma regra a ser chamada make -C $(KERNELDIR) M=$(pwd). Em Kbuild, o mínimo necessário é a lista de módulos que você está construindo (geralmente apenas um) e uma lista de arquivos a serem incluídos no seu módulo, além de uma declaração de dependência:
Não pude atualizar a postagem porque não tinha reputação suficiente.
Om Narasimhan
1
@ Narasimhan: Se isso ajudou você a descobrir a solução, marque a resposta como aceita.
um CVn
1
Tradicionalmente, o caminho para #includearquivos com caminhos relativos ao diretório do código-fonte atual é usar aspas em vez de colchetes angulares:
#include <stdio.h>
#include "mygreatfunctions.h"
Nesse caso, o primeiro #includefará referência ao caminho de pesquisa de inclusão do compilador (que, no caso do gcc, é controlado pela -Iopção de linha de comando), enquanto o segundo procurará no diretório que contém o arquivo de origem #include.
Esses caminhos também podem ser relativos. Portanto, em src / mod / mymod.c, você pode dizer:
#include "../inc/mymod.h"
e deve "apenas funcionar".
Não sei se isso é prática comum na árvore do kernel do Linux, mas certamente é melhor do que mexer no caminho de inclusão, que pode ter vários efeitos colaterais indesejados.
Bons conselhos em geral, porém os makefiles do kernel do Linux são muito peculiares. Eles chamam um conjunto bastante complexo de macros chamado Kbuild; geralmente é melhor tratar o Kbuild como uma linguagem que é quase, mas não completamente, completamente diferente do make.
Gilles 'SO- stop be evil'
1
Com certeza, mas o comportamento do compilador C de procurar <foo> em algum conjunto de diretórios configurado e de "bar" primeiro olhar no diretório atual e depois voltar ao caminho mencionado anteriormente não mudará pelo que significa bizarro chamado o compilador em primeiro lugar.
Tradicionalmente, o caminho para
#include
arquivos com caminhos relativos ao diretório do código-fonte atual é usar aspas em vez de colchetes angulares:Nesse caso, o primeiro
#include
fará referência ao caminho de pesquisa de inclusão do compilador (que, no caso do gcc, é controlado pela-I
opção de linha de comando), enquanto o segundo procurará no diretório que contém o arquivo de origem#include
.Esses caminhos também podem ser relativos. Portanto, em src / mod / mymod.c, você pode dizer:
e deve "apenas funcionar".
Não sei se isso é prática comum na árvore do kernel do Linux, mas certamente é melhor do que mexer no caminho de inclusão, que pode ter vários efeitos colaterais indesejados.
fonte