STM32MP1: Inicialização em U, Buildroot, Arch Linux e um pouco de Debian

Olá Habr!

Há algum tempo, a STMicroelectronics lançou interessantes processadores da série STM32MP1. Quando finalmente coloquei minhas mãos na placa de depuração com base neste processador, fiquei surpreso ao descobrir que ele não possui compilações baseadas em distribuições populares (Debian, Arch Linux, etc.). Tudo o que restou foi tentar adaptar algum kit de distribuição para este quadro. Com base nos resultados, este artigo apareceu.



Quais são as características?


Este artigo não seria completo sem pelo menos uma breve visão geral das características dos processadores da série STM32MP1. Existem três famílias de processadores na série STM32MP1: STM32MP151, STM32MP153 e STM32MP157. Suas principais características são apresentadas na tabela.



Como você pode ver na tabela, a diferença entre as famílias é que o STM32MP151 possui um núcleo Cortex-A7, enquanto o STM32MP153 e o STM32MP157 possuem dois núcleos, e o STM32MP157 também oferece suporte à GPU 3D. Mas, em geral, as características desses processadores em 2020 não causam impressão, são bastante modestas. Por que eu ainda prestava atenção neles?

Por que STM32MP1?


De fato, uma questão completamente lógica pode surgir: existe um Raspberry Pi, há um Banana Pi, há um Orange Pi e, finalmente - por que precisamos de outro STM32MP1? Além disso, todas essas placas geralmente têm desempenho significativamente superior ao objeto de nosso estudo. A resposta é simples - enquanto você faz artesanato para uso doméstico, é preciso levar a framboesa e ela estará correta. Mas se estamos falando de produtos produzidos em massa para aplicações industriais - aqui outras coisas começam a desempenhar um papel decisivo, graças ao qual o STM32MP1 é o vencedor:

  • Faixa de temperatura operacional. Para o STM32MP1, ele inicia em menos de 40 graus, enquanto para muitos processadores de outros computadores de placa única é bom se estiver em menos de 20.
  • . STMicroelectronics , .
  • . DigiKey Mouser STM32MP1, .

Obviamente, o ST32MP1 não é o único processador no mercado para aplicações industriais. Existem NXP e TI. Quanto à TI, eu tinha um projeto de um módulo bastante complexo, e havia um sedimento de um número notável de recursos de hardware que não foram abordados na documentação, mas, se não respeitados, o processador poderia falhar completamente, e não imediatamente, mas com o tempo e com o tempo. no momento mais inoportuno. Além disso, era um processador de núcleo único e, com um aumento no número de tarefas atribuídas a ele, surgiam cada vez mais problemas de desempenho. Ao mesmo tempo, eu estava lidando com microcontroladores da STMicroelectronics, e eles provaram ser muito bons, então decidi tentar escolher esse novo pequeno.

Placa de depuração


Para experimentos, comprei uma placa de depuração STM32MP157A-DK1. Esta placa é bastante modesta em termos de equipamento: não possui uma tela LCD como a STM32MP157C-DK2 ou um periférico tão rico como a STM32MP157A-EV1. No entanto, há um slot para cartão microSD, um console USB-UART, várias portas USB e Ethernet. Para o primeiro começo, mais do que suficiente. E para diluir a história seca com uma foto, estou anexando uma foto deste quadro de depuração.



O que é um software pronto?


Na STMicroelectronics, tudo geralmente é muito bom em termos de hardware, mas terrível em termos de software. Todas essas modificações do Atollic True Studio, CubeMX, CubeIDE, que são cada vez mais problemáticas a cada novo lançamento, provocam certa angústia. A situação é um pouco melhor com o suporte do STM32MP1. A STMicroelectronics oferece apenas uma determinada montagem do OpenSTLinux. Esta montagem é uma distribuição criada usando o Projeto Yocto. Obviamente, tudo isso pode existir dessa forma, mas para mim a principal desvantagem foi a falta de acesso a repositórios de distribuições conhecidas. Isso significa que você não poderá colocar em seu quadro nenhum utilitário dos repositórios de distribuições populares simplesmente executando um comando como o apt-get install. Geralmente, isso não é necessário para soluções incorporadas, mas são possíveis situações,quando tal oportunidade definitivamente não será supérflua.

O que nós fazemos?


Portanto, a tarefa é clara - precisamos executar alguma distribuição popular em nosso quadro de depuração. Minha escolha caiu no Arch Linux. Esta não é a distribuição mais fácil, mas está bem adaptada aos dispositivos ARM: existem montagens prontas e um site oficial dedicado a isso.

A primeira coisa que tentei resolver o problema rapidamente - acabei de retirar o núcleo pronto do gerenciador de inicialização da distribuição do Arch Linux, montado sob o armv7. Isso às vezes funcionava em outras placas, mas havia um fiasco esperando por mim: apesar do fato de o kernel ter sido montado para a arquitetura correta, ele não foi iniciado. Bem, então você precisa montar seu kernel e, ao mesmo tempo, seu carregador. Meu plano de ação era este:

  1. Crie o carregador de inicialização U-Boot.
  2. Construa o kernel do Linux.
  3. Marcamos o cartão microSD.
  4. Escrevemos o carregador de inicialização, o kernel e o sistema de arquivos raiz no cartão microSD.
  5. Lucro

Preparação da montagem


Para implementar esse plano, precisamos de um computador com Linux e um leitor de cartão para gravar em um cartão microSD. Eu usei um laptop com o Debian 10, mas em geral isso não é importante, os nomes dos utilitários podem ser um pouco diferentes. Então, colocamos os utilitários necessários. Percebo imediatamente que agora e mais todos os comandos devem ser executados como root ou através do sudo.

apt-get install git
apt-get install make
apt-get install gcc
apt-get install gcc-arm-linux-gnueabihf
apt-get install bison
apt-get install flex
apt-get install g++
apt-get install rsync
apt-get install libncurses-dev

Na preparação para a montagem, criamos três diretórios no diretório de trabalho: u-boot (para o carregador de inicialização), buildroot (para a construção do sistema) e archlinux (para a distribuição):

mkdir u-boot
mkdir buildroot
mkdir archlinux

Nós precisaremos desses diretórios ainda mais. Vou me referir a esses nomes mais adiante no texto do artigo.

Conjunto de inicialização em U


Muitos artigos já foram escritos sobre o U-Boot e, como parte disso, não vou me aprofundar nas explicações sobre o que é, para que serve e como funciona. Só posso dizer que este é um carregador de inicialização que fornece a inicialização do Linux em dispositivos ARM. O código fonte do gerenciador de inicialização U-Boot está disponível no GitHub.

Para criar o U-Boot, primeiro clonamos o repositório do U-Boot no diretório u-boot que criamos anteriormente:

git clone https://github.com/u-boot/u-boot

Para criar com êxito o U-Boot, precisamos de um arquivo em árvore do dispositivo e um arquivo de configuração do U-Boot.

O arquivo em árvore do dispositivo é um arquivo dependente do dispositivo. Este arquivo descreve a configuração do processador para uma placa específica. Se você constrói seu hardware com base em qualquer processador ARM e planeja executar o Linux nele, precisará desenvolver o arquivo da árvore de dispositivos para ele (ou adaptar algum já pronto). No entanto, muitas placas de depuração já possuem arquivos prontos: os desenvolvedores cuidadosos de U-Boot os incluem em seu repositório. Então, veja o diretório u-boot / arch / arm / dts. Ele deve conter o arquivo stm32mp157a-dk1.dtb - este é o arquivo da árvore de dispositivos da nossa placa de depuração.

No arquivo de configuração do U-Boot, as configurações básicas do carregador de inicialização são gravadas.

Configurar o U-Boot a partir do zero é um processo bastante longo e trabalhoso, porque há muitas configurações. Para esses fins, existem configuradores gráficos e de console. No entanto, aqui tivemos sorte: no diretório u-boot / configs, há um arquivo stm32mp15_basic_defconfig . Este é o arquivo de configuração básica do U-Boot para as placas de depuração STM32MP15. Abrimos esse arquivo e vemos que, para iniciarmos rapidamente, basta alterar apenas uma linha: em vez disso

CONFIG_DEFAULT_DEVICE_TREE=”stm32mp157c-ev1”

Escreva

CONFIG_DEFAULT_DEVICE_TREE=”stm32mp157a-dk1”

Com essa linha, dizemos ao gerenciador de inicialização que precisamos usar o arquivo da árvore de dispositivos para nossa placa.

Agora você está pronto para criar o U-Boot. Usamos nossa configuração:

make CROSS_COMPILE=arm-linux-gnueabihf- stm32mp15_basic_defconfig

E execute a montagem:

make CROSS_COMPILE=arm-linux-gnueabihf-

Se tudo correu bem, então no diretório u-boot devemos ter um monte de arquivos. Destes, dois são interessantes para nós: u-boot-spl.stm32 e u-boot.img .

O primeiro arquivo é o chamado First Stage Boot Loader (FSBL). Ele está localizado na frente do U-Boot, é iniciado primeiro e inicializa a memória DDR3, necessária para iniciar o U-Boot. Em outras placas, o FSBL geralmente é combinado com o U-Boot em uma imagem, mas aqui você deve gravar cada imagem separadamente em uma unidade flash USB.

Isso é tudo com o U-Boot por enquanto, salve os arquivos designados e prossiga diretamente para o conjunto do kernel do Linux.

Montagem do kernel do Linux


Vou usar o Buildroot para construir o kernel do Linux. Obviamente, para esses propósitos, você pode usar o igualmente popular Yocto, ou mesmo tentar compilar o kernel a partir da fonte a partir do kernel.org. No entanto, eu tinha alguma experiência trabalhando com o Buildroot, então decidi. Além disso, o Buildroot também cria o sistema de arquivos raiz (rootfs) e até o carregador U-Boot.

Agora, por qualquer meio disponível, baixe o arquivo do Buildroot no site oficial , descompacte-o no diretório buildroot e vá para ele.

Como no caso do U-Boot, a primeira coisa que você precisa cuidar é o arquivo de configuração do nosso hardware.

Vamos para o diretório buildroot / configs e vemos que os desenvolvedores já adicionaram um arquivo de configuração para a nossa placa: existe um arquivostm32mp157a_dk1_defconfig (verdadeiro para a versão Buildroot-2020.05, nas versões anteriores deste arquivo ainda não havia).

Tentei compilar o kernel 5.4.26 usando esse arquivo de configuração, e ele geralmente foi iniciado com êxito na minha placa. No entanto, por algum motivo, o arquivo da árvore de dispositivos Linux neste assembly acabou por ser truncado: por padrão, não havia suporte para portas USB. Vamos esperar que, com o tempo, esse bug seja corrigido, mas o que fazer agora?

Procurei no google esse problema e me deparei com repositórios STMicroelectronics, onde encontrei fontes Linux 4.19 com patches para seus produtos. Inclusive, os arquivos DTB corretos também estavam lá. Resta apenas dizer ao Buildroot para usar este repositório ao criar o kernel. Para fazer isso, copie o arquivo stm32mp157a_dk1_defconfig e renomeie-o para stm32mp157a_dk1_new_defconfig . Abra-o e faça as seguintes alterações:

Em vez disso

BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_5_4=y

Nós escrevemos

BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_19=y

Em vez de

BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="5.4.26"

Nós escrevemos

BR2_LINUX_KERNEL_CUSTOM_TARBALL=y
BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION="$(call github,STMicroelectronics,linux,v4.19-stm32mp-r1.2)/linux-v4.19-stm32mp-r1.2.tar.gz"

Salve e feche o arquivo. O arquivo de configuração está pronto, vamos aplicá-lo (é necessário executá-lo no diretório buildroot):

make CROSS_COMPILE=arm-linux-gnueabihf- stm32mp157a_dk1_new_defconfig

Este comando transferirá informações do nosso arquivo de configuração stm32mp157a_dk1_defconfig para o arquivo .config, localizado no diretório buildroot. No futuro, o assembly será criado com base no arquivo .config.

Então, agora tudo está quase pronto para iniciar o processo de compilação, mas antes disso você precisa configurar nosso kernel.

Aqui vale a pena dizer que, por padrão, a funcionalidade mínima será incluída no kernel. Se quisermos expandi-lo, o kernel precisará ser configurado por nós mesmos. No mínimo, você precisará adicionar suporte ao Grupo de Controle ao kernel: sem isso, nosso Arch Linux não será iniciado. Além disso, como exemplo, demonstrarei como adicionar suporte a unidades flash USB ao kernel: como resultado, nossa placa de depuração poderá trabalhar com unidades flash.
Para iniciar o configurador do kernel a partir do diretório buildroot, execute o comando

make linux-menuconfig

e vai tomar chá. Esse processo não é rápido e, dependendo da potência do seu computador, pode levar de quinze minutos a várias horas. Importante: durante o trabalho de buildroot, você precisa de uma conexão estável com a Internet, muitos pacotes diferentes serão baixados.
Se, no processo, aparecer um erro

configure: error: you should not run configure as root (set FORCE_UNSAFE_CONFIGURE=1 in environment to bypass this check)
See `config.log' for more details

precisará executar o comando

export FORCE_UNSAFE_CONFIGURE=1

e reinicie o configurador do kernel.

Como resultado, a janela do configurador deve aparecer:



Adicionar suporte ao Grupo de controle: Configuração geral -> Suporte ao grupo de controle e defina o asterisco com um espaço:



E como adicionar suporte à unidade flash?
SCSI . 80- , , , USB FLASH . Device Drivers -> SCSI support :



USB FLASH . Device Drivers -> USB support USB Mass Storage support:



, FLASH : File systems -> Native language support -> Codepage 437 File systems -> Native language support -> NLS ISO 8859-1:





, USB FLASH .

Depois que todas as configurações no configurador do kernel forem feitas, salve-as com o botão Salvar e saia do configurador com o botão Sair .

Agora resta apenas iniciar o processo de compilação com o comando:

make CROSS_COMPILE=arm-linux-gnueabihf-

e você pode tomar um chá pela segunda vez, esse processo também leva muito tempo.

Se tudo correu bem, o seguinte conjunto de arquivos deve aparecer no diretório buildroot / output / images:

  • rootfs.ext2 é um sistema de arquivos raiz compilado com ext2. Não nos interessa;
  • rootfs.ext4 é um sistema de arquivos raiz compilado com ext4. Será útil para nós um pouco mais tarde;
  • sdcard.img - uma imagem de um cartão microSD, incluindo FSBL + U-Boot + zImage + rootfs. Um arquivo para os preguiçosos, permite que você não se preocupe em marcar um cartão microSD e faça o upload imediato de todo o sistema para ele. Claro, este não é o nosso caminho :).
  • stm32mp157a-dk1.dtb - arquivo em árvore do dispositivo. Certifique-se de ser útil para iniciar o sistema;
  • u-boot.img e u-boot-spl.stm32 - arquivo FSBL e U-Boot. Como os coletamos na última etapa, não precisamos deles;
    Por que os coletamos separadamente?
    , Buildroot U-Boot. , . U-Boot, – Linux.
  • zImage - o coração de todo o sistema - um arquivo compactado do kernel do Linux.

Assim, o processo de montagem está concluído, agora passamos a marcar o cartão de memória microSD e a criar partições nele.

Particionamento e seções de um cartão microSD


Marcar um cartão microSD e criar partições é um estágio muito importante, fortemente vinculado a uma plataforma de hardware específica. Infelizmente, nem sempre é fácil encontrar informações sobre esse problema em um processador específico e, mesmo que você colete o U-Boot e o kernel Linux totalmente funcionais, nada disso funcionará com o menor erro no layout do cartão microSD.

Imediatamente, observo que o cartão microSD com o qual o sistema é iniciado no STM32MP1 deve ter marcação GPT. O utilitário gdisk nos ajudará com isso , mas mais sobre isso mais tarde.

As seções do cartão microSD devem ficar assim:



Como você pode ver na figura, o cartão deve conter pelo menos 5 partições: fsbl1, fsbl2, ssbl, kernel, rootfs. Além disso, você também pode criar uma ou mais seções de dados para armazenar qualquer informação nelas.

Os fsbl1 e seções fsbl2 são completamente idênticos eo bootloader principal é escrito para eles (como você se lembra, este é o arquivo u-boot-spl.stm32 que recebemos durante o U-Boot montagem de processo). Apesar de tudo funcionar e com apenas uma dessas seções, a documentação do STM2MP1 recomenda executar duas delas. Outros requisitos se aplicam a estas seções:

  • Cada partição deve ter 256 KB de tamanho.
  • , fsbl (fsbl1 fsbl2). : , .

A seção ssbl destina - se à gravação do carregador de inicialização U-Boot (o arquivo u-boot.img que recebemos durante o processo de montagem do U-Boot). O tamanho da partição ssbl recomendado é 2 MB.
A seção do kernel destina - se a gravar nele o kernel do Linux (arquivo zImage ), a árvore do dispositivo ( arquivo stm32mp157a-dk1.dtb ) e o script do U-Boot, com o qual o sistema será iniciado. O tamanho da partição do kernel recomendado é de 64 MB.

A seção rootfs é para escrever o sistema de arquivos raiz. Vamos tentar escrever nele o sistema de arquivos raiz compilado pelo Buildroot, bem como o sistema de arquivos raiz do Arch Linux. O tamanho da partição rootfs recomendado é de 1 GB ou mais.
A seção de dados é destinada ao armazenamento de dados do usuário. Você pode fazer uma dessas seções ou várias. E você pode ficar sem ele. Neste artigo, não vou criar esta seção.

Então, começamos a marcação. Nós inserimos o cartão microSD no leitor de cartão do nosso computador com o Linux a bordo e, usando qualquer meio disponível (por exemplo, usando dmesg), determinamos o nome do dispositivo que aparece. No meu caso, este é / dev / sdb. No seu caso, pode ser um nome diferente.

Execute o utilitário gdisk e exclua completamente a marcação no cartão microSD:

root@debian:/home/myuser# gdisk /dev/sdb
GPT fdisk (gdisk) version 1.0.3
Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present
Found valid GPT with protective MBR; using GPT.
Command (? for help): x
Expert command (? for help): z
About to wipe out GPT on /dev/sdb. Proceed? (Y/N): y
GPT data structures destroyed! You may now partition the disk using fdisk or
other utilities.
Blank out MBR? (Y/N): y

Por precaução, martelamos o início do cartão microSD com zeros.

dd if=/dev/zero of=/dev/sdb bs=1M count=64

Agora execute o gdisk novamente, adicione a marcação e crie 5 partições no cartão microSD de acordo com a tabela que eu dei acima:

root@debian:/home/myuser# gdisk /dev/sdb
GPT fdisk (gdisk) version 1.0.3

Partition table scan:
  MBR: not present
  BSD: not present
  APM: not present
  GPT: not present

Creating new GPT entries.

Command (? for help): o
This option deletes all partitions and creates a new protective MBR.
Proceed? (Y/N): y

Command (? for help): n
Partition number (1-128, default 1): 1
First sector (34-30873566, default = 2048) or {+-}size{KMGTP}: 
Last sector (2048-30873566, default = 30873566) or {+-}size{KMGTP}: +256K
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

Command (? for help): n
Partition number (2-128, default 2): 2
First sector (34-30873566, default = 4096) or {+-}size{KMGTP}: 
Last sector (4096-30873566, default = 30873566) or {+-}size{KMGTP}: +256K
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

Command (? for help): n
Partition number (3-128, default 3): 3
First sector (34-30873566, default = 6144) or {+-}size{KMGTP}: 
Last sector (6144-30873566, default = 30873566) or {+-}size{KMGTP}: +2M
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

Command (? for help): n
Partition number (4-128, default 4): 4
First sector (34-30873566, default = 10240) or {+-}size{KMGTP}: 
Last sector (10240-30873566, default = 30873566) or {+-}size{KMGTP}: +64M
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

Command (? for help): n
Partition number (5-128, default 5): 5
First sector (34-30873566, default = 141312) or {+-}size{KMGTP}: 
Last sector (141312-30873566, default = 30873566) or {+-}size{KMGTP}: 
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sdb.
The operation has completed successfully.

Em seguida, adicione os nomes às seções no cartão microSD. Como você se lembra, isso é especialmente crítico para as primeiras seções em que o FSBL será gravado: se você não atribuir os nomes necessários a eles, o sistema não será iniciado:

root@debian:/home/myuser# gdisk /dev/sdb
GPT fdisk (gdisk) version 1.0.3

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): c
Partition number (1-5): 1
Enter name: fsbl1

Command (? for help): c
Partition number (1-5): 2
Enter name: fsbl2

Command (? for help): c
Partition number (1-5): 3
Enter name: ssbl

Command (? for help): c
Partition number (1-5): 4
Enter name: kernel

Command (? for help): c
Partition number (1-5): 5
Enter name: roootfs

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sdb.
The operation has completed successfully.

No final do trabalho com o cartão microSD, precisamos adicionar o atributo inicializável do BIOS herdado à seção em que escreveremos o kernel do Linux. Sem esse atributo, o kernel se recusou a iniciar:

root@debian:/home/myuser# gdisk /dev/sdb
GPT fdisk (gdisk) version 1.0.3

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): x

Expert command (? for help): a
Partition number (1-5): 4
Known attributes are:
0: system partition
1: hide from EFI
2: legacy BIOS bootable
60: read-only
62: hidden
63: do not automount

Attribute value is 0000000000000000. Set fields are:
  No fields set

Toggle which attribute field (0-63, 64 or <Enter> to exit): 2
Have enabled the 'legacy BIOS bootable' attribute.
Attribute value is 0000000000000004. Set fields are:
2 (legacy BIOS bootable)

Toggle which attribute field (0-63, 64 or <Enter> to exit): 

Expert command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sdb.
The operation has completed successfully.

Isso é tudo, o layout do cartão de memória está pronto. Por precaução, verifique se tudo está registrado como deveria. Para fazer isso, execute o gdisk novamente e execute o comando p . O resultado deve aconselhar a imagem:



Agora crie o sistema de arquivos ext4 em / dev / sdb4 e / dev / sdb5:

mkfs.ext4 /dev/sdb4
mkfs.ext4 /dev/sdb5

E prescrevemos etiquetas de volume para que mais tarde seja mais fácil acessá-las:

e2label /dev/sdb4 kernel
e2label /dev/sdb5 rootfs

Isso completa a criação de seções do cartão de memória, você pode continuar gravando arquivos nele.

Gravação de cartão MicroSD


Portanto, no estágio atual, tudo está pronto para a gravação em um cartão microSD. Nós o inserimos no leitor de cartão do computador Linux e gravamos o carregador de inicialização primário (FSBL) na primeira e na segunda seção do cartão mocroSD:

dd if=u-boot/u-boot-spl.stm32 of=/dev/sdb1
dd if=u-boot/u-boot-spl.stm32 of=/dev/sdb2

Agora escreva U-Boot na terceira seção do cartão microSD:

dd if=u-boot/u-boot.img of=/dev/sdb3

Em seguida, você precisa copiar o kernel, o arquivo em árvore do dispositivo e o script de inicialização para a quarta seção do cartão microSD.

Antes de começar a copiar arquivos, você precisa de uma pequena explicação sobre o script de download. De fato, neste script, são indicadas várias informações sobre o U-Boot, com a ajuda do qual ele pode inicializar o sistema e transferir o controle para o kernel. Existem diferentes maneiras de escrever esses scripts, mas o mais simples (na minha opinião) é descrito na documentação do STM32MP1: você precisa criar o diretório / extlinux na raiz da seção do kernel e criar um arquivo de texto com o nome extlinux.conf com o seguinte conteúdo:

LABEL stm32mp157a-dk1
KERNEL /zImage
FDT /stm32mp157a-dk1.dtb
APPEND root=/dev/mmcblk0p5 rootwait rw console=ttySTM0,115200

Tudo é bem simples aqui: dizemos ao carregador onde obter o kernel, a árvore de dispositivos, o sistema de arquivos raiz e dizemos que teremos a porta ttySTM0 como console de trabalho.

Agora copie o kernel:

cp -a buildroot/output/images/zImage /media/myuser/kernel/

Nota: no diretório / media / myuser /, montei um cartão microSD quando instalado no leitor de cartão. No seu caso, pode ser um diretório diferente.

Copie o arquivo da árvore do dispositivo:

cp -a buildroot/output/images/stm32mp157a-dk1.dtb /media/myuser/kernel/

Crie um diretório:

mkdir /media/myuser/kernel/extlinux

Crie um arquivo:

nano /media/myuser/kernel/extlinux/extlinux.conf

e preencha com o conteúdo:

LABEL stm32mp157a-dk1
KERNEL /zImage
FDT /stm32mp157a-dk1.dtb
APPEND root=/dev/mmcblk0p5 rootwait rw console=ttySTM0,115200

Salve o arquivo e feche o editor.

Nisso, a quarta seção do cartão microSD está pronta: o kernel do linux e todos os arquivos auxiliares já estão gravados. Já neste estágio, se você inserir o cartão microSD na placa de depuração, o kernel do Linux deverá ser carregado; no entanto, no final, ele entrará em pânico pelo kernel, devido ao fato de que o sistema de arquivos raiz não pode ser montado. Isso não é surpreendente, porque gravamos até agora.

Há a etapa final, na qual escreveremos o sistema de arquivos raiz no cartão microSD. E aqui várias opções são possíveis:

  1. Escreva o sistema de arquivos raiz gerado pelo Buildroot
  2. Reescreva o sistema de arquivos raiz do Arch Linux

Primeiro, anote o sistema de arquivos raiz que o Buildroot gerou para nós e tente começar com ele. Esse não era o objetivo deste artigo, mas me parecia que, em geral, poderia ser útil para qualquer aplicativo, principalmente porque essa ação não leva muito tempo. O sistema de arquivos raiz é gravado na quinta seção do cartão microSD com apenas um comando:

dd if=buildroot/output/images/rootfs.ext4 of=/dev/sdb5

Agora insira o cartão de memória na placa de depuração e inicie o sistema. Observaremos a saída das informações de depuração por meio do console USB-UART: o acesso é fornecido através de uma porta microUSB na placa STM32MP157A-DK1. É possível exibir as informações exibidas em qualquer programa do terminal, por exemplo, Putty ou Minicom. Para os propósitos deste artigo, usei o último abrindo outra janela de terminal no Debian.

Agora, inserimos o cartão microSD na placa de depuração, fornecemos energia à placa e olhamos para o terminal. Se tudo foi feito corretamente, os logs do FSBL, U-Boot, kernel devem ser colocados lá e, finalmente - um convite para entrar no login aparecerá. Entramos no root e - voila - chegamos ao console do sistema que acabamos de coletar:



Sim, ele nem sequer possui um gerenciador de pacotes e, em geral, a funcionalidade é muito ruim, mas com a ajuda do Buildroot você pode construí-lo muito bem e criar um sistema realmente complexo. Enquanto isso, seu tamanho é de apenas 7 megabytes!



Depois de garantir que o sistema de arquivos raiz caseiro seja iniciado com êxito, é hora de iniciar o Arch Linux. Mais uma vez, insira o cartão microSD no leitor de cartão do nosso computador e formate novamente a quinta seção do cartão de memória:

mkfs.ext4 /dev/sdb5

Faça o download do arquivo com o Arch Linux, montado sob armv7, no site oficial. Descompacte o archive no diretório archlinux e use o comando:

cp -a archlinux/* /media/myuser/rootfs 

Copie-o para a seção rootfs do cartão microSD.

Limpamos o diretório / media / myuser / rootfs / boot: não precisamos do conteúdo, porque o kernel e a árvore do dispositivo estão em uma seção separada do cartão microSD:

rm –rf /media/myuser/rootfs/boot/*

Posteriormente, você pode montar a partição / dev / sdb4 no diretório de inicialização, onde temos a imagem do kernel.

Depois disso, insira o cartão microSD na placa de depuração, energize e aproveite o trabalho do ArchLinux:



Depois que o Arch Linux foi iniciado com êxito, decidi tentar executar o Debian na placa de depuração também. Usando manipulações absolutamente semelhantes ao sistema de arquivos raiz, ele funcionou com sucesso:



Conclusão


Neste artigo, jogamos o suficiente com a placa de depuração STM32MP157A-DK1: coloque U-Boot, o kernel do Linux, nosso próprio sistema de arquivos raiz e também lançou o Arch Linux e o Debian. Espero que este material seja útil para alguém quando estiver trabalhando com processadores da família STM32MP1 ou com qualquer outra placa única no ARM.


All Articles