“nenhuma versão de símbolo para module_layout” ao tentar carregar usbhid.ko

25

Estou tentando criar meu próprio módulo para usbhid.ko , mas depois de compilado, não consigo carregar o módulo. dmesg diz no symbol version for module_layout . Eu estou querendo saber qual é o problema? Eu já usei a fonte do kernel fornecida pelo Ubuntu e também assegurei que a versão do kernel é a mesma.

    
por SpecC 24.11.2010 / 00:08

3 respostas

18

Especificamente, o problema é que, quando você construiu seu módulo, a árvore de origem do kernel provavelmente estava faltando no arquivo Modules.symvers. O sistema kbuild na verdade avisa sobre isso quando você constrói seu módulo. Se Modules.symvers estiver faltando, você verá:

  

Aviso: dump de versão de símbolo /usr/src/linux-2.6.34-12/Modules.symvers            está desaparecido; módulos não terão dependências e modversões.

Se o seu kernel tem CONFIG_MODVERSIONS habilitado, então durante a fase de modulação da construção do seu driver ele rodará scripts / mod / modpost com a opção -m. Se você é corajoso e dá uma olhada na fonte scripts / mod / modpost.c , verá que a opção -m adiciona o símbolo _module_layout_ do vmlinux, no entanto, se você não tiver Modules.symvers do seu kernel, você não obterá o valor de CRC para este símbolo e terminará com essa mensagem de erro.

Portanto, há duas maneiras de contornar isso.

1) execute uma compilação completa de seu kernel em execução para gerar Modules.symvers e, em seguida, recrie seu módulo. [http://www.mjmwired.net/kernel/Documentation/kbuild/modules.txt] [1]

51  === 2. How to Build External Modules
52  
53  To build external modules, you must have a prebuilt kernel available
54  that contains the configuration and header files used in the build.
55  Also, the kernel must have been built with modules enabled. If you are
56  using a distribution kernel, there will be a package for the kernel you
57  are running provided by your distribution.
58  
59  An alternative is to use the "make" target "modules_prepare." This will
60  make sure the kernel contains the information required. The target
61  exists solely as a simple way to prepare a kernel source tree for
62  building external modules.
63  
64  NOTE: "modules_prepare" will not build Module.symvers even if
65  CONFIG_MODVERSIONS is set; therefore, a full kernel build needs to be
66  executed to make module versioning work.

2) A outra opção é dizer ao modprobe estúpido para simplesmente ignorar toda essa porcaria e apenas carregar seu módulo de qualquer maneira:

modprobe -f <module>

Eu tenho a tendência de favorecer a opção 2:)

    
por Dan Gora 07.02.2012 / 01:08
15

Tenha os pacotes linux-headers e linux-source correspondentes ao seu kernel instalado. Por exemplo, para o kernel 3.2.0-27-generic-pae você precisa:

  1. linux-headers-3.2.0-27-generic-pae e
  2. linux-source-3.2.0-27-generic-pae .

Caso a versão dos pacotes acima não corresponda à sua versão do kernel em execução, você precisará substituir $(uname -r) pela string de versão do pacote do kernel instalado acima.
Para o exemplo acima, a versão do pacote é 3.2.0-27-generic-pae . Quando você executa uname -r e sua saída é algo diferente, então 3.2.0-27-generic-pae , você precisa substituir cada $(uname -r) abaixo para corresponder à string de versão dos pacotes instalados.

  1. cd /usr/src/linux-source-$Version e descompactar o arquivo .tar.bz2 no lugar e cd no diretório extraído - Eu acho que você já fez isso
  2. cp /boot/config-$(uname -r) .config no diretório de origem do kernel
  3. cp /usr/src/linux-headers-$(uname -r)/Module.symvers . no diretório de origem do kernel

Depois de fazer isso, no diretório de origem do kernel, faça o seguinte:

  1. make prepare
  2. make scripts
  3. make M=drivers/usb/serial - altere o caminho depois de M= para atender às suas necessidades

Infelizmente, não sei como criar um módulo específico, mantendo Module.symvers intocado. Fazer make drivers/usb/serial/option.ko , por exemplo, mata o arquivo Module.symvers e você acaba com o problema original. Usar o parâmetro M= não o mata, mas você precisa construir todos os módulos no caminho especificado - e ainda não encontrei uma maneira de contornar isso.

    
por Radu C 03.08.2012 / 19:07
1

Você deve usar a configuração de kernel precisamente idêntica antes de executar make prepare . Além disso, se você está construindo fora da árvore, você precisa construí-lo contra os cabeçalhos de kernel precisamente idênticos que correspondem ao seu kernel atualmente em execução (ou ao de destino, se você não o estiver executando no momento da compilação). / p>     

por Daniel T Chen 24.11.2010 / 05:04