Como incluir arquivos de cabeçalho locais no módulo do kernel do Linux

17

Digamos que eu tenha um módulo mymod com arquivos de origem da seguinte forma:

src/mod/mymod.c
src/inc/mymod.h

Eu tento incluir mymod.h da seguinte forma

#include <mymod.h>

Meu makefile contém EXTRA_CFLAGS= -I$(shell pwd)/../inc/ , mas quando o kernel é criado, recebo um erro dizendo:

mymod.h not found

O motivo parece ser que, quando os módulos do kernel são feitos, este comando é executado a partir do makefile: (usando make V1):

make -C <path/to/linux/src> M=<path/to/mymod> modules

Em outros trabalhos, meu $(shell pwd) foi expandido para <path/to/linux> . Isso não é o que eu quero. Como posso especificar o parâmetro -I para apontar para src/inc da minha árvore de código mymod ?

    
por Om Narasimhan 05.08.2011 / 19:34

2 respostas

17

Os makefiles do kernel Linux usam o framework 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 legal 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 um redator de módulo, você deveria especialmente ler modules.txt (e pelo menos folhear os outros ).

O que você está fazendo agora não está funcionando porque $(shell pwd) é expandido quando a variável EXTRA_CFLAGS é usada. Já que o makefile é executado a partir da árvore fonte do kernel ao invés do diretório do seu módulo (este é um dos muitos aspectos não óbvios do Kbuild), ele está pegando o diretório errado.

O idioma oficial para especificar diretórios include em um módulo fora da árvore está em §5.3 de modules.txt . A variável src está definida para o diretório de nível superior do seu módulo. Portanto:

EXTRA_CFLAGS := -I$(src)/src/inc

Note que esta declaração deve estar em um arquivo chamado Kbuild na raiz da sua árvore de módulos. (Você pode considerar o diretório src como a raiz da árvore de módulos; se estiver, coloque Kbuild e substitua o valor acima por -I$(src)/inc ). Também é possível colocá-los em Makefile , mas lembre-se que essa definição (desde que qualquer outra coisa que se aplique somente ao construir um módulo do kernel) deve estar dentro de uma diretiva condicional ifeq ($(KERNELRELEASE),) . Veja §4.1 de modules.txt .

Se você não tiver um arquivo Kbuild e quiser mudar para um, leia §4.1 de modules.txt . Ter um arquivo Kbuild separado é um pouco mais claro. Não coloque nada que se aplique ao kernel em seu makefile principal, além de uma regra para chamar make -C $(KERNELDIR) M=$(pwd) . Em Kbuild , o mínimo que você precisa é a lista de módulos que você está construindo (geralmente o único) e uma lista de arquivos para incluir em seu módulo, além de uma declaração de dependência:

EXTRA_CFLAGS := -I$(src)/inc
obj-m := mymod.o
mymod-y := $(src)/mod/mymod.o
$(src)/mod/mymod.o: $(src)/inc/mymod.h
    
por 06.08.2011 / 02:19
0

Tradicionalmente, o caminho para #include arquivos 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 #include fará referência ao caminho de busca de inclusão do compilador (que, no caso do gcc, é controlado pela opção de linha de comando -I ), enquanto o segundo procurará no diretório que contém o arquivo de origem com o #include .

Esses caminhos também podem ser relativos. Então, em src / mod / mymod.c, você pode dizer:

#include "../inc/mymod.h"

e deve "apenas funcionar".

Eu não sei se isso é uma prática comum na árvore do kernel do Linux, mas com certeza é melhor do que mexer com o caminho include, que pode ter qualquer número de efeitos colaterais indesejados.

    
por 05.08.2011 / 22:04