Modificando kernel no OpenEmbedded

kernel no OpenEmbedded

Inúmeras pessoas não sabem como adicionar alterações de kernel dentro do build system OpenEmbedded/Yocto. Apesar de ser uma ótima ferramenta para gerar sua imagem, usar o build system para compilar e testar pequenas alterações de pacotes independentes, apesar de possível, pode se tornar muito confuso. Minha sugestão para alteração de kernel é compilar o mesmo isoladamente, testar todas as alterações realizadas e no final do projeto, adicionar estas alterações ao build system. Este artigo irá apresentar como adicionar suas próprias alterações de kernel no OpenEmbedded. Para ilustrar o processo, iremos adicionar suporte ao acelerômetro mma8653 da NXP (antiga Freescale) ao kernel 4.4.14 utilizado pelo computador em módulo Toradex Colibri VF61.

 

 

Procedimento

 

A primeira coisa a fazer é ter o OpenEmbedded e seus pré-requisitos instalados. Você pode seguir as seções prerequisites e installation deste artigo para tal.

 

Para encontrar a localização e o kernel sendo utilizado pelo target, você pode começar procurando as receitas de kernel utilizadas pelos diferentes targets suportados:

 

cd stuff
find . -wholename "*recipes-kernel/linux*.bb"

 

Dentre os resultados, aqueles nos quais estamos interessados ficam dentro do diretório meta-toradex/recipes-kernel/linux/. Ao olhar dentro deste diretório, vemos o resultado apresentado na figura 1:

 

Olhando dentro do diretório meta-toradex/recipes-kernel/linux/
Figura 1: Olhando dentro do diretório meta-toradex/recipes-kernel/linux/

 

Observe que há diversas versões de kernel. Para descobrir quais targets utilizam quais versões do kernel, execute o seguinte comando dentro do diretório. O resultado é mostrado na figura 2:

 

grep -nre "COMPATIBLE_MACHINE" *

openembedded_compatible_machine

Observe que alguns targets podem utilizar mais de uma receita de kernel. Para saber rapidamente qual receita está sendo usada pelo target com o qual você está trabalhando, vá ao diretório de build e execute o bitbake da sua receita responsável pelo kernel, no nosso caso linux-toradex. Observe com atenção enquanto o comando é executado e você verá qual receita está sendo utilizada, conforme ilustrado na figura 3 (você também pode procurar pela variável PREFERRED_PROVIDER_virtual/kernel na receita para a sua machine):

 

bitbake linux-toradex

 

Verificando a versão do kernel sendo utilizada pelo bitbake, para o target em questão
Figura 3: Verificando a versão do kernel sendo utilizada pelo bitbake, para o target em questão

 

Agora que nós sabemos qual receita está sendo usada, vamos abrir o seu arquivo e dar uma olhada. Abaixo está o conteúdo do arquivo stuff/meta-toradex/recipes-kernel/linux/linux-toradex_4.4.bb:

require recipes-kernel/linux/linux-imx.inc
require recipes-kernel/linux/linux-dtb.inc


SUMMARY = "Linux kernel for Toradex Colibri VFxx Computer on Modules"


SRC_URI = "git://git.toradex.com/linux-toradex.git;protocol=git;branch=${SRCBRANCH} \
                      file://defconfig"


KERNEL_MODULE_AUTOLOAD += "${@bb.utils.contains('COMBINED_FEATURES', 'usbgadget', ' libcomposite', '',d)}"


LOCALVERSION = "-v2.6b2"
SRCBRANCH = "toradex_vf_4.4"
SRCREV = "efe965a5dad66bd14219cdc9474ea75eda783456"
DEPENDS += "lzop-native bc-native"
COMPATIBLE_MACHINE = "(vf)"

 

Nós estamos interessados nas variáveis SRC_URI, SRCBRANCH e SRCREV. SRC_URI indica de onde o código-fonte do kernel deve ser buscado e qual o arquivo de configuração a ser utilizado. SRCBRANCH indica o branch do repositório git apontado pela variável SRC_URI. SRCREV aponta qual é o commit sendo usado para este branch.

 

Vamos clonar o mesmo branch para a nossa máquina de desenvolvimento (host) e em seguida verificar os últimos 5 commits realizados. O resultado é apresentado na figura 4:

 

git clone -b 2015.04-toradex git://git.toradex.com/u-boot-toradex.git
git log -5 --pretty=oneline

 

Últimos 5 commits do código-fonte do kernel
Figura 4: Últimos 5 commits do código-fonte do kernel

 

Você pode observar que o último commit (que começa com efe...) é o mesmo que aquele apontado pela variável SRCREV da receita. Isto confirma que nós temos o mesmo código-fonte que está sendo utilizado pelo OpenEmbedded.

 

 

Realizando mudanças e adicionando ao OpenEmbedded

 

Para o exemplo deste artigo, o driver para o acelerômetro mma8653 será habilitado, assim como o dispositivo adicionado à device tree do target. Para isto é preciso ter instalada uma toolchain que permita a compilação cruzada para a arquitetura do target - que no caso é ARM. É possível baixar e instalar diretamente a toolchain Linaro, ou alternativamente fazer uma build do OpenEmbedded e depois usar a toolchain gerada durante a build. Mais informações sobre como executar ambas as abordagens podem ser encontradas neste artigo. Em resumo, para instalar a toolchain diretamente:

 

cd
wget -c https://releases.linaro.org/components/toolchain/binaries/5.2-2015.11-2/arm-linux-gnueabihf/gcc-linaro-5.2-2015.11-2-x86_64_arm-linux-gnueabihf.tar.xz
tar xvf gcc-linaro-5.2-2015.11-2-x86_64_arm-linux-gnueabihf.tar.xz
ln -s gcc-linaro-5.2-2015.11-2-x86_64_arm-linux-gnueabihf gcc-linaro

 

E depois de instalada, exportar as variáveis no terminal e carregar as configurações padrão do kernel para o target desejado, como ponto de partida. Note que isto deve ser feito toda vez que for aberto um novo terminal.

 

export ARCH=arm
export PATH=~/gcc-linaro/bin/:$PATH
export CROSS_COMPILE=arm-linux-gnueabihf-
make colibri_vf_defconfig

 

Copie a configuração atual para outro arquivo. Não pule este passo, pois vamos usar os arquivos de backup a seguir:

 

cp .config .config_old
cp arch/arm/configs/colibri_vf_defconfig arch/arm/configs/colibri_vf_mma8653

 

Configure o kernel e modifique seu código-fonte de acordo com as suas necessidades. Para habilitar o driver do acelerômetro, será usada a ferramenta menuconfig, conforme ilustrado no comando abaixo e na figura 5:

 

make menuconfig

 

Habilitando o driver do kernel para o acelerômetro mma8452Q (compatível com mma8653)
Figura 5: Habilitando o driver do kernel para o acelerômetro mma8452Q (compatível com mma8653)

 

Para verificar o que mudou entre o antes e depois, vamos comparar o arquivo de configuração com o backup que fizemos anteriormente. O resultado é apresentado na figura 6:

 

meld .config .config_old

 

Diferença entre antes e depois de habilitar o driver do mma8452
Figura 6: Diferença entre antes e depois de habilitar o driver do mma8452

 

Observe que a única mudança é que CONFIG_MMA8452 agora está setado. Vamos simplesmente adicionar esta linha para o backup do defconfig que fizemos anteriormente:

 

echo "CONFIG_MMA8452=y" >> arch/arm/configs/colibri_vf_mma8653

 

A device tree também precisa de algumas mudanças. Abra o arquivo arch/arm/boot/dts/vf-colibri-eval-v3.dtsi e modifique o nó &i2c0 (linha 127) conforme apresentado abaixo. Observe que o nó [email protected] é o que foi adicionada ao arquivo:

 

&i2c0 {
        status = "okay";


        /* TouchRevolution Fusion 7 and 10 multi-touch controller */
        touch: [email protected] {
                compatible = "touchrevolution,fusion-f0710a";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_gpiotouch>;
                reg = <0x10>;
                gpios = <&gpio0 30 GPIO_ACTIVE_HIGH /* SO-DIMM 28, Pen down interrupt */
                                &gpio0 23 GPIO_ACTIVE_LOW /* SO-DIMM 30, Reset interrupt */
                                >;
                status = "disabled";
        };


        /* M41T0M6 real time clock on carrier board */
        rtc: [email protected] {
                compatible = "st,m41t00";
                reg = <0x68>;
        };


        [email protected] {
                compatible = "fsl,mma8653";
                reg = <0x1d>;
                pinctrl-0 = <&pinctrl_gpiokeys>;
                interrupt-parent = <&gpio1>;
                interrupts = <9 0>;
        };


};

 

Também modifique a porção de código abaixo. Ela está no nó &iomuxc, no final do arquivo. Observe que o valor hexadecimal foi modificado de 0x218d para 0x22ed:

 

pinctrl_gpiokeys: gpiokeys {
                        fsl,pins = <
                                VF610_PAD_PTB19__GPIO_41        0x22ed
                        >;
                };

 

Faça o commit das suas mudanças e crie um patch a partir deles:

 

git commit –m "mma8653 accelerometer"
git format-patch --signoff HEAD~1

 

Se você fez múltiplos commits, crie múltiplos arquivos mudando o número 1 acima conforme o número de commits que você fez.

 

Para adicionar as mudanças ao OpenEmbedded, copie o patch e o arquivo defconfig modificado para o diretório que corresponde à sua receita:

 

cp 0001-mma8653-accelerometer.patch /home/prjs/oe-core/stuff/meta-toradex/recipes-kernel/linux/linux-toradex-4.4/


cp arch/arm/configs/colibri_vf_mma8653 /home/prjs/oe-core/stuff/meta-toradex/recipes-kernel/linux/linux-toradex-4.4/defconfig

 

Edite a receita para aplicar o patch, adicionando seu arquivo à variável SRC_URI:

 

SRC_URI = "git://git.toradex.com/linux-toradex.git;protocol=git;branch=${SRCBRANCH} \
                      File://0001-mma8653-accelerometer.patch \
                      file://defconfig"

 

Por fim, compile o kernel:

 

bitbake -c clean linux-toradex
bitbake linux-toradex

 

A imagem do kernel e a device tree estarão no diretório out-glibc/deploy/images/colibri-vf/, conforme ilustrado pela figura 7. Você pode aplicar ambos ao target seguindo a seção kernel update deste artigo.

 

Imagem do kernel, módulos compilados e device tree
Figura 7: Imagem do kernel, módulos compilados e device tree

 

 

Conclusão

 

Conforme comentado na introdução, compilar o kernel dentro do build system é possível, mas um pouco confuso. Existem comandos que permitem fazer isso, porém é preciso conhecer muito bem OpenEmbedded/Yocto para ter certeza do que realmente está sendo feito.

 

A ideia deste artigo é mostrar que é possível isolar os problemas compilando e personalizando o kernel fora do build system. Espero que este artigo tenha sido útil e até a próxima!

NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

2
Deixe um comentário

avatar
 
1 Comment threads
1 Thread replies
1 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
Leonardo VeigaDiego Sueiro Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Diego Sueiro
Visitante
Diego Sueiro

Olá Leonardo,

Ótimo artigo.

Ainda estou para avaliar o devtool para modificação e desenvolvimento do kernel:
http://www.yoctoproject.org/docs/2.2/dev-manual/dev-manual.html#dev-modifying-source-code

Leonardo Veiga
Membro
Leonardo Veiga

Olá Diego,

Acabei deixando passar seu comentário e, passando pelos artigos antigos vi ele aqui. Me desculpe pela demora.

Achei bem massa essa ferramenta aí dando uma olhada por cima, agradeço muito por compartilhar a informação e espero poder investigar em profundidade.

Abraço!