Os módulos do driver são carregados e descarregados automaticamente?


15

No Ubuntu 14.04, descobri que quando não conecto meu adaptador sem fio externo, seu módulo rt2800usbainda é mostrado lsmod.

  1. quando acontece o carregamento automático de um módulo de driver? É quando o dispositivo está conectado ao computador ou quando o sistema operacional é inicializado?

  2. quando acontece o descarregamento automático de um módulo de driver? É quando o dispositivo está desconectado do computador ou quando o sistema operacional é desligado?

Respostas:


13

Quando o kernel detecta um novo dispositivo, ele executa o programa modprobee passa um nome que identifica o dispositivo. A maioria dos dispositivos é identificada através de números registrados para um fornecedor e modelo, por exemplo, identificadores PCI ou USB . O modprobeprograma consulta a tabela de alias do módulo para encontrar o nome do arquivo que contém o driver para esse dispositivo específico. Um princípio semelhante se aplica aos drivers para coisas que não são dispositivos de hardware, como sistemas de arquivos e algoritmos criptográficos. Para mais detalhes, consulte Debian não detecta placa PCI serial após a reinicialização/lib/modules/VERSION/modules.alias

Depois que o modprobe identifica qual arquivo de módulo ( .ko) contém o driver solicitado, ele carrega o arquivo de módulo no kernel: o código do módulo é carregado dinamicamente no kernel. Se o módulo for carregado com sucesso, ele aparecerá na lista de lsmod.

O carregamento automático dos módulos ocorre quando o kernel detecta um novo hardware hotpluggable, por exemplo, quando você conecta um periférico USB. O sistema operacional também faz uma enumeração de todo o hardware presente no sistema no início da inicialização, para carregar drivers de periféricos presentes no momento da inicialização.

Também é possível solicitar manualmente o carregamento de um módulo com o comando modprobeou insmod. A maioria das distribuições incluem um script de inicialização que carrega os módulos listados na /etc/modules. Outra maneira de carregar os módulos é se eles dependem de um módulo: se o módulo A depende do módulo B, modprobe Acarrega B antes de carregar A.

Depois que um módulo é carregado, ele permanece carregado até ser descarregado explicitamente, mesmo que todos os dispositivos que usam esse driver tenham sido desconectados. Há muito tempo, havia um mecanismo para descarregar automaticamente módulos não utilizados, mas ele foi removido, se bem me lembro, quando o udev entrou em cena. Suspeito que o descarregamento automático de módulos não seja um recurso comum, porque os sistemas que tendem a precisar dele são principalmente computadores de mesa que têm muita memória de qualquer maneira (na escala do código do driver).


Obrigado. Eu não modifiquei /etc/modules. rt2800usbestá na saída de lsmod, e isso significa que eu conectei seu dispositivo ao meu computador antes desde a inicialização?
Tim

1
@ Tim Se o módulo estiver carregado e você não o tiver carregado explicitamente, e não estiver listado /etc/modules, sim, provavelmente o motivo pelo qual o módulo foi carregado é porque o dispositivo estava presente em algum momento.
Gilles 'SO- stop be evil'

5

Os módulos são carregados quando o sistema inicializa através do disco RAM inicial, também conhecido como initrd . A Seção Justificativa declara:

Muitas distribuições Linux fornecem uma única imagem genérica do kernel Linux - uma que os desenvolvedores da distribuição criam especificamente para inicializar em uma ampla variedade de hardware. Os drivers de dispositivo para esta imagem genérica do kernel estão incluídos como módulos carregáveis, porque compilar estaticamente muitos drivers em um kernel faz com que a imagem do kernel seja muito maior, talvez muito grande para inicializar em computadores com memória limitada. Isso levanta o problema de detectar e carregar os módulos necessários para montar o sistema de arquivos raiz no momento da inicialização ou, nesse caso, deduzir onde ou qual é o sistema de arquivos raiz.

O Ubuntu, como muitas outras distribuições, escolhe carregar todos os drivers de dispositivo neste initrd, independentemente de o driver ser necessário ou não, e também independentemente de o dispositivo estar presente no sistema ou não. Como Giles apontou, tudo é carregado na RAM e, em seguida, os módulos usados ​​são detectados na inicialização e os não utilizados são removidos da RAM. O uso dessa abordagem garante que o Ubuntu sempre inicie em qualquer sistema, independentemente da configuração. O Ubuntu está imitando um kernel monolítico usando construções de microkernel. Veja a razão pela qual isso funciona


  1. O módulo rt2800usbsempre será carregado na inicialização porque o módulo foi incluído no initramfs a que o Gilles se referia. O initramfs é um sucessor do initrd, portanto sempre será mostrado por lsmod. Observe que você pode inserir um módulo recém-compilado no kernel usando modprobeseguido pelo nome do módulo.

Como teste, reinicie o sistema com o adaptador sem fio desconectado. Se tudo correr bem, o módulo não será listado na lsmodsaída s, porque durante a inicialização, o processo de detecção iniciado pelo initramfs e o init não encontrou o dispositivo durante a análise e o módulo foi removido da RAM.

  1. Para remover um módulo enquanto um sistema está em execução, você pode usar comandos como rmmod, ou modprobe -rseguidos pelo nome do módulo. Na próxima inicialização, o módulo será recarregado. Veja acima. Na maioria dos casos, um módulo não é removido dinamicamente, pois isso desativaria a conexão automática, ou seja, uma vez que um módulo é removido, o dispositivo em uso não pode ser detectado novamente quando conectado novamente.

Para remover um módulo lsmod, você deve removê-lo da imagem initramfs criada recompilando o kernel sem o módulo escolhido e depois reconstruindo a imagem. Isso desativa toda a detecção do referido módulo.


3
Você está confuso carregando um arquivo na RAM como parte de um disco RAM e carregando (ou seja, ligando dinamicamente) um módulo no kernel em execução. Os módulos são carregados temporariamente na memória - não no kernel - a partir do initrd (tecnicamente um initramfs atualmente), mas são removidos da memória após a montagem da raiz real. Os módulos são carregados apenas no kernel quando um dispositivo que os utiliza é detectado (com algumas exceções).
Gilles 'SO- stop be evil'

Enquanto eu concordo aqui, ele estava falando sobre descarregar e carregar um módulo que não pode ser feito, a menos que ele opte por reconfigurar o disco RAM do Ubuntu, o que não é recomendado porque o Ubuntu escolhe carregar todos os módulos na RAM a cada atualização do kernel. Todos os módulos são carregados sempre, mas nem todos são usados.
precisa saber é o seguinte

2
Não, a pergunta é sobre carregar e descarregar um módulo no kernel. Nem sua resposta original nem sua resposta revisada abordam isso. O initramfs é irrelevante (ou no máximo periférico) para esta questão.
Gilles 'SO- stop be evil'

@Gilles Isso é melhor?
usar o seguinte código

1
@ eyoung100, concordo com Gilles. Uma discussão sobre initramfs não é relevante para a questão. Os módulos geralmente são carregados enumerando dispositivos /syse carregando os drivers dos dispositivos realmente encontrados no sistema. Isso acontece se o dispositivo estiver presente na inicialização ou conectado posteriormente. udevtem muito mais a ver com isso do que o initramfs / initrd, e se todos, a maioria ou apenas alguns módulos são copiados para o initramfs (uma opção de configuração no /etc/initramfs-tools/initramfs.conf) não é especialmente relevante.
Celada
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.