Configurando, compilando e instalando um kernel Linux personalizado

38

Gostaria de tentar usar um kernel que não seja o fornecido pela minha distribuição - de outro lugar ou como personalizado por mim. Isso é difícil ou perigoso?

Por onde começo?

Cachinhos Dourados
fonte

Respostas:

51

A construção de um kernel personalizado pode consumir muito tempo - principalmente na configuração, pois os computadores modernos podem fazer a compilação em questão de minutos - mas não é particularmente perigoso se você mantiver seu kernel atual e funcionando e não se esqueça disso. como uma opção através do seu gerenciador de inicialização (consulte a etapa 6 abaixo). Dessa forma, se o seu novo não funcionar, basta reiniciar o antigo.

Nas instruções a seguir, os caminhos dentro da árvore de origem tomam o formato [src]/whatever, onde [src]está o diretório em que você instalou a fonte, por exemplo /usr/src/linux-3.13.3. Você provavelmente deseja fazer isso, su rootpois a árvore de origem deve permanecer segura em termos de permissões de gravação (deve pertencer à raiz).

Embora algumas das etapas sejam opcionais, você deve lê-las de qualquer maneira, pois elas contêm as informações necessárias para entender o restante do processo.

  1. Baixe e descompacte o tarball de origem.

    Estes estão disponíveis no kernel.org . As mais recentes estão listadas na primeira página, mas se você olhar dentro do /pub/diretório, encontrará um arquivo que vai desde a versão 1.0. A menos que você tenha motivos especiais para fazer o contrário, é melhor escolher o "Último Estável". No momento da redação deste artigo, este era um tar.xzarquivo de 74 MB .

    Depois que o tarball é baixado, você precisa descompactá-lo em algum lugar. O lugar normal é em /usr/src. Coloque o arquivo lá e:

    tar -xJf linux-X.X.X.tar.xz
    

    Observe que as distribuições individuais geralmente recomendam o uso de um de seus pacotes de origem em vez da árvore de baunilha. Isso contém patches específicos para a distribuição, que podem ou não ser importantes para você. Também corresponderá aos cabeçalhos de inclusão do kernel usados ​​para compilar algumas ferramentas do espaço do usuário, embora elas sejam provavelmente idênticas de qualquer maneira.

    Em mais de 15 anos de construção de kernels personalizados (principalmente no Fedora / Debian / Ubuntu), nunca tive problemas ao usar a fonte vanilla 1 . Fazer isso realmente não faz muita diferença, no entanto, além do fato de que, se você quiser o kernel absolutamente mais recente, sua distribuição provavelmente ainda não o empacotou. Portanto, a rota mais segura ainda é usar o pacote distro, que deve ser instalado no /usr/src. Eu prefiro o estábulo mais recente para que eu possa agir como um porquinho da índia antes que ele seja lançado nas distros :)

  2. Comece com uma configuração básica [opcional].

    Você não precisa fazer isso - basta mergulhar de cabeça e criar uma configuração do zero. No entanto, se você nunca fez isso antes, espere várias tentativas e erros. Isso também significa ter que ler a maioria das opções (existem centenas). Uma aposta melhor é usar sua configuração existente, se disponível. Se você usou um pacote fonte de distribuição, ele provavelmente já contém um [src]/.configarquivo, para que você possa usá-lo. Caso contrário, verifique a /proc/config.gz. Este é um recurso opcional adicionado ao kernel 2.6. Se existir, copie-o para o nível superior da árvore de origem e gunzip -c config.gz > .config.

Se não existir, talvez porque essa opção tenha sido configurada como um módulo. Tente sudo modprobe configse verifique o /procdiretório config.gznovamente.

A configuração da distribuição não é muito ideal no sentido de incluir quase todos os drivers de hardware possíveis. Isso não importa muito para a funcionalidade do kernel, já que são módulos e a maioria deles nunca será usada, mas aumenta significativamente o tempo necessário para a construção. Também é estranho, pois exige que o initramfs contenha determinados módulos principais (consulte a etapa 4 abaixo). No entanto, é provavelmente um ponto de partida melhor que o padrão.

Observe que as opções de configuração mudam e mudam de uma versão do kernel para a seguinte, e quando você executa um dos make configprogramas abaixo, você .configprimeiro será analisado e atualizado para corresponder à nova versão. Se a configuração for de uma versão muito mais antiga, isso pode levar a resultados estranhos; portanto, preste atenção ao fazer a configuração. AFAIK não funcionará de maneira inversa (usando uma configuração de uma versão mais recente).

  1. Crie uma .configuração.

    [src]/.configé um arquivo de texto usado para configurar o kernel. Não edite este arquivo diretamente . Mudar opções geralmente não é uma simples questão de substituir a Ypor uma N, etc; geralmente há um conjunto de interdependências e possibilidades de ramificação. Em vez disso, você deseja usar um dos destinos de configuração do makefile do kernel (ou seja, digite make _____na linha de comando no diretório de origem de nível superior):

    • make configé o mais básico, mas provavelmente não o gosto da maioria das pessoas. É uma sequência de perguntas - muitas perguntas - e se você mudar de idéia, terá que começar de novo.

    • make oldconfigé como make configexceto, se você já possui um .configde uma versão anterior, ignorará as perguntas, exceto as referentes a novas opções. Ainda pode haver muitos deles e a maioria deles será irrelevante para você, então novamente, eu não recomendo.

    • make menuconfigé o meu (e acho que a maioria dos outros) método preferido. Ele cria e executa uma interface TUI (menus coloridos que funcionarão em um terminal). Isso requer que você tenha o -devpacote para ncurses instalado. É bastante auto-explicativo, exceto pela pesquisa que é acessível via /; a "ajuda" F1 fornece uma explicação para a opção atual. Existe uma versão alternativa make nconfig, com alguns recursos extras, em que F2 "syminfo" é o equivalente ao F1 do menuconfig.

    • make xconfigé uma interface gráfica completa. Isso requer que qmakeo -devpacote para o Qt seja instalado, pois é um programa que é compilado e construído. Se você não os estava usando anteriormente, pode ser um download substancial. O motivo pelo qual prefiro menuconfiga versão da GUI é que as hierarquias de opções são apresentadas usando telas sucessivas na primeira, mas abertas como acordeão na segunda.

    Uma das primeiras coisas que você deve (mas não precisa) fazer é adicionar uma string "Versão local" (em Configuração geral ). O motivo disso é mencionado no item 5 abaixo.

    "Labirinto" é uma boa maneira de descrever a hierarquia de opções, e entrar em detalhes com ela está muito além do escopo de uma sessão de perguntas e respostas como esta. Se você quiser se sentar e passar por tudo, reserve horas . Greg Kroah-Hartman (desenvolvedor de longa data líder para o kernel do linux) tem um livro on-line gratuito sobre o kernel (consulte Referências abaixo) que contém um capítulo sobre configuração , embora tenha sido escrito em 2006. Meu conselho é começar com uma base razoável do seu kernel de distribuição atual (conforme o item 2) e depois passe por ele e desmarque todas as coisas que você sabe que não precisa. Você provavelmente também desejará alterar algumas das opções "module" para "built-in", o que nos leva ao meu próximo ponto ...

  2. Sobre initramfs[opcional]

    Um "initramfs" é um sistema de arquivos compactado embutido no kernel e / ou carregado no momento da inicialização. Seu principal objetivo é incluir módulos que o kernel precisará antes de poder acessá-los no /lib/modulessistema de arquivos raiz - por exemplo, drivers para o dispositivo que contém esse sistema de arquivos. As distribuições sempre as usam parcialmente porque os drivers são mutuamente incompatíveis e, portanto, não podem ser todos incorporados ao kernel. Em vez disso, os apropriados para o sistema atual são selecionados de dentro do initramfs.

    Isso funciona bem e não representa nenhum tipo de desvantagem, mas é provavelmente uma complicação desnecessária ao criar seu próprio kernel. 2 O problema é que, se você não usar um initramfs, precisará garantir que os drivers do seu sistema de arquivos raiz (e do dispositivo em que ele está ligado) estejam incorporados no kernel. Em menuconfig, esta é a diferença entre uma opção M(= module) e uma opção *(= built-in). Se você não acertar, o sistema falhará no início do processo de inicialização. Portanto, por exemplo, se você possui um disco rígido SATA e um sistema de arquivos raiz ext4, precisa de drivers para aqueles embutidos. [Se alguém puder pensar em algo mais que seja essencial, deixe um comentário e eu o incorporarei aqui].

    Se você deseja usar um initramfs, precisará selecionar as opções apropriadas na Configuração geral . Existe um guia de esqueleto para a criação de um construído no kernel em [src]/Documentation/filesystems/ramfs-rootfs-initramfs.txt, mas nota que as distros não faça isso; eles usam um arquivo cpio externo compactado com gzip. No entanto, esse documento contém uma discussão sobre o que deve constar no initramfs(consulte "Conteúdo do initramfs").

  3. Crie e instale o kernel.

    O próximo passo é fácil. Para criar o kernel, basta executar makeno [src]diretório Se você estiver em um sistema com vários núcleos, poderá adicionar -j Npara acelerar as coisas, onde Nestá o número de núcleos que deseja dedicar + 1. Não há testou check. Feito isso, você pode make modules. Em uma caixa rápida, tudo isso deve levar <10 minutos.

    Se tudo correr bem make INSTALL_MOD_STRIP=1 modules_install,. Isso criará um diretório que /lib/modulescorresponda ao número da versão do kernel mais a string "Versão local" mencionada na etapa 3, se houver. Se você não usou uma string "Versão local", tenha cuidado se você já possui um kernel da mesma versão da qual você depende , porque esses módulos os substituirão. 3 INSTALL_MOD_STRIP=1 é opcional, para o significado, veja aqui .

    Você pode make installinstalar o kernel em um local padrão. Minha recomendação, no entanto, é fazer você mesmo para garantir que nenhum arquivo existente seja substituído. Olhe em [src]/arch/[ARCH]/bootum arquivo chamado bzImage4 , onde [ARCH]é x86se você estiver em um x86 ou máquina x86-64 (e algo mais se você estiver em outra coisa). Copie isso /boote renomeie-o para algo mais específico e informativo (não importa o que). Faça o mesmo [src]/System.map, mas renomeie-o de acordo com o seguinte esquema:

    System.map-[VERSION]
    

    Aqui, [VERSION]é exatamente o mesmo que o nome do diretório /lib/modulescriado pormake modules_install , que incluirá a string "Versão local", por exemplo System.map-3.13.3-mykernel,.

  4. Configure o carregador de inicialização do GRUB 2.

    Se você não estiver usando grub(a maioria dos usuários de desktop Linux), isso obviamente não se aplica a você. Você deve ter um /etc/grub.d/40_customarquivo com pouco. Caso contrário, crie-o pertencente à raiz e chmod 755(deve ser executável). Para isso, adicione:

    menuentry 'My new kernel, or whatever' {
        set root='hd0,1'
        linux /boot/[name-of-kernel] root=/dev/sda1 [other kernel options]
    }
    

    Se você estiver usando um initramfs, também deverá ter uma última linha initrd /path/to/initramfs. Cuidado com a set root=linha. O exemplo presume que o grub foi instalado na primeira partição do primeiro disco rígido (hd0,1). Se você tiver várias unidades, convém usar o UUID da partição e substituir essa linha por:

        search --no-floppy --fs-uuid --set=root [the UUID of the partition]
    

    A menos que o grub não esteja no seu sistema de arquivos raiz, isso também deve corresponder à root=diretiva na linuxlinha, que indica o seu sistema de arquivos raiz (aquele com /sbin/inite /lib/modules). A versão UUID disso é root=UUID=[the UUID].

    Você pode procurar /boot/grub2/grub.cfgpor uma pista sobre o nome do dispositivo. Aqui está um breve guia para tal no grub 2. Quando estiver feliz, corra grub2-mkconfig -o /boot/grub2/grub.cfg(mas faça o backup do seu atual grub.cfgprimeiro). Você pode editar esse arquivo e mover sua entrada para o topo. Ele ainda deve conter uma lista para a sua idade (em execução) kernel, e sua distribuição podem ter um mecanismo que duplicado uma entrada para o novo kernel automaticamente (porque foi encontrado em /boot; Fedora faz isso, portanto, usando um título distinto com menuentryum boa ideia). Você pode remover isso mais tarde se tudo der certo.

    Você também pode simplesmente inserir o menuentryno grub.cfgdiretamente, mas algumas distros o substituirão quando seu kernel for atualizado (enquanto o uso /etc/grub.d/o manterá incorporado).

    É isso aí. Tudo o que você precisa fazer agora é reiniciar. Se não funcionar, tente deduzir o problema da saída da tela, reinicie a escolha de um kernel antigo e volte para a etapa 3 (exceto use o que .configvocê já possui e ajuste-o). Pode ser uma boa ideia make clean(ou make mrproper) entre as tentativas, mas certifique-se de copiar [src]/.configprimeiro para algum backup, pois isso será apagado. Isso ajuda a garantir que os objetos usados ​​no processo de construção não sejam obsoletos.

  5. Em relação aos cabeçalhos do kernel et. al.

    Uma coisa que você provavelmente deve fazer é symlink ( ln -s -i) /lib/modules/X.X.X/sourcee /lib/modules/X.X.X/buildpara o /usr/srcdiretório em que a árvore de origem está (mantenha isso). Isso é necessário para que algumas ferramentas do espaço do usuário (e instaladores de drivers de terceiros) possam acessar a fonte do kernel em execução.

    Um problema relacionado a isso são os .harquivos /usr/includeetc. Eles mudam muito gradualmente e são compatíveis com versões anteriores . Você tem duas opções:

    • Deixe os usados ​​pela sua distribuição. Se você atualizar todo o sistema regularmente, a distribuição instalará novos periodicamente de qualquer maneira, portanto, essa é a opção "menos complicada".

    • Use make headers_install.

    Como eles são compatíveis com versões anteriores (significando "um programa criado em uma biblioteca C usando cabeçalhos de kernel mais antigos deve ser executado em um kernel mais novo"), você não precisa se preocupar muito com isso. O único problema em potencial seria se você criar um kernel personalizado e mantê-lo por um tempo, durante o qual a distro atualiza o pacote "kernel-headers" para uma versão mais nova que a usada para construir o kernel, e parece haver alguns incompatibilidade (que só se aplicaria ao software posteriormente compilado a partir da fonte).

Referências

Aqui estão alguns recursos:

  • [src]/README inclui um breve guia para construção e instalação.

  • O [src]/Documentationdiretório contém muitas informações que podem ser úteis na configuração.

  • Muito do livro Linux Kernel in a Nutshell, de Greg KH (disponível gratuitamente aqui como uma série de PDFs), gira em torno da construção do kernel.

  • O Grub 2 tem um manual online .


1. "Baunilha" refere-se à fonte oficial original e não adulterada, encontrada em kernel.org. A maioria das distros usa essa fonte de baunilha e adiciona algumas personalizações menores.

2. Observe que há circunstâncias que requerem um initramfs porque é necessário algum espaço no usuário para montar o sistema de arquivos raiz - por exemplo, se ele estiver criptografado ou se espalhar por uma matriz RAID complexa.

3. No entanto, ele não removerá os módulos que já estão lá, se você não os construiu, o que significa que você pode adicionar um módulo posteriormente, simplesmente modificando sua configuração e executando make modules_installnovamente. Observe que a construção de alguns módulos pode exigir alterações no próprio kernel; nesse caso, você também precisa substituir o kernel. Você será capaz de saber quando tentar usar modprobepara inserir o módulo.

4. Esse arquivo pode ter um nome diferente se você tiver usado uma opção de compactação não padrão. Não sei ao certo quais são todas as possibilidades.

Cachinhos Dourados
fonte
3
Votado. Você pode adicionar uma menção localmodconfige ferramentas como o streamline_config.plscript; uma abordagem útil para o trabalho a partir de sua configuração existente ...
jasonwryan
1
Provavelmente, isso é detalhado o suficiente para ser uma pergunta do tipo canônico por iniciativa de @ terdon. Considere fornecer uma resposta para sua pergunta sobre meta. Ou eu poderia, se você preferir. Parece que essa pode ter sido a intenção, já que você fez a pergunta de qualquer maneira. Incluir métodos específicos de distribuição para construir pacotes binários também seria útil, eu acho.
Faheem Mitha
1
FYI: initramfsdeve ser usado quase sempre. Por exemplo, definir rootfs no LVM + RAID geralmente requer um. Raiz criptografada definitivamente faz. Até configurações RAID razoavelmente complicadas o fazem. A montagem automática no kernel, mesmo de matrizes triviais, está realmente obsoleta ...
derobert
2
@derobert: Isso sugere que "quase sempre" o linux está sendo usado para executar um servidor corporativo. O initramfsque quero dizer é que, se você não precisa usar um, não precisa e isso simplifica o processo. De qualquer forma, eu adicionei uma nota de rodapé sobre fs raiz criptografados, etc.
Goldilocks
Inclua detalhes sobre o EFI e a funcionalidade efi-stub do linux.
IW16 13/0816