O que é um kernel:
É o componente central do sistema operacional da maioria dos computadores, a função principal e razão existencial é fazer a interface entre os processos e o hardware.
![]()
Existem alguns tipos de kernel, abaixo segue a definição de três deles.
Monolitico: Todas as funcionalidades principais do sistema operacional vão dentro do kernel, dentro de um processo especial que tem diversos privilégios, costuma ter mais desempenho devido ter mais privilégios e não realizar demasiadas trocas de contexto que um do tipo MicroKernel porém perde em relação em segurança e estabilidade.
MicroKernel: Tenta retirar os processos do processo principal, como se fosse vários kernels operando em uma unica causa, assim a segurança aumenta devido ao fato que uma falha critica em algum ponto de execução não derrubaria o sistema inteiro porém o desempenho é sacrificado já que ele opera com menos privilégios e ocorre mais trocas de contextos que um kernel monolitico.
ExoKernel: O kernel é minimo e as aplicações “conversam” mais diretamente com o hardware, obviamente essa definição é bem “forçada”.

Compilando um Kernel
Basicamente são 3 etapas para se compilar um kernel, segue:
- Limpeza
- Configuração
- Compilação
- Instalação
Então é o seguinte, existem alguns motivos para se querer compilar um kernel, acredito que giram em torno de compatibilidade no sentido de módulos/drivers, talvez hardening por performance algo como lowlatency ou simplesmente porquê você ta afim.
Abaixo vou descrever os passos para se compilar um kernel.
Mas antes segue alguns requisitos que eu encontrei e tive que instalar no sistema antes de realizar os proximos procedimentos, eu to num CentOS então os requisitos do debian eu não pesquisei mas provavelmente são os mesmos porém o nome dos pacotes devem ser diferentes.
## Debian:
# apt-get install build-essential ncurses-devel bc gcc libssl-dev libelf-dev,
## RedHat:
# yum groupinstall "Development Tools"
# yum install kernel-devel kernel-headers ncurses-devel libelf-dev libelf-devel bc openssl-devel
Caso vocẽ não for utilizar a versão atual do kernel que está rodando no sistema, será necessário realizar o download do kernel desejado no seguinte site www.kernel.org
O diretório qual contém os sources do kernel geralmente é /usr/src/ então quando você realizar o download do kernel, descompate ele e coloque nesse diretório.
Antes de configurar o kernel é necessário realizar a limpeza, remover arquivos de compilações anteriores, esse procedimento pode ser feito com os seguintes comandos:
# make mrproper ## -> Apaga os arquivos gerados anteriormente assim como arquivos de configuração.
# make clean ## -> Apaga apenas os arquivos compilados anteriormente, preservando os arquivos de configuração.
É recomendado a utilização do mrproper.
Agora é a hora que é necessário realizar a configuração antes de compilar, existem algumas formas de se realizar as configurações, basicamente todas elas vão gerar um .conf no diretório, para realizar as configurações obviamente você precisa estar dentro do diretório do kernel que vai compilar.
Os seguintes utilitários podem ser utilizados:
- make config
- make xconfig
- make menuconfig
- make gconfig
O item da bolinha 2 e 4 utilizam a interface gráfica, eu não fui por eles, eu fui na primeira tentativa pelo make config e eu espero que você não seja igual a mim que sai fazendo as coisas sem terminar o parágrafo porque foi uma péssima ideia usar o make config, ele literalmente te pergunta todas as opções possíveis de configuração, eu basicamente coloquei o mouse em cima do enter pra fazer peso e deixei ele indo nas respostas default.
Uma melhor opção pra interface texto é a make menuconfig, ela faz um menu pra você padrão miçanga dos anos 1980 e você pode navegar pelo menu e gerar o .conf e sair em menos de 2 minutos. então é isso, ele depende do ncurses-devel se não me engano então instale antes de executar, caso esqueça, vocẽ vai perceber em breve.
Para realizar as configurações, utilize o make menuconfig da seguinte forma:
# make menuconfig
Eu espero que você saiba o que está fazendo pois isso é configuração do kernel, então é esperado que você saiba, sei lá.
Posteriormente a realização da configuração, vem a parte da compilação. A compilação é relativamente simples quando não se tem nenhum problema, basicamente você vai criar a imagem que pode ser zImage ou bzImage, zImage é referente à imagens pequenas até 512kb e bzImage tem b de Big zImage qual não tem limitação de tamanho, então essa é a forma que nós vamos fazer, tem outras formas claro, como empacotar o kernel e gerar um .deb/.rpm/.tar para distribuir entre computadores de hardware semelhante.
Então basicamente é executar os seguintes comandos:
# make bzImage ## -> Vai criar uma imagem em arch/x86/boot/bzImage, você precisara mover ela manualmente para /boot/ mas depois eu explico isso.
# make modules ## -> Vai compilar os módulos necessários, nem todos os módulso são internos ao kernel, alguns são externos.
# make modules_install ## -> Vai instalar os módulos, se não me engano fica em /lib/modules/
Uma alternativa ao bzImage seriam adotar o empacotamento do kernel. Empacotamento de kernel é interessante onde o hardware é semelhante, por exemplo, meu ambiente de virtualização, então eu gero o pacote .rpm e consigo distribuir dentro da minha infraestrutura, isso evitaria a reconfiguração/compilação do kernel em cada servidor. Para realizar isso pode-se realizar os seguintes utilitários no lugar do make bzImage:
- make rpm-pkg -> Gera um pacote RPM compilado e com código fonte.
- make binrpm-pkg -> Gera um pacote RPM compilado.
- make deb-pkg -> Gera um pacote compilado Deb;
- make tar-pkg -> Gera um arquivo Tar sem compressão
- make targz-pkg -> Gera um arquivo Tar com compressão gzip;
- make tarbz2-pkg -> Gera um arquivo Tar com compressão bzip2;
Então executando make rpm-pkg você estaria gerando um .rpm do kernel. Esse pacote pode ser utilizado nos outros servidores para atualizar o kernel, segue demonstração:
# Copiando o pacote para o outro servidor.
[root@cobaia-one /]# scp /root/rpmbuild/RPMS/x86_64/kernel-4.14.13-1.x86_64.rpm operador@10.0.0.21:~/
operador@10.0.0.21's password:
kernel-4.14.13-1.x86_64.rpm 100% 496MB 45.3MB/s 00:10
# E então no servidor de destino basta utilizar o rpm -ivh para realizar a instalação do novo kernel.
[root@webserver centos]# rpm -ivh /home/operador/kernel-4.14.13-1.x86_64.rpm
Preparing... ################################# [100%]
Updating / installing...
1:kernel-4.14.13-1 ################################# [100%]
# Verificando a versão do kernel atual:
[root@webserver centos]# uname -r
3.10.0-693.11.6.el7.x86_64
# O kernel atual é o 3.10.0-693, vamos dar um reboot e verificar se ele atualizou para o 4.14.13
[root@webserver centos]# init 6
# No reboot eu tive que entrar no grub2 na hora de escolher o kernel, selecionando o kernel adequado o boot ocorre normalmente e então:
[root@webserver centos]# uname -r
4.14.13
Depois da compilação, se todos os comandos anteriores foram OK agora é a hora da instalação do kernel. O primeiro passo é gerar o initramfs, o initramfs é um pseudo sistema de arquivos que vai conter os módulos pra poder reconhcer o disco do sistema, então pro kernel montar o disco ele precisa ter uns módulos iniciados, então repetindo, esses módulos para montar o disco estão no initramfs, então o initramfs é montado primeiro para poder carregar os módulos para montar o sistema e depois é dado meio que um chroot pra dentro do sistema.
Para criar o initramfs é necessário realizar uns passos que seguem abaixo.
Copiar o bzImage para dentro do /boot/ respeitando opcionalmente a nomemclatura que seria vmlinuz.<Versão Principal>..<Número de revisão principal, número de revisão secundário e correções Urgentes. Então são 4 númerais contudo geralmente são 3 números separados por pontos e em alguns teriamos uma correção urgente que deixaria com 4 números. Um outro arquivo que você precisará copiar é o System.map para dentro do /boot/ também, é bom renomear ele para algo do tipo System.map-4.14.13 para ficar fácil pra você identificar, coloque a mesma versão do kernel.
[root@cobaia-one linux-4.15-rc7]# cp arch/x86/boot/bzImage /boot/vmlinuz-4.15.rc7
Então ta na hora de gerar o initramfs,
-
- mkinitrd
- mkinitramfs
- dracut
Eu vou usar o dracut porquê não gostei dos outros dois, no centOS que to testando nem tem o mkinitramfs, então vamos lá.
Caso você for compilar a mesma versão do kernel, o initramfs talvez sobreescreva, então faça um backup da seguinte forma:
# cp /boot/initrd.$(uname -r).img /root
Como não é o meu caso, vamos então com o dracut
[root@cobaia-one modules]# dracut -f /boot/initramfs-4.15.rc7.img 4.15.rc7
O Dracut vai gerar o initramfs, um dos programas que ele executa é o depmod que vai verificar as dependências de módulos do kernel e etc. O comando depmod verifica as dependências dos módulos do kernel e grava o resultado no arquivo /lib/modules//modules.dep.
Falando em dependência de módulos podemos citar o DKMS, que é um programa/framework que permite gerar módulos do kernel do linux cujos fontes residam fora da árfore de fontes. O conceito é ter poder ter os módulos automaticamente reconstruídos quando uma nova versão do kernel é instalada. Para mais informações clique aqui.
Depos de gerado o initramfs, temos que atualizar o grub2 para que reconheça o kernel novo no próximo reboot, então o comando segue:
# grub2-mkconfig -o /boot/grub2/grub.cfg
Esse comando vai reconhecer cara initramfs e cada imagem do kernel no diretório /boot, então se o seu não for reconhecido provavelmente existe um problema.
Então dê um reboot maneiro e no menu do grub e selecione o kernel que você compilou e se tudo estiver correto o boot vai ocorrer normalmente.
Esse tópico ainda está em estudo então provavelmente terá atualizações no paper em breve.
Fontes:
https://en.wikipedia.org/wiki/Exokernel
https://pt.stackoverflow.com/questions/114911/quais-as-diferen%C3%A7as-entre-kernel-e-micro-kernel
https://imasters.com.br/infra/linux/compilando-kernel-linux-em-debian-e-ubuntu/?trace=1519021197&source=single
https://wiki.centos.org/TipsAndTricks/CreateNewInitrd
https://wiki.centos.org/TipsAndTricks/CreateNewInitrd
https://askubuntu.com/questions/408605/what-does-dkms-do-how-do-i-use-it
https://edpsblog.wordpress.com/2015/04/02/how-to-empacotamento-de-kernel-no-debian-definitivo/
