 Olá, tudo bem? Meu nome é o Mirocato, sou o engenheiro de software embarcado na Expressif e hoje vou falar um pouco sobre MCLboot. Desejar agradecer a presença de todos vocês. Bom, aqui tem os tópicos que eu vou abordar passando por o que é o MCLboot, como que é sua estrutura, como ele funciona, o processo de boot atualização e os fatores de segurança que tornam esse bootloader um bootloader interessante. Também farei uma demonstração simples de um update de firmware utilizando o MCLboot. Bom, mas primeiro vamos aqui falar um pouco sobre esses dados aqui do IoT Analytics. Hoje em dia o IoT e sistemas embarcados são termos que praticamente se confundem. Bom, do lado do IoT a gente tem um mercado que está em crescimento. Até 2021 tivemos aí 158 bilhões de dólares investidos e tem aí uma previsão até 2027 de crescimento. Bom, em quantidade de dispositivos IoT a gente tem também bilhões de dispositivos conectados, em 2021 cerca de 12.2 bilhões, também em crescimento. Isso sem contar os smartphones e computadores a gente está considerando aqui dispositivos com sensores atuadores que fazem parte dessa denominação IoT. Mas que isso tem a ver, como falei, são termos que se confundem. Mais IoT significa mais microcontroladores, certo? Temos aí mais conectividade, mais atualizações e mais maior preocupação com segurança. Então, com o crescimento do mercado cresce as preocupações. Bom, e o MC Boot, de uns anos para cá, foi desenvolvido com o objetivo de ajudar a tentar resolver esses problemas, essas questões de atualização e segurança. Então, MC Boot, como falei, é um bootloader, é um bootloader open source, iniciou alguns anos atrás no My Newt. Ele é voltado para microcontroladores e baixo custo, que tem pouca flash, pouca RAM, baixa frequência de clock, baixa consumo de energia. E o objetivo ali é simplificar e padronizar o processo de boot seguro e atualização de firmware. Isso dependendo de um layout de memória flash bem definido para ele funcionar. O MC Boot não está atrelado a um sistema operacional. Ele depende de uma camada de portabilidade. Vou falar um pouquinho mais sobre isso daqui a pouco. E ele tem compatibilidade com o MCO Manager, um outro projeto ali, e o que permite um recovery serial, a recuperação do firmware através da porta serial. Bom, é que a gente tem os RTOS suportados. Como falei, o MC Boot, ele depende de uma camada de portabilidade. Então, ele funciona praticamente como se fosse uma Lib, que as features, suas features estão implementadas e, como se você integrasse isso numa aplicação desse determinado sistema operacional. Então, aqui a gente tem o MyUnit, o Zephyr, Cypress, EmbeddedOS, Riot, Nuttix, e no caso do port da Expressif, ele não é voltado a um sistema operacional, mas ele permite a compatibilidade com as placas, como o SB32. Foi implementado de uma forma um pouco diferente dessa compatibilidade com esses sistemas operacionais. Bom, como falei, o MC Boot está fortemente estrelado ali ao layout da flash. Aqui a gente divide a flash em regiões, em que uma imagem, a imagem do firmware, ele deve ter dois slots, os slots primários secundários, que permite atualização através da permuta. E a gente tem também uma área de scratch, que auxilia essa permuta, essa troca. A execução, no caso da execução padrão do MC Boot, ele ocorre sempre a partir do primeiro slot da imagem. E o slot secundário, ele armazena a atualização ou após a permuta a imagem original, a imagem antiga. Bom, também tem um formato específico para a imagem compatível com o MC Boot. Então, existe um cabeçalho, um suffix, um trailer, que a gente chama de TLV, que contém informações sobre a imagem, como o tamanho, o hash de assinatura, a versão, o estado de atualização, permuta. São informações que também tem uma ferramenta chamada IMAGTOO, que é fornecida com o MC Boot, que pode fazer essa adição do cabeçalho e dos TLVs. O MC Boot também permite múltiplas imagens. No caso, cada imagem possui no seu slot primário secundário e você consegue fazer atualizações independentes. No caso do MC Boot, ele definiu que a primeira imagem sempre é responsável por botar as outras. O MC Boot só dispara a primeira imagem e ela fica responsável por iniciar as outras imagens. O MC Boot fica responsável por gerenciar as atualizações. É permitido também a dependência entre as versões, essas imagens. Você consegue fazer atualizações que têm essas dependências de versões. O processo de boot do MC Boot, a gente tem aqui três modos distintos. Sendo o padrão, o que não é in-place, que seria o non-directXIP, ele sempre carrega a imagem do slot primário. A gente tem também o directXIP, que é a execução in-place, que executa diretamente da flash. Aí o processo de atualização é um pouco diferente e não tem toda aquela parte da permuta. E o run-loading, que é parecido com o directXIP, mas você carrega a imagem inteira em RAM. E mais voltado para dispositivos que têm mais memória RAM, o suficiente. Aqui a gente tem o fluxograma de como funciona. Partindo dele, desde o reset do dispositivo. É feito o bring-up básico da placa. Você entra nas rotinas do MC Boot e tem algumas verificações a serem feitas antes do boot. Pode ser que alguma permuta estava em progresso antes do reset. Caso tenha uma permuta em progresso que tenha sido interrompida, a gente vai para a etapa de finalizar essa permuta e depois fazer o boot da imagem. Se não estava ocorrendo nenhuma permuta, a gente vai para a verificação da confirmação da imagem. A imagem, no caso, tem um campo de confirmação ali. Se ela é uma imagem estável ou uma imagem OK para ser verificado no boot. Aqui a gente tem três possibilidades. Confirmado, uma permuta foi requisitada ou não confirmada. Caso tenha ocorrido a confirmação da imagem, você vai para a verificação se é uma imagem válida no slide primário. Caso não seja válida, um erro vai parar o processo por aí. Caso seja válido, vai para o boot da imagem corrente. Caso uma permuta tenha sido requisitada, também vai para uma verificação da imagem que está no slide secundário. E no caso que está ocorrendo a atualização. Então, se a imagem que está no slide secundário for válida, acontece a permuta de imagens e o boot. Caso não tenha sido validado, vai ser apagada a imagem do slide secundário e vai continuar com o boot da imagem original que acabou não ocorrendo a permuta, então era a imagem original no slide primário. Caso aquela imagem não tenha sido confirmada, aqui nesse passo, vai acontecer um revert. Quer dizer que pode ser que anteriormente tenha ocorrido uma permuta, aí depois do boot dessa imagem nova, essa imagem não foi confirmada e aí nesse boot atual acontece esse revert, esse holdback. E aí continua para o boot da imagem que está no slide primário, que é aquela imagem anterior a esse revert. E o processo de atualização, mais ou menos como eu expliquei no processo de boot, a gente tem o processo de atualização por permuta, dito por padrão do mcboot. E há três formas que você pode escolher, construir o mcboot para fazer a atualização. Então você tem aqui a permuta através da área de scratch, que é essa área auxiliar. Ela ocupa mais espaço em flash, mais permite os mecanismos de recuperação e holdback. A gente tem aqui a permuta por movimentação, economiza um pouco da área de scratch, mas necessita de um setor de slot primário para fazer essa permuta. E você tem a permuta por overwrite, que sobrecreve o slot primário, ocupa menos espaço, porque não precisa de uma área auxiliar, mas aí ele não suporta o fallback da imagem, caso a imagem não tenha sido confirmada ou tenha acontecido algum problema. Não é possível fazer o fallback porque não existe mais aquela imagem, foi sobrescrito. E no caso do DirectX IP ou Unloading, não ocorre a permuta, e o mcboot escolhe qual imagem inicia, através de uma flag indicativa e a versão mais recente. Já na camada de aplicação, a camada de aplicação deve ter um agente atualizador que conheça, o layout de mcboot, e que implemente as APIs da LibBootUtil do mcboot para fazer a confirmação de imagem posterior à permuta, o processo de atualização, que vai indicar que essa imagem é estável, e vai fazer com que ela não seja revertida no próximo boot. Aqui a gente tem o diagrama de sequência da atualização, no caso a atualização através da permuta, o agente atualizador na camada de aplicação vai requerir ou vai ser avisado de que há uma atualização de imagem, aí o servidor de atualização vai enviar a imagem, a aplicação vai fazer o download, pode ocorrer uma verificação na camada de aplicação, vai ser armazenada essa imagem nova no slot secundário, e vai ser reiniciado dispositivo. Então, quando for reiniciado o dispositivo, vai acontecer aquele processo de boot, que foi explicado lá atrás, que é a verificação da imagem no slot secundário, vai acontecer a permuta, e aí vai finalmente fazer o boot da imagem atualizada. A aplicação pode validar essa imagem nova, pode fazer algum self-test, algo assim, e vai marcar que a imagem é estável, vai marcar ela como confirmada, vai marcar o campo que está nos telves, como confirmada, e o próximo boot vai ocorrer sempre com essa imagem, atual. Bom, o MS Boot ainda oferece alguns fatores de segurança nessas diversas etapas. Você tem a verificação da integridade através da verificação do hash, você tem a verificação de assinatura, que pode ser através de chave RSA, de curva elíptica EC256, ED25519, aí você tem o script, a aplicação auxiliar, que pode gerar, o image2 pode gerar essas chaves de assinatura, e ele assina colocando cabeçalho com assinatura correta e os telves. Também possibilita a imagem ser criptografada, dificultando o acesso dos dados de código da imagem, exportado o algoritmo ASCTR, e também é tolerante a falhas durante as permutas e permite o rollback caso a imagem não seja confirmada. Então, se torna esses mecanismos, esses procedimentos, eles tornam o MS Boot um bootloader mais robusto, que permite uma construção de uma cadeia de segurança, desde você autenticar que a imagem que está sendo iniciada é uma imagem conhecida através da verificação de assinatura e com a criptografia você consegue proteger os seus dados também. Aqui vamos para a demonstração, uma simulação de atualização simples com assinatura EC256, eu estou utilizando o USB32, que tem essa organização de flash, que você tem o bootloader nesse endereço, o slot primário, o slot secundário e a área de scratch. Vou tentar mostrar um pouco disso na prática. Aqui para mostrar a configuração da organização da flash, temos aqui o endereço do bootloader, do slot primário, do slot secundário e da área de scratch. No caso, o port da expressive se utiliza do mecanismo swap scratch, ou de permuta com aquela área auxiliar. Aqui a gente está ablitando a assinatura EC256, que é necessita da Libitine Crypt. E aqui a gente está usando o arquivo da chave. Aqui a chave é a chave padrão, que vem de exemplo no repositório do mcboot. É recomendável você gerar a sua própria chave. A gente está no repositório do mcboot, utilizar o port da expressive, os comandos são um pouco tensos. Aqui a gente vai estar compilando mcboot para SP32. Vou iniciar aqui o dispositivo. Então o mcboot foi gravado, por enquanto a gente não gravou nenhuma imagem. Então, claro, não vai acontecer nada de boot, não vai iniciar a imagem. Eu vou colocar aqui, então, gravar aqui. Já tem duas imagens pré-compiladas, uma imagem que seria a imagem original e uma de atualização. Eu estou utilizando uma aplicação Zephyr. Aqui vou comentar que o port da expressive, tem um pessoal até que chamou o port de port bare metal, porque ele está voltado para os chips da expressive e você pode ter a compatibilidade de outros RTOS com o mcboot para o SP32. Aqui, por exemplo, tem uma imagem do Zephyr que vai rodar aqui, mas tem também um port de compatibilidade do NuttX, que também é compatível utilizando com o mcboot na SP32. Então, primeiro eu vou fazer a assinatura dessa imagem. Aqui a gente tem uma imagem tool que eu citei anteriormente. A gente vai estar assinando. Tem alguns parâmetros aqui. Aqui a gente indica que a imagem já vai ser confirmada, já vai estar confirmada. Aqui a gente indica a chave. Aqui, como eu falei, é uma das chaves de exemplo do mcboot. Aqui está o meu binário da aplicação e aqui a saída que seria o binário assinado. Se não usar a imagem. E vamos fazer a gravação dessa imagem no slot primário, primeiramente. Aqui para vocês. Eu vou fazer aqui a escrita de uma imagem que não está assinada, mas que não está assinada no slot secundário. Estava aqui nesse endereço, é o slot secundário. Então, vou fazer o flash da imagem de atualização sem assinatura só para mostrar para vocês que o mcboot não permite a atualização. Vou iniciar aqui. Continua sendo inicia a imagem original, mesmo tendo gravado no slot secundário. O mcboot verificou essa imagem e não fez a permuta. Agora eu vou fazer a assinatura dessa imagem de atualização. Assinar aqui para esse update. Vou fazer o flash no slot secundário. Caso que eu estou fazendo flash e não estou reiniciando para eu poder mostrar aqui no pico com. Então, novamente aqui nos slots secundário. Vou fazer o flash, iniciou o swap. Imagine que reiniciou. Mesmo assim, no meio da casa que tinha acontecido uma queda de energia, o mcboot conseguiu se recuperar e conseguiu fazer o update. Terminou aqui a permuta e fez o boot. Se a gente reiniciar aqui de novo o dispositivo, ele iniciou a imagem atualizada, que foi copiada para o slot primário. É isso. A gente pode ver que o mcboot tem alguns mecanismos que permitem essa robustez no projeto de firmware. Se já tem padronizado uma forma de update, a camada de aplicação tem que se preocupar com menos coisas. Existe uma menor complexidade. Aqui temos as referências. A documentação do mcboot tem uma apresentação do David Brown, que é uma das cabeças pensantes do mcboot. E também tem esse artigo de um guia de porting do mcboot. Também tem bastante informações legais ali. Bom, por hoje é isso. Agradeço a atenção de todos. Obrigado e vamos para a sessão de perguntas e respostas. Muito obrigado e até mais.