201.2 Compilando o Kernel
Para compilar seu próprio kernel você só precisa fazer três etapas: baixar o código fonte, ajustar a configuração de build de acordo com o hardware que pretende suportar e, por fim, compilar/instalar. O fluxo típico é o seguinte, e vale tanto para Debian/Ubuntu quanto para a família Red Hat:
# Debian/Ubuntu
sudo apt update
sudo apt install -y build-essential
# RHEL/Fedora/CentOS/Alma/Rocky
sudo dnf groupinstall "Development Tools"
O processo de build usa ferramentas de "tradução" para conseguir compilar o Kernel (também conhecido como parsers, que são Bison, Flex...), exige bibliotecas para a interface ncurses dos menus de configuração, além de cabeçalhos ELF, utilitários de criptografia e uma calculadora de precisão (bc
) usados nos scripts Makefile. Precisamos instalar os pacotes abaixo para que seja possível compilar o Kernel, como explicado acima.
# comum em distribuições Debian-like
sudo apt install -y bison flex libncurses-dev libelf-dev bc libssl-dev
Se sua distribuição for Red Hat-like, muitos desses itens já vêm com Development Tools, o que faltar pode ser instalado individualmente (ncurses-devel
, elfutils-libelf-devel
, openssl-devel
, etc.).
O kernel oferece várias interfaces para selecionar quais módulos vamos colocar ou não no nosso Kernel compilado, além de outras opções. Essas interfaces podem ser:
make menuconfig
(ncurses): Funciona em qualquer terminal (requerlibncurses-dev
).make xconfig
(Qt): Interface gráfica; instalepkg-config
,g++
eqt5-base-dev
(oulibqt4-dev
em sistemas mais antigos).make gconfig
(GTK): Alternativa em GTK2, precisa delibgtk2.0-dev
,libglib2.0-dev
elibglade2-dev
.
Veja a relação de pacotes abaixo, na última linha, você encontrará todos os pacotes que devam ser instalados, mas no começo, terá uma explicação simples para cada pacote.
## Debian
## Para usar o xconfig (Qt) baixe os pacotes abaixo:
$ sudo apt install -y pkg-config g++ libqt4-dev bison flex
## Para usar o gconfig (GTK) baixe os pacotes abaixo:
$ sudo apt install -y libgtk2.0-dev libglib2.0-dev libglade2-dev
Configurando o Ambiente
Existem várias formas de compilar o Kernel, vou tentar passar por elas e demonstrar a melhor forma. Antes de começar a compilar o Kernel de fato, vamos preparar o ambiente da compilação:
# Entre em '/usr/src':
$ cd /usr/src
# Agora vamos baixar o código fonte do Kernel (no caso a versão estável do momento):
$ sudo wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.14.8.tar.xz
# Vamos descompactar usando o 'tar':
$ sudo tar xvf linux-5.14.8.tar.xz
# Crie um link simbólico apontando para o diretório do novo Kernel,
# isso vai facilitar nosso trabalho:
$ sudo ln -s linux-5.14.8 linux
# Entre na pasta do Kernel novo:
$ cd linux
Para compilar o kernel você precisa, antes de tudo, gerar um arquivo de configuração que diga ao sistema de build quais módulos, subsistemas e opções serão incluídos. Esse arquivo chama-se .config
e fica na raiz do diretório onde está o código fonte. Cada linha tem o formato CONFIG_OPÇÃO=y/m/n
, e o Makefile principal vai ler esse arquivo para decidir o que compilar, que flags passar ao GCC, que módulos instalar em /lib/modules/<versão>/
e assim por diante.
Para criar esse .config
podemos fazer de duas formas, mais conhecidas são usando o make config
e o make menuconfig
, além desses dois, você ainda pode usar make xconfig
ou make gconfig
.
Ao executar qualquer um dos make
acima, o sistema fará algumas perguntas (via linha de comando ou menu). Ao finalizar todas as perguntas e/ou configurações do que incluir ou não no Kernel, o sistema vai salvar tudo no .config
. Na próxima vez que você usar o make
, o próprio Makefile principal detecta a presença (ou mudança) desse .config
, gera as dependências (include/config/
e autoconf.h
) e então começa a compilar.
Na hora de escolher o que entra no kernel, cada item da árvore Kconfig declara o tipo de build que aceita. Em termos práticos você verá três situações:
Kernel-only (built-in)
Aparece no menu com apenas duas opções:<*>
para habilitado no Kernel ou< >
para quando não for carregado no Kernel. Se marcar<*>
a funcionalidade é compilada diretamente no binário do kernel. Se deixar em branco ela fica de fora. Não existe modo módulo para esse caso. Exemplos comuns são o agendador do kernel ou o driver "virtio-mmio" em arquiteturas que exigem inicialização precoce.Modules-only
São funcionalidades que só podem ser usadas no Kernel como módulos. Aparece no menu com apenas duas opções:<M>
para carregado como módulo ou< >
para quando não for carregado no Kernel. Ao marcar M o sistema gera um arquivo.ko
dentro de/lib/modules/<versão>/
, esse módulos não podem ser compilados como Kernel-only.Tristate (built-in ou módulo)
São funcionalidades que podemos escolher habilitar como módulo (<M>
), habilitar diretamente no kernel como built-in (<*>
) ou desativar.
Internamente o Kconfig deixa essas escolhas como o exemplo abaixo dentro de .config
:
CONFIG_FOO=y
→ built-inCONFIG_FOO=m
→ módulo externo# CONFIG_FOO is not set
→ ausente
Para relembrar isso, consulta a seção módulos da LPIC-1.
Formas de configurar o ambiente para a compilação
make config
É o modo mais root de configurar um ambiente para compilação, nele vamos responder o que colocar ou não junto com o Kernel, mas vamos responder pergunta por pergunta, no total são mais de 100 perguntas.
make menuconfig
Com isso será exibido um menu via cli para que possamos marcar e desmarcar os módulo que queremos ou não no Kernel. Vamos ver como as opções são apresentadas:
# Módulo será Built-in:
[*] built-in
# Módulo será removido da compilação:
[ ] excluded
# Módulo será carregado como um módulo:
<M> module
# Módulo será carregado como Built-in:
<*> moduleVocê pode clicar em
Save
(use oenter
para selecionar), repondaYes
para salvar, toda essas perguntas serão salvas num arquivo chamado.config
. Outra opção que temos aqui é oload
, usado para importar um.config
já existente.
make oldconfig
Usado quando já temos um
.config
, esse arquivo pode ser uma instalação já padronizada, ou podemos pegar de outro Kernel que já foi configurado. Caso exista alguma nova pergunta que ainda não tem resposta, o configurador do ambiente irá fazer essa pergunta, isso acontece principalmente em novos Kernels.make xconfig
Utiliza um instalador gráfico baseado em Qt, é similar ao menuconfig, mas utiliza a interface gráfica.
make gconfig
Utiliza um instalador gráfico baseado em GTK, é similar ao menuconfig, mas utiliza a interface gráfica.
Makefile
Para a maioria dos programas em C que você baixa, existe um script chamado configure
, a função dele é vasculhar o sistema, verifica dependências e, ao final, cria (ou atualiza) um arquivo Makefile
adaptado ao seu ambiente local. Esse Makefile é efêmero, ou seja, em cada execução de ./configure
, você pode fornecer opções diferentes para o Makefile.
No Kernel, esse script não está disponível, já que o código fonte do Kernel vem com o Makefile para podemos iniciar a compilação, só precisando gerar o .config
.
Uma das opções que podemos alterar no Makefile é o EXTRAVERSION =
, ele é usado para inserir um sufixo ao número de versão do Kernel, criando uma versão nossa por exemplo. A string final que aparece em uname -r
é montado assim: KERNELRELEASE = VERSION.PATCHLEVEL.SUBLEVEL EXTRAVERSION CONFIG_LOCALVERSION
. Vou deixar essa opção como EXTRAVERSION = -rev1
.
Além desse opção, existem outras que podemos modificar com relação a versão/nome do Kernel, a tabela abaixo exemplifica essas opções:
Campo | Valor | O que significa, resumidamente |
---|---|---|
VERSION | 5 | Versão "major", indica o release principal do kernel. Mudanças aqui tendem a ser grandes. |
PATCHLEVEL | 14 | Versão "minor", é uma atualização dentro do release acima, costuma trazer novos recursos para a versão acima. |
SUBLEVEL | 8 | Pode ser um patch ou revisão de manutenção que corrige bugs e falhas de segurança para o major.minor (exemplo, versão 5.14). |
EXTRAVERSION | -rev1 | Sufixo opcional adicionado pelo mantenedor local para distinguir builds; aparece em uname -r e cria diretório exclusivo em /lib/modules/ . |
NAME | The Linux is Crazy | Codinome divertido que a equipe do kernel associa a essa versão, é um valor puramente simbólico. |
.config
O arquivo .config
, fica na raiz do código-fonte, é nele que fica toda a configuração do que o kernel saberá fazer quando for compilado. Cada linha segue a forma CONFIG_<opção>=<valor>
, ao final, esse conjunto vira macros de pré-processador que o make
transforma em código C condicional. Você não precisa se preocupar com isso, o utilitário make...
criará esse arquivo para você (caso você não tenha).
Dentro do .config
existe uma opção chamada config_local_version
que você pode confundir o significado com EXTRAVERSION
, abaixo vemos uma explicação:
EXTRAVERSION
(Makefile)
Fica noMakefile
. É usado para identificar versões específicas do kernel base (como correções ou variações de empacotadores). Um exemplo com ele seria:5.14.8-rev1
. Afeta todos que usarem esse código-fonte.CONFIG_LOCALVERSION
(.conf)
Fica dentro do arquivo.config
. Adiciona um sufixo personalizado ao nome do kernel compilado. Mais indicado para personalizações locais, como quando você compila o kernel só para sua máquina. Pode ser usado junto doEXTRAVERSION
. O resultado é seguinte (se o EXTRAVERSION for-rev1
):5.14.8-rev1-clicraze
.
Use EXTRAVERSION
se você mantém uma versão modificada do kernel para várias máquinas ou usuários ou use CONFIG_LOCALVERSION
se quer personalizar localmente, sem alterar o Makefile principal. Vou configurar CONFIG_LOCALVERSION
com o valor -clicraze
.
Uma forma de pegar um .config
já existente é pegando do Kernel que já temos instalado:
$ ls /boot/config-$(uname -r)
/boot/config-5.4.0-86-generic
# Podemos copiar esse arquivo para a pasta onde temos o código fonte do Kernel:
$ sudo cp /boot/config-$(uname -r) .config
# Agora importe esse arquivo e salve novamente:
$ make menuconfig
## Clique em 'Load', depois 'Save' e saia.
Dessa forma, ja teremos um .config
pronto.
Como estou pegando o .config
da Canonical, eu tive que instalar alguns pacotes a mais, seguem abaixo:
apt install -y dwarves
Compilando o Kernel
Agora vamos dar início ao processo de compilação do Kernel. Para que não tenha nenhum problema na compilaçãom você precisa de no mínimo 2GB de Ram e 20GB de espaço livre em disco.
# Se você ainda não tem o '.config' gere ele com algum dos comandos abaixo:
$ make config
$ make menuconfig
$ make xconfig
$ make gconfig
$ make nconfig
# Após termos criado ou obtido o '.config', basta usar o comando abaixo para compilar o Kernel.
#
# O -j(N) significa que vamos usar N núcleos da CPU,
# bzImage é o formato do arquivo final do Kernel.
#
# Esse processo pode demorar dependendo da configuração de Hardware, então pode esperar bastante!
# Levei 25 minutos usando a conf de 10 VCPU e 7GB de Ram.
$ sudo make -j10 bzImage
Se você obter o erro abaixo, edite o .config
e deixe a opção CONFIG_SYSTEM_TRUSTED_KEYS
em branco, ficando assim CONFIG_SYSTEM_TRUSTED_KEYS=""
. O valor padrão pede um certificado que não temos.
# Erro:
DESCEND objtool
CALL scripts/atomic/check-atomics.sh
CALL scripts/checksyscalls.sh
CHK include/generated/compile.h
make[1]: *** No rule to make target 'debian/canonical-certs.pem', needed by 'certs/x509_certificate_list'. Stop.
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1858: certs] Error 2
make: *** Waiting for unfinished jobs....
Casoa compilação tenha dado certo, você verá a saída abaixo, deixarei apenas o final:
LZ4 arch/x86/boot/compressed/vmlinux.bin.lz4
MKPIGGY arch/x86/boot/compressed/piggy.S
AS arch/x86/boot/compressed/piggy.o
LD arch/x86/boot/compressed/vmlinux
ZOFFSET arch/x86/boot/zoffset.h
OBJCOPY arch/x86/boot/vmlinux.bin
AS arch/x86/boot/header.o
LD arch/x86/boot/setup.elf
OBJCOPY arch/x86/boot/setup.bin
BUILD arch/x86/boot/bzImage
Kernel: arch/x86/boot/bzImage is ready (#1)
Esse processo nos informa onde está a imagem do Kernel (arch/x86/boot/bzImage
), esse arquivo é o que vemos em /boot
com o nome de vmlinuz-*
.
Compilando os Módulos para o Kernel
Agora vamos compilar os módulos, esses que estão em .config
, nesse ponto os módulos serão Built-in ou Externos:
# Comece a conpilar os módulos, esse processo pode e vai demorar mais que o anterior, no meu caso demorou 32 minutos:
$ sudo make -j10 modules
Outras opções do MAKE
Existem outras opções do comando make
que podemos usar, veja abaixo quais são:
- make clean
Usado para limpar a compilação que foi realizada, muito útil quando temos erro durante a compilação ou caso acabe o espaço em disco.
- make mrproper
Igual a opção acima, mas remove o.config
.
make distclean
Similar a opçãomrproper
, mas remove tudo que não veio com o código fonte (bakcups, dumps, temps e etc)make localmodconfig
Cria um.config
baseado apenas nos módulos que seu sistema atual está carregando (lsmod
).make allnoconfig
Cria um.config
com tudo desativado (deixando apenas o necessário).make localyesconfig
Ativar no.config
somente o que está em uso no momento do sistema (sem suporte a módulos).
Instalação dos Módulos
Agora devemos instalar o que compilamos, no caso, o Kernel e os módulos.
Para instalar o módulos siga o processo abaixo:
# Use o comando abaixo para instalar os módulos:
$ sudo make INSTALL_MOD_STRIP=1 modules_install
Esse comando irá instalar os módulos em /lib/modules
com a versão do nosso Kernel. Esse argumento INSTALL_MOD_STRIP=1
fará com que os módulos sejam removidos após a instação, isso reduz drasticamente o tamanho do initrd
.
# Liste os módulos instalados:
$ ls -ld /lib/modules/5.14.8-rev1-clicraze/
drwxr-xr-x 3 root root 4096 Jul 2 13:04 /lib/modules/5.14.8-rev1-clicraze/
Veja este link para tentar reduzir o tamanho do initrd
, outra forma de reduzir o tamanho dele é usando um .config
com menos recursos, já que o gerado automaticamente vem com bastante coisa.
Instalação do Kernel
Para instalar o Kernel devemos ter no mínimo 1.5GB livre, caso não tenha seguido a recomendação de redução acima dará erro durante a criação do novo initd
, isso só acontece em ambientes onde o /boot
está numa partição separada e/ou com pouco espaço de armazenamento.
Para instalar o Kernel, podemos fazer de duas formas:
Usando o make
Siga os passos abaixo para instalar usando o comando
make
:$ sudo make install
sh ./arch/x86/boot/install.sh \
5.14.8-rev1-clicraze arch/x86/boot/bzImage \
System.map "/boot"
run-parts: executing /etc/kernel/postinst.d/initramfs-tools 5.14.8-rev1-clicraze /boot/vmlinuz-5.14.8-rev1-clicraze
update-initramfs: Generating /boot/initrd.img-5.14.8-rev1-clicraze
run-parts: executing /etc/kernel/postinst.d/unattended-upgrades 5.14.8-rev1-clicraze /boot/vmlinuz-5.14.8-rev1-clicraze
run-parts: executing /etc/kernel/postinst.d/update-notifier 5.14.8-rev1-clicraze /boot/vmlinuz-5.14.8-rev1-clicraze
run-parts: executing /etc/kernel/postinst.d/xx-update-initrd-links 5.14.8-rev1-clicraze /boot/vmlinuz-5.14.8-rev1-clicraze
I: /boot/vmlinuz.old is now a symlink to vmlinuz-5.4.0-216-generic
I: /boot/initrd.img.old is now a symlink to initrd.img-5.4.0-216-generic
I: /boot/vmlinuz is now a symlink to vmlinuz-5.14.8-rev1-clicraze
I: /boot/initrd.img is now a symlink to initrd.img-5.14.8-rev1-clicraze
run-parts: executing /etc/kernel/postinst.d/zz-update-grub 5.14.8-rev1-clicraze /boot/vmlinuz-5.14.8-rev1-clicraze
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.14.8-rev1-clicraze
Found initrd image: /boot/initrd.img-5.14.8-rev1-clicraze
Found linux image: /boot/vmlinuz-5.4.0-216-generic
Found initrd image: /boot/initrd.img-5.4.0-216-generic
Found linux image: /boot/vmlinuz-5.4.0-169-generic
Found initrd image: /boot/initrd.img-5.4.0-169-generic
done
# Agora reinicie e veja o novo Kernel:
$ uname -r
5.14.8-001-maddogs
Usando método manual
Siga os passos abaixo para fazer essa instalação manualmente.
# Instale o Kernel:
$ sudo cp arch/x86/boot/bzImage /boot/vmlinuz-5.14.8-rev1-clicraze
############################################
### Veja o antigo apontamento do vmlinuz ###
############################################
$ ls -lh /boot/vmlinuz
lrwxrwxrwx 1 root root 24 Sep 23 21:11 /boot/vmlinuz -> vmlinuz-5.4.0-86-generic
$ ls -lh /boot/vmlinuz.old
lrwxrwxrwx 1 root root 24 Sep 23 21:11 /boot/vmlinuz.old -> vmlinuz-5.4.0-66-generic
## Agora apague o 'vmlinuz.old':
$ sudo rm /boot/vmlinuz.old
# Renomeie o atual 'vmlinuz' para 'vmlinuz.old':
$ sudo mv /boot/vmlinuz /boot/vmlinuz.old
# Crie o apontamento para o novo Kernel:
$ cd /boot
$ sudo ln -s vmlinuz-5.14.8-rev1-clicraze vmlinuz
## Agora vamos gerar um novo 'initrd' (5.14.8-rev1-clicraze é a versão que nomeamos):
$ sudo mkinitramfs -o /boot/initrd.img-5.14.8-rev1-clicraze 5.14.8-rev1-clicraze
## Segue outro comando que podemos usar para gerar um 'initrd' (5.14.8-rev1-clicraze é a versão que nomeamos):
$ sudo update-initramfs -c -k 5.14.8-rev1-clicraze
# Agora atualize o grub:
$ sudo update-grub
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.14.8-rev1-clicraze
Found initrd image: /boot/initrd.img-5.14.8-rev1-clicraze
Found linux image: /boot/vmlinuz-5.4.0-86-generic
Found initrd image: /boot/initrd.img-5.4.0-86-generic
Found linux image: /boot/vmlinuz-5.4.0-66-generic
Found initrd image: /boot/initrd.img-5.4.0-66-generic
Found linux image: /boot/vmlinuz-5.4.0-42-generic
Found initrd image: /boot/initrd.img-5.4.0-42-generic
done
# Agora reinicie e veja o novo Kernel ativo:
$ uname -r
5.14.8-rev1-clicraze
O initramfs
originalmente é compactado com CPIO
, mas em algumas distros também podemos encontrar ele compactado com gzip
.
Initrd vs Initramfs
Ambos possuem o mesmo propósito, o initrd
ou initramfs
servem para dar suporte ao Kernel no momento da inicialização do sistema. É um filesystem temporário que é carregador na memória ram e não no disco, muitas vezes chamado de disco RAM inicial.
O initramfs ou initrd é um arquivo que contém um sistema de arquivos raiz temporário que é usado durante o processo de inicialização. O principal objetivo de um arquivo desses é fornecer os módulos necessários para que o Kernel possa acessar o sistema de arquivos raiz "verdadeiro" do sistema operacional.
Logo que o sistema de arquivos raiz fica disponível, o kernel monta todos os sistemas de arquivos configurados em /etc/fstab
e, em seguida, executa o primeiro programa, um utilitário chamado init
. O programa init
é responsável por executar todos os scripts de inicialização e daemons do sistema. Depois que o programa init é carregado, o initramfs ou initrd é removido da RAM.
Coloquei sempre os dois para que você veja que ambos possuem o mesmo objetivo, porém, com limitações. O initramfs é o sistema usado nos dias de hoje, além de ser o sucessor do initrd.
Mesmo mudando o tipo de arquitetura/conteúdo desses arquivos, você sempre verá com o nome de initrd, mesmo sendo um initramfs, em algumas distros (como o ArchLinux) podem colocar com initramfs e não mais como initrd.
initrd
Possui o tipo de sistema de arquivo sendo
ramdev
;Possui a imagem de um FileSystem, por isso precisa de pelo menos um driver que tem que estar compilado em Kernel;
Um disco criado precisa ter um tamanho fixo;
É compactado com cpio e depois com gzip.
# Verificando o tipo de arquivo:
$ file initrd.image
initrd.image: gzip compressed data, from Unix, last modified: Sun Aug 14 22:45:56 2016
# Podemos descompactar e depois desagrupar com os comandos abaixo:
$ zcat initrd.image | cpio -i
106469 blocks
# Possui a arquitetura:
$ ls -lh | grep -v initrd.image
total 20M
drwxr-xr-x 2 vagrant vagrant 4.0K Oct 12 15:12 bin
drwxr-xr-x 3 vagrant vagrant 4.0K Oct 12 15:12 conf
drwxr-xr-x 8 vagrant vagrant 4.0K Oct 12 15:12 etc
-rwxr-xr-x 1 vagrant vagrant 6.6K Oct 12 15:12 init
drwxr-xr-x 7 vagrant vagrant 4.0K Oct 12 15:12 lib
drwxr-xr-x 2 vagrant vagrant 4.0K Oct 12 15:12 lib64
drwxr-xr-x 2 vagrant vagrant 4.0K Oct 12 15:12 run
drwxr-xr-x 2 vagrant vagrant 4.0K Oct 12 15:12 sbin
drwxr-xr-x 8 vagrant vagrant 4.0K Oct 12 15:12 scripts
drwxr-xr-x 3 vagrant vagrant 4.0K Oct 12 15:12 var
# Realmente sendo um filesystem completo.
initramfs
Possui o tipo de sistema de arquivo sendo
tmpfs
;O
tmpfs
não precisa de um driver porque está sempre no Kernel;É um arquivo agrupado com
CPIO
, mas em algumas distros também podemos encontrar ele compactado comgzip
.# Verificando o tipo de arquivo:
$ file initrd.img
initrd.img: ASCII cpio archive (SVR4 with no CRC)
# Podemos desagrupar com o comando abaixo (quando é CPIO):
$ sudo cpio -i < initrd.img
62 blocks
# Possui uma arquitetura assim:
$ tree
.
├── initrd.img
└── kernel
└── x86
└── microcode
└── AuthenticAMD.bin
3 directories, 2 files
Criação de um pacote de instalação do Kernel
Com a compilação em mãos, podemos criar um pacote para facilitar a instalação dele em outras máquinas, para isso, veja abaixo:
# Criando um pacote .deb do Kernel:
$ sudo make deb-pkg
## Criando um pacote .rpm do Kernel:
$ sudo make rpm-pkg
## Criando um pacote .rpm somente com a imagem do Kernel:
$ sudo make binrpm-pkg
Os pacotes ficarão em /usr/src
.
Pacotes | Descrição |
---|---|
*.desc | Usado para realizar o checksum. |
*.orig.tar.gz | Versão original do Kernel (código fonte). |
*headers* | Cabeçalhos para o novo Kernel. |
*image* | Imagem do Kernel. |
*libc-dev | Cabeçalhos das bibliotecas. |
*amd64.deb | Pacote do Kernel que vamos usar para instalar em outras máquinas. |
DKMS
O Dynamic Kernel Module Support (DKMS) é um programa/framework que nos permite gerar módulos para o kernel do Linux, onde as fontes não residam dentro da árvore principal de fontes, ou seja, cujo as fontes que vão gerar esse módulo não façam parte das fontes do Kernel em sí. O conceito aqui é poder ter alguns módulos automaticamente reconstruídos quando uma nova versão do kernel é instalada.
Um exemplo para isso são os módulos da NVIDIA (pelo menos no ArchLinux) e o DroidCam que devemos sempre construir novos módulos toda vez que um novo Kernel é instalado; onde esse processo de reconstruir um novo módulo para o Kernel novo é completamente manual.
Com o DKMS a reconstrução é automática ao instalar um novo Kernel.
Dependendo do pacote, ele pode vir pronto para trabalhar com o DKMS, como em
package_name-dkms
, nesse caso basta instalar e já temos o suporte ao DKMS nesse pacote ou pode não existir uma versão para isso, e vamos ter que adicionar esse pacote ao DKMS manualmente.
Instale o dkms:
$ sudo apt install dkms
Vejamos algumas opções do DKMS:
# Listando o status:
$› dkms status
nvidia, 460.91.03, 5.4.0-80-generic, x86_64: installed
nvidia, 460.91.03, 5.4.0-81-generic, x86_64: installed
nvidia, 460.91.03, 5.4.0-84-generic, x86_64: installed
nvidia, 460.91.03, 5.4.0-86-generic, x86_64: installed
nvidia, 460.91.03, 5.4.0-88-generic, x86_64: installed
virtualbox, 6.1.26, 5.4.0-81-generic, x86_64: installed
virtualbox, 6.1.26, 5.4.0-84-generic, x86_64: installed
virtualbox, 6.1.26, 5.4.0-86-generic, x86_64: installed
virtualbox, 6.1.26, 5.4.0-88-generic, x86_64: installed
Para que isso funcione, é instalado em /usr/src
o código fonte do programa que queremos habilitar o suporte do DKMS, com o arquivo de configuração do DKMS: /usr/src/nvidia-460.91.03/dkms.conf
.
# listando o conteúdo:
$ cat /usr/src/nvidia-460.91.03/dkms.conf
PACKAGE_NAME="nvidia"
PACKAGE_VERSION="460.91.03"
CLEAN="make clean"
BUILT_MODULE_NAME[0]="nvidia"
DEST_MODULE_LOCATION[0]="/kernel/drivers/char/drm"
PROCS_NUM=`nproc`
[ $PROCS_NUM -gt 16 ] && PROCS_NUM=16
MAKE[0]="unset ARCH; [ ! -h /usr/bin/cc ] && export CC=/usr/bin/gcc; env NV_VERBOSE=1 \
'make' -j$PROCS_NUM NV_EXCLUDE_BUILD_MODULES='' KERNEL_UNAME=${kernelver} IGNORE_XEN_PRESENCE=1 IGNORE_CC_MISMATCH=1 SYSSRC=$kernel_source_dir LD=/usr/bin/ld.bfd modules"
BUILT_MODULE_NAME[1]="nvidia-modeset"
DEST_MODULE_LOCATION[1]="/kernel/drivers/char/drm"
BUILT_MODULE_NAME[2]="nvidia-drm"
DEST_MODULE_LOCATION[2]="/kernel/drivers/char/drm"
AUTOINSTALL="yes"
PATCH[0]="disable_fstack-clash-protection_fcf-protection.patch"
#PATCH[1]="buildfix_kernel_5.6.patch"
#PATCH_MATCH[0]="^4.[6-7]"
BUILT_MODULE_NAME[3]="nvidia-uvm"
DEST_MODULE_LOCATION[3]="/kernel/drivers/char/drm"
#PATCH[2]="buildfix_kernel_4.9_amd64_only.patch"
Dracut
O Dracut é usado para gerar uma imagem initramfs em ambientes Redhat. Similiar ao update-initramfs
(que roda em Debian Like), mas o Dracut roda em sistemas RedHat.
Antigamente se usava o
mkinitrd
no ambiente Redhat, mas hoje foi substituído pelo Dracut.