Qual é a diferença entre drivers e módulos do kernel?

67

Quando eu faço um lspci -kno meu Kubuntu com um kernel 3.2.0-29-genérico, vejo algo assim:

01:00.0 VGA compatible controller: NVIDIA Corporation G86 [Quadro NVS 290] (rev a1)
    Subsystem: NVIDIA Corporation Device 0492
    Kernel driver in use: nvidia
    Kernel modules: nvidia_current, nouveau, nvidiafb

Há um driver de kernel nvidiae os módulos do kernel nvidia_current, nouveau, nvidiafb.

Agora eu me perguntava qual seria a diferença entre os drivers do Kernel e os módulos do Kernel.

JohnnyFromBF
fonte

Respostas:

78

Um módulo do kernel é um pouco de código compilado que pode ser inserido no kernel em tempo de execução, como com insmodou modprobe.

Um driver é um pouco de código que é executado no kernel para conversar com algum dispositivo de hardware. "Conduz" o hardware. Quase todo hardware do seu computador possui um driver associado.¹ Grande parte do kernel em execução é o código do driver.²

Um driver pode ser incorporado estaticamente no arquivo do kernel no disco.³ Um driver também pode ser criado como um módulo do kernel, para que possa ser carregado dinamicamente mais tarde. (E talvez descarregado.)

A prática padrão é criar drivers como módulos do kernel sempre que possível, em vez de vinculá-los estaticamente ao kernel, pois isso oferece mais flexibilidade. Existem boas razões para não, no entanto:

  • Às vezes, um determinado driver é absolutamente necessário para ajudar o sistema a inicializar. Isso não acontece com a frequência que você imagina, devido ao recurso initrd .

  • Drivers estaticamente criados podem ser exatamente o que você deseja em um sistema com escopo estaticamente, como um sistema incorporado . Ou seja, se você souber com antecedência exatamente quais drivers serão sempre necessários e que isso nunca mudará, você tem um bom motivo para não se preocupar com os módulos dinâmicos do kernel.

  • Se você construir seu kernel estaticamente e desativar o recurso de carregamento de módulo dinâmico do Linux, evite a modificação em tempo de execução do código do kernel. Isso fornece segurança e estabilidade adicionais à custa da flexibilidade.

Nem todos os módulos do kernel são drivers. Por exemplo, um recurso relativamente recente no kernel do Linux é que você pode carregar um agendador de processos diferente . Outro exemplo é que os tipos de hardware mais complexos geralmente têm várias camadas genéricas que ficam entre o driver de hardware de baixo nível e a área do usuário, como o driver USB HID , que implementa um elemento específico da pilha USB , independente do hardware subjacente.


Apartes:

  1. Uma exceção a essa declaração ampla é o chip da CPU, que não possui "driver" em si . Seu computador também pode conter hardware para o qual você não possui driver.

  2. O restante do código em um kernel do SO fornece serviços genéricos como gerenciamento de memória , IPC , agendamento , etc. Esses serviços podem servir principalmente a aplicativos da terra do usuário , como nos exemplos vinculados anteriormente, ou podem ser serviços internos usados ​​por drivers ou outros infraestrutura de kernel.

  3. Aquele /bootcarregado na RAM no momento da inicialização pelo carregador de inicialização no início do processo de inicialização .

Warren Young
fonte
11
Os módulos podem ser sistemas de arquivos, protocolos de rede, funcionalidades de firewall e muito mais. Alguns hardwares (por exemplo, placas WiFi) exigem uma pilha de módulos, alguns oferecendo infraestrutura geral, enquanto outros gerenciam o próprio hardware.
vonbrand
11
Esse é um bom esboço geral, mas eu tinha exatamente a mesma pergunta do OP, então encontrei essa resposta e ainda não sabia por que o "driver em uso" é diferente dos "módulos". Por outro lado, a resposta de @Jim Paris está correta. De man lspci: "-k Mostra os drivers do kernel manipulando cada dispositivo e também os módulos do kernel capazes de manipulá- lo." Você pode ler isso como: "Mostrar o driver atualmente / realmente manipulando o dispositivo e também todos os módulos que podem / devem ser manipulados ".
Binarus
Se você conhece o Windows: Um módulo é muito semelhante a uma DLL. No unix, um módulo é semelhante a um objeto compartilhado, mas um módulo é apenas para o kernel. Um módulo vinculado dinamicamente pode conter drivers. Um kernel pode conter drivers vinculados estaticamente. Um módulo é diferente de uma DLL (ou .so) porque o kernel possui requisitos específicos para como as coisas são carregadas dinamicamente.
robocat
18

Para responder sua pergunta específica sobre a lspcisaída, a linha "driver do kernel" refere-se a qual driver está atualmente vinculado à placa, nesse caso, o nvidiadriver proprietário . A linha "módulos do kernel" lista todos os drivers conhecidos por serem capazes de vincular a esta placa. Aqui, o driver proprietário mostra um nome diferente, provavelmente devido à lspcilocalização do driver e seu nome de arquivo versus o nome codificado no próprio driver.

Jim Paris
fonte
Obrigado - isso ajudou. Se eu apenas tivesse emitido man lspci- diz exatamente o que você escreveu.
Binarus
5

De acordo com este bom tutorial :

... um tipo de módulo é o driver de dispositivo, que permite ao kernel acessar o hardware conectado ao sistema.

Portanto, se tentarmos desenhar uma árvore, teremos o "Driver de dispositivo" que herda do módulo (estende) e que possui características mais específicas, entre as quais encontramos "acesso ao hardware" ...

user1847726
fonte
Isso está apenas parcialmente correto. O driver é um objeto de uma classe na hierarquia (sim, o design interno do Linux, como a maioria dos sistemas operacionais atuais, é orientado a objetos). Mas esse driver pode ser um módulo (carregável em tempo de execução) ou compilado no kernel. Não há (ou muito pouca) diferença entre as alternativas, em termos de código.
vonbrand
4

Um módulo do kernel pode não ser um driver de dispositivo.

"Driver do kernel" não é um termo bem definido, mas vamos tentar.

Este é um módulo do kernel que não conduz nenhum hardware e, portanto, não pode ser considerado razoavelmente um "driver de dispositivo":

#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("GPL");

static int myinit(void)
{
    printk(KERN_INFO "hello init\n");
    return 0;
}

static void myexit(void)
{
    printk(KERN_INFO "hello exit\n");
}

module_init(myinit)
module_exit(myexit)

Após a compilação, você pode usá-lo com:

insmod hello.ko

e imprime hello initpara dmesg.

No entanto, existem módulos do kernel que não são drivers de dispositivo, mas são realmente úteis, por exemplo, módulos que expõem informações de depuração / desempenho do kernel.

Drivers de dispositivo geralmente também são módulos do kernel.

Um exemplo de algo que é um "driver de dispositivo" é um pouco mais difícil de gerar, pois requer um hardware para dirigir e as descrições de hardware tendem a ser complicadas.

No entanto, usando o QEMU ou outros emuladores, podemos construir modelos de software de hardware real ou simplificado, o que é uma ótima maneira de aprender a conversar com o hardware. Aqui está um exemplo simples de um driver de dispositivo PCI mínimo: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/hello.c

Vemos então que, no x86, conversar com o hardware se resume a:

Em geral, essas operações não podem ser realizadas a partir da terra do usuário, conforme explicado em: Qual é a diferença entre o espaço do Usuário e o espaço do Kernel? No entanto, existem algumas exceções: https://stackoverflow.com/questions/7986260/linux-interrupt-handling-in-user-space .

O kernel oferece APIs de nível superior para tornar essa interação de hardware mais fácil e mais portátil:

  • request_irq lidar com interrupções
  • ioreadX mapeamento de memória IO
  • interfaces de nível ainda mais alto para protocolos populares como PCI e USB
Ciro Santilli adicionou uma nova foto
fonte
0

Minha resposta vai com Jim. Um driver do kernel é um programa (módulo do kernel) projetado para conduzir uma peça de hardware. A saída lspci diz que a nvidia é o driver do kernel, pois é o loadedmódulo do dispositivo. Junto com ele vem outros módulos de kernel disponíveis.

Vou acrescentar que os comandos no linux para listar e remover drivers são lsmode rmmodrespectivamente. O que diz listar módulo e remover módulo.

paintbox
fonte
0

Todos os drivers são módulos. Nem todos os módulos são drivers.

Módulos podem ser inseridos em tempo de execução. Módulos / Drivers também podem ser compilados estaticamente, juntamente com o kernel.

O módulo típico init possui

module_init(init_fn);
init_fn()
{
   /* some code */
}

O mesmo módulo pode ser um driver

module_init(init_fn);
init_fn()
{
   device_register(&device);
   /* some code */
}
Prabagaran
fonte
8
Os drivers nem sempre são módulos, eles podem ser incluídos na imagem principal do kernel.
Gilles 'SO- stop be evil'
3
@Prabagaran: "Todos os drivers são módulos. Todos os módulos não são drivers." Isso é contraditório. Em termos matemáticos, o que você está dizendo é D -> M e M ->! D. Isso permite D e! D.
Francesco Turco
2
Eu acho que ele quer dizer "Todos os drivers são módulos. Nem todos os módulos são drivers".
Renan
4
@ Renan: Isso seria correto, mas se você olhar o histórico de edições para esta resposta, alguém já tentou consertar o erro e o autor o reverteu. Normalmente, eu editaria apenas para corrigir o erro e seguir em frente, mas neste caso eu coloquei -1 porque está errado e confunde o problema.
Caleb
Pelo que me lembro (há algum tempo não mexo), existem alguns drivers que não podem ser construídos como módulos carregáveis. Pareço me lembrar de outros que só podem ser manipulados como módulos.
vonbrand