8.10. Compilando o núcleo
Os núcleos fornecidos pelo Debian incluem o maior número de recursos possível, assim como o máximo de drivers, para cobrir o mais amplo espectro de configurações de hardware. É por isso que alguns usuários preferem recompilar o núcleo, e assim, incluir apenas o que eles precisam especificamente. Existem duas razões para essa escolha. Primeiro, talvez seja para otimizar o consumo de memória, já que o código do núcleo, mesmo nunca sendo usado, ocupa memória para nada (e nunca "cai" no espaço swap, já que é a RAM real que ele usa), o que pode comprometer o desempenho de todo o sistema. Um núcleo compilado localmente pode também limitar o risco com problemas de segurança já que apenas uma fração do código do kernel é compilado e rodado.
A recompilação do kernel também é necessária se você quer usar certas características que só estão disponíveis através de patches (e portanto não incluídas na versão padrão do kernel).
8.10.1. Introdução e Pré-requisitos
Obviamente o Debian gerencia o núcleo na forma de pacote, que não é como os núcleos tem sido tradicionalmente compilados e instalados. Como o núcleo se mantém no controle do sistema de empacotamento, ele pode ser removido de maneira limpa, ou implantado em várias máquinas. Além do mais, os scripts associados com esses pacotes automatizam a interação com o carregador de inicialização e o gerador de initrd.
Os fontes do desenvolvedor principal do Linux contém tudo o que é necessário para construir um pacote Debian do núcleo. Mas você ainda precisa instalar o build-essential para garantir que você tem as ferramentas necessárias para construção de um pacote Debian. Além do mais, a etapa de configuração do núcleo requer o pacote libncurses-dev (anteriormente libncurses5-dev, que agora é um pacote de transição) . E finalmente, o pacote fakeroot irá permitir a criação de um pacote Debian sem usar os direitos de administrador.
8.10.2. Pegando os Fontes
Como tudo mais que pode ser útil em um sistema Debian, os fontes do kernel Linux estão disponíveis em um pacote. Para obtê-los, apenas instale o pacote
linux-source-versão. O comando
apt search ^linux-source
lista as várias versões do kernel empacotadas pelo Debian. A última versão está disponível na distribuição
Unstable: você pode obtê-la sem muitos riscos (especialmente se o seu APT está configurado de acordo com as instruções em
Seção 6.2.6, “Trabalhando com Distribuições Diversas”). Note que o código fonte contido nesses pacotes não correspondem precisamente com o que é publicado pelo Linus Torvalds e o desenvolvedores do kernel; como todas as distribuições, o Debian aplica inúmeros patches, que podem (ou não) serem incorporados na versão upstream do Linux. Essas modificações incluem backports de correções/recursos/drivers de novas versões do kernel, novos recursos ainda não (totalmente) inseridos na árvore do upstream do Linux, e, às vezes, até nas alterações específicas do Debian.
O restante desta seção foca na versão 5.10 do kernel Linux, mas os exemplos podem, é claro, ser adaptados a versão em particular do kernel que você quiser.
Nós assumimos que o pacote linux-source-5.10 foi instalado. ele contém o /usr/src/linux-source-5.10.tar.xz
, um arquivo compactado dos fontes do kernel. Você deve extrair esses arquivos em um novo diretório (não diretamente sob /usr/src/
, já que não é necessário permissões especiais para compilar o kernel Linux): ~/kernel/
é o apropriado.
$
mkdir ~/kernel; cd ~/kernel
$
tar -xaf /usr/src/linux-source-5.10.tar.xz
Para construir um kernel a partir das fontes puras, simplesmente descarregue o tarball da versão de sua escolha do
kernel.org
, verifique a integridade após importar a chave dos mantedores do kernel, e depois proceda como se descreve nos seguintes capítulos-
8.10.3. Configurando o Núcleo
O próximo passo consiste da configuração do núcleo de acordo com suas necessidades. O procedimento exato depende dos objetivos.
Quando recompilamos uma versão mais recente do núcleo (possivelmente com um patch adicional), a configuração, provavelmente, será mantida o mais próximo possível daquela proposta pelo Debian. Nesse caso, e ao invés de reconfigurar tudo a partir do zero, será suficiente copiar o arquivo
/boot/config-versão
(a versão é aquela do núcleo atualmente usado, a qual pode ser encontrada com o comando
uname -r
) no arquivo
.config
dentro do diretório contendo os fontes do núcleo. Certifique-se de ler a barra lateral
DICA debian/certs/debian-uefi-certs.pem
ausente neste caso.
$
cp /boot/config-5.10.0-8-amd64 ~/kernel/linux-source-5.10/.config
A menos que você precise mudar a configuração, você pode parar por aqui e pular para
Seção 8.10.4, “Compilando e Construindo um Pacote”. Se você precisa mudá-la, por outro lado, ou se você decidir reconfigurar tudo a partir do zero, você precisa dedicar um tempo para configurar seu núcleo. Existem varias interfaces dedicadas no diretório do fonte do núcleo que podem ser usadas executando o comando
make alvo
, aonde
alvo é um dos valores descritos abaixo.
0 make menuconfig
compila e executa uma interface de modo texto (é aqui que o pacote libncurses-dev é necessário) a qual permite a navegação pelas opções disponíveis em uma estrutura hierárquica. Pressionar a tecla Espaço muda o valor da opção selecionada, e Enter valida o botão selecionado no pé da tela; Select returna ao sub menu selecionado; Exit fecha a tela corrente e volta para cima na hierarquia; Help irá exibir informações mais detalhadas sobre a função da opção selecionada. As setas permitem mover pela lista de opções e botões. Para sair do programa de configuração, escolha Exit no menu principal. O programa então oferece salvar as alterações que você fez; aceite se você estiver satisfeito com suas escolhas.
Outras interfaces tem características semelhantes, mas elas trabalham com interfaces gráficas mais modernas; como a make xconfig
, a qual usa a interface gráfica Qt, e a make gconfig
, a qual usa GTK+. A primeira requer qtbase5-dev, enquanto a última depende de libglade2-dev e libgtk2.0-dev.
Ao usar uma dessa interfaces de configuração, sempre é uma boa ideia iniciar a partir de uma configuração padrão razoável. O núcleo prove tais configurações em arch/arch/configs/*_defconfig
e você pode colocar sua configuração selecionada no lugar com um comando como make x86_64_defconfig
(no caso de um PC de 64-bit) ou make i386_defconfig
(no caso de um PC de 32-bit).
8.10.4. Compilando e Construindo um Pacote
Uma vez que a configuração do núcleo esteja pronta, um simples make deb-pkg
gerará até 5 pacotes Debian:
- linux-image-versão
contém a imagem do núcleo ("kernel") e os módulos associados,
- linux-headers-versão
contém os arquivos de cabeçalho necessários para criar módulos externos,
- linux-firmware-image-versão
contém os arquivos de firmware necessários para alguns controladores (este pacote poderia faltar quando se constrói desde as fontes do núcleo fornecidas pelo Debian),
- linux-image-versão-dbg
contém os símbolos de depuração para a imagem do kernel e seus módulos (criados apenas se CONFIG_DEBUG_INFO=y
), e
- linux-libc-dev
contém cabeçalhos relevantes para algumas bibliotecas do espaço de usuário como GNU glibc.
A versão é definida pela concatenação da versão do upstream (como definido pelas variáveis VERSION
, PATCHLEVEL
, SUBLEVEL
e EXTRAVERSION
no Makefile
), do parâmetro de configuração LOCALVERSION
, e da variável de ambiente LOCALVERSION
. A versão do pacote reusa a mesma cadeia de caracteres da versão com uma revisão adicionada, que é regularmente incrementada (e armazenada em .version
), exceto se você sobrescrever ela com a variável de ambiente KDEB_PKGVERSION
.
$
make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=$(make kernelversion)-1
[...]
$
ls ../*.deb
../linux-headers-5.10.46-falcot_5.10.46-1_amd64.deb
../linux-image-5.10.46-falcot_5.10.46-1_amd64.deb
../linux-image-5.10.46-falcot-dbg_5.10.46-1_amd64.deb
../linux-libc-dev_5.10.46-1_amd64.deb
Todo o processo requer uns 20 GB de espaço livre, pelo menos 8 GB de RAM e várias horas de compilação (utilizando um núcleo) para um kernel Debian amd64. Estes requisitos podem-se reduzir drasticamente desabilitando a informação de depuração usando CONFIG_DEBUG_INFO=n
, mas isto fará impossível rastrear erros do kernel ("oops") usando gdb
e também deterá a criação do pacotelinux-image-versão-dbg.
8.10.5. Compilando Módulos Externos
Alguns módulos são mantidos fora do núcleo Linux oficial. Para usá-los, eles devem ser compilados a parte do referido núcleo. Um número de módulos de terceiros comuns são fornecidos pelo Debian em pacotes dedicados, tais como o vpb-driver-source (módulos extra para o hardware de telefone Voicetronix) ou leds-alix-source (drivers de placas PCEngines ALIX 2/3).
Esses pacotes são muitos e variados, o apt-cache rdepends module-assistant $
pode mostrar a lista fornecida pelo Debian. No entanto, uma lista completa não é particularmente útil, pois não há nenhuma razão particular para compilar módulos externos, exceto quando você sabe que precisa dela. Nesses casos, a documentação do dispositivo normalmente detalha o(s) módulo(s) específico(s) de que ele precisa para funcionar no Linux.
Por exemplo, vamos dar uma olhada no pacote dahdi-source: após a instalação, um .tar.bz2
dos fontes do módulo é armazenado em /usr/src/
. Embora nós possamos extrair manualmente o tarball e construir o módulo, na prática nós preferimos automatizar tudo isso usando a estrutura DKMS (Dynamic Kernel Module Support). A maioria dos módulos oferecem a integração DKMS necessária em um pacote terminando com o sufixo -dkms
. No nosso caso, instalar o dahdi-dkms é tudo que é preciso para compilar o módulo do kernel para o kernel atual, incluindo também o pacote linux-headers-* associado ao núcleo instalado. Por exemplo, se você usa o linux-image-amd64, você deve também instalar o linux-headers-amd64.
$
sudo apt install dahdi-dkms
[...]
Setting up dkms (2.8.4-3) ...
Setting up linux-headers-5.10.0-8-amd64 (5.10.46-4) ...
/etc/kernel/header_postinst.d/dkms:
dkms: running auto installation service for kernel 5.10.0-8-amd64:.
Setting up dahdi-dkms (1:2.11.1.0.20170917~dfsg-7.4) ...
Loading new dahdi-2.11.1.0.20170917~dfsg-7.4 DKMS files...
Building for 5.10.0-8-amd64
Building initial module for 5.10.0-8-amd64
Done.
dahdi_dummy.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/5.10.0-8-amd64/updates/dkms/
dahdi_dynamic_eth.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/5.10.0-8-amd64/updates/dkms/
[...]
DKMS: install completed.
$
sudo dkms status
dahdi, 2.11.1.0.20170917~dfsg-7.4, 5.10.0-8-amd64, x86_64: installed
$
sudo modinfo dahdi_dummy
filename: /lib/modules/5.10.0-8-amd64/updates/dkms/dahdi_dummy.ko
license: GPL v2
author: Robert Pleh <robert.pleh@hermes.si>
description: Timing-Only Driver
depends: dahdi
retpoline: Y
name: dahdi_dummy
vermagic: 5.10.0-8-amd64 SMP mod_unload modversions
parm: debug:int
8.10.6. Aplicando um Patch ao Núcleo
Alguns recursos não são incluídos no kernel padrão devido a falta de maturidade ou algum desentendimento entre os mantenedores do kernel. Tais recursos podem ser distribuídos através de patches, e assim, qualquer um está livre para aplicá-los aos fontes do kernel.
O Debian às vezes fornece alguns desses patches em pacotes linux-patch-*, mas eles geralmente não chegam a versões estáveis (às vezes pelos mesmos motivos que eles não são combinados no kernel upstream oficial). Esses pacotes instalam arquivos no diretório /usr/src/kernel-patches/
.
Para aplicar um ou mais desses patches instalados, use o comando patch
no diretório dos fontes, e então, inicie a compilação do kernel como descrito acima. A seguir há um exemplo antigo usando linux-patch-grsecurity2 e linux-source-4.9.
$
cd ~/kernel/linux-source-4.9
$
make clean
$
zcat /usr/src/kernel-patches/diffs/grsecurity2/grsecurity-3.1-4.9.11-201702181444.patch.gz | patch -p1
Note que um patch(qualquer um) talvez não necessariamente funcione com todas as versões do núcleo; é possível que o patch
falhe ao aplicá-lo nos fontes do núcleo. Uma mensagem de error será exibida e informará alguns detalhes sobre a falha; neste caso, referencie a documentação disponível no pacote Debian do patch (no diretório /usr/share/doc/linux-patch-*/
). Na maioria dos casos, o mantenedor indica para qual versão do núcleo o patch é feito.