{"id":32984,"date":"2018-01-19T20:14:35","date_gmt":"2018-01-19T20:14:35","guid":{"rendered":"http:\/\/antonini.psc.br\/?p=32984"},"modified":"2021-04-02T04:55:58","modified_gmt":"2021-04-02T04:55:58","slug":"boot-no-raspberry-pi","status":"publish","type":"post","link":"https:\/\/antonini.ddns.net\/?p=32984","title":{"rendered":"Boot no Raspberry Pi"},"content":{"rendered":"<p style=\"text-align: justify;\">Raspberry Pi e o processo de boot<br \/>\n29\/10\/2012 &#8211; POR SERGIO PRADO<\/p>\n<p style=\"text-align: justify;\">Categorias: Raspberry Pi Tags: arm11, bootloader, broadcom, gpu, Kernel, raspberry pi<\/p>\n<p style=\"text-align: justify;\">Uma das primeiras coisas que voc\u00ea precisa fazer quando come\u00e7ar a trabalhar com uma nova plataforma de hardware \u00e9 entender o seu processo de boot.<\/p>\n<p style=\"text-align: justify;\">E o processo de boot da Raspberry Pi \u00e9 um pouco diferente comparado \u00e0s outras plataformas comuns que rodam Linux como a Beagleboard, Beaglebone ou i.MX53. A come\u00e7ar pelo hardware\u2026<\/p>\n<p style=\"text-align: justify;\">Quando voc\u00ea energiza o SoC da Broadcom (BCM2835), quem assume o controle n\u00e3o \u00e9 a CPU (ARM1176JZ-F), mas sim a GPU, respons\u00e1vel pelo processamento gr\u00e1fico do chip! Sim, caros leitores. Ao ser energizada, o processador principal da placa \u00e9 a GPU, e o co-processador \u00e9 o ARM11, que fica ali, paradinho, esperando sua vez para entrar na brincadeira.<\/p>\n<p style=\"text-align: justify;\">Outra diferen\u00e7a \u00e9 que a Raspberry Pi (pelo menos por enquanto) n\u00e3o usa o U-Boot como bootloader padr\u00e3o para carregar e executar o kernel Linux. Mas vamos come\u00e7ar pelo come\u00e7o\u2026<\/p>\n<p style=\"text-align: justify;\"><strong>O primeiro eletron<\/strong><\/p>\n<p style=\"text-align: justify;\">Conforme descrevi mais acima, ao energizar a Raspberry Pi, quem assume o controle da placa \u00e9 o core da GPU. E o primeiro c\u00f3digo a ser executado esta armazenado em ROM, dentro do SoC, inacess\u00edvel a n\u00f3s, meros mortais que n\u00e3o trabalhamos na Broadcom.<\/p>\n<p style=\"text-align: justify;\">Este c\u00f3digo \u00e9 respons\u00e1vel por procurar um c\u00f3digo de boot em algumas interfaces de armazenamento, carregar este c\u00f3digo para uma mem\u00f3ria interna (cache L2 do SoC para ser mais preciso) e executar. E que tipos de interfaces de armazenamento o SoC reconhece como dispositivo de boot? N\u00e3o d\u00e1 para saber, j\u00e1 que n\u00e3o temos o datasheet do SoC. Temos dispon\u00edvel apenas uma parte do datasheet, que descreve o acesso aos perif\u00e9ricos do SoC, mas que n\u00e3o descreve o processo de boot (este documento pode ser acessado aqui). Mas se voc\u00ea quiser o datasheet do BCM2835 \u00e9 f\u00e1cil, \u00e9 s\u00f3 assinar um NDA com a Broadcom\u2026:)<\/p>\n<p style=\"text-align: justify;\">Voltando ao processo de boot, o que sabemos \u00e9 que o SoC procura na primeira parti\u00e7\u00e3o do cart\u00e3o SD um arquivo chamado bootcode.bin. Esta parti\u00e7\u00e3o do cart\u00e3o SD precisa estar formatada com FAT32, e o bootcode.bin \u00e9 um c\u00f3digo compilado para ser executado na GPU. Sim, voc\u00ea adivinhou, n\u00e3o temos os fontes deste bootloader de primeiro est\u00e1gio\u2026 :(<\/p>\n<p style=\"text-align: justify;\">Resumindo a primeira etapa de boot: voc\u00ea liga a Raspberry Pi, a GPU assume, procura o arquivo bootcode.bin na primeira parti\u00e7\u00e3o do cart\u00e3o SD, carrega para a mem\u00f3ria cache L2 e executa.<\/p>\n<p style=\"text-align: justify;\">Mas o que ent\u00e3o faz este bootcode.bin?<\/p>\n<p style=\"text-align: justify;\"><strong>O segundo est\u00e1gio<\/strong><\/p>\n<p style=\"text-align: justify;\">O bootcode.bin tem duas responsabilidades principais: inicializar a SDRAM e carregar um bootloader de segundo est\u00e1gio para ela. Este bootloader de segundo est\u00e1gio \u00e9 um arquivo chamado start.elf que tamb\u00e9m deve estar na primeira parti\u00e7\u00e3o do cart\u00e3o SD.<\/p>\n<p style=\"text-align: justify;\">O start.elf tamb\u00e9m \u00e9 um bin\u00e1rio compilado para ser executado na GPU, e com a ajuda de um outro bin\u00e1rio chamado fixup.dat, tamb\u00e9m possui duas responsabilidades principais: configurar o hardware de acordo com um arquivo de configura\u00e7\u00e3o e carregar o kernel Linux.<\/p>\n<p style=\"text-align: justify;\">O arquivo de configura\u00e7\u00e3o \u00e9 chamado config.txt, e tamb\u00e9m deve estar na primeira parti\u00e7\u00e3o do cart\u00e3o SD. Neste arquivo de configura\u00e7\u00e3o voc\u00ea pode configurar o hardware, definir mapeamento de mem\u00f3ria, especificar par\u00e2metros para carregar o kernel Linux, etc. Uma especifica\u00e7\u00e3o completa do arquivo encontra-se aqui.<\/p>\n<p style=\"text-align: justify;\">Ap\u00f3s ler o arquivo de configura\u00e7\u00e3o, ele ir\u00e1 carregar o arquivo kernel.img, que tamb\u00e9m deve estar na primeira parti\u00e7\u00e3o do cart\u00e3o SD. Esse arquivo nada mais \u00e9 do que a imagem do kernel Linux. Antes de executar a imagem do kernel, ele \u00e9 capaz de passar a linha de comandos para o kernel, que pode ser definida no arquivo cmdline.txt, ou em uma vari\u00e1vel no arquivo config.txt.<\/p>\n<p style=\"text-align: justify;\">Resumo da \u00f3pera: voc\u00ea energiza a placa, a GPU assume, carrega o bootcode.bin para a mem\u00f3ria cache L2 e executa. O bootcode.bin inicializa a SDRAM, carrega o start.elf para a RAM externa e executa. O start.elf configura o hardware de acordo com o arquivo config.txt, carrega a imagem do kernel em kernel.img, l\u00ea a linha de comandos do kernel no cmdline.txt, e d\u00e1 vida ao pinguim mais famoso do universo. Todos estes arquivos devem estar na primeira parti\u00e7\u00e3o do cart\u00e3o SD, que deve estar formatado com FAT32:<\/p>\n<p style=\"text-align: justify;\"><em>$ ls \/media\/raspberrypi <\/em><\/p>\n<p style=\"text-align: justify;\"><em>bootcode.bin cmdline.txt config.txt fixup.dat kernel.img start.elf<\/em><\/p>\n<p style=\"text-align: justify;\">Obs: Em uma vers\u00e3o mais antiga do firmware de boot, existia um passo adicional. Em vez do bootcode.bin carregar diretamente o start.elf, ele carregava o loader.bin, e este era o respons\u00e1vel por carregar o start.elf. Este passo adicional foi removido nas vers\u00f5es mais novas do firmware do boot.<\/p>\n<p style=\"text-align: justify;\"><strong>O firmware<\/strong><\/p>\n<p style=\"text-align: justify;\">Todo o firmware descrito aqui, com exce\u00e7\u00e3o da imagem do kernel (kernel.img) pode ser baixado no reposit\u00f3rio oficial do projeto no github em https:\/\/github.com\/raspberrypi\/firmware. Mas nada de fontes, voc\u00ea s\u00f3 vai encontrar neste projeto os bin\u00e1rios e alguma documenta\u00e7\u00e3o, o suficiente para voc\u00ea carregar e executar o seu sistema Linux na Raspberry Pi.<\/p>\n<p style=\"text-align: justify;\">No pr\u00f3ximo artigo vamos construir um sistema Linux do zero para a Raspberry Pi. At\u00e9 l\u00e1!<\/p>\n<p style=\"text-align: justify;\">Um abra\u00e7o,<\/p>\n<p style=\"text-align: justify;\">Sergio Prado<\/p>\n<p style=\"text-align: center;\">[<a href=\"javascript:history.go(-1)\">Voltar<\/a>]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Raspberry Pi e o processo de boot 29\/10\/2012 &#8211; POR SERGIO PRADO Categorias: Raspberry Pi Tags: arm11, bootloader, broadcom, gpu, Kernel, raspberry pi Uma das primeiras coisas que voc\u00ea precisa fazer quando come\u00e7ar a trabalhar com uma nova plataforma de hardware \u00e9 entender o seu processo de boot. E o processo de boot da Raspberry [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24],"tags":[],"class_list":["post-32984","post","type-post","status-publish","format-standard","hentry","category-informatica"],"_links":{"self":[{"href":"https:\/\/antonini.ddns.net\/index.php?rest_route=\/wp\/v2\/posts\/32984","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/antonini.ddns.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/antonini.ddns.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/antonini.ddns.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/antonini.ddns.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=32984"}],"version-history":[{"count":2,"href":"https:\/\/antonini.ddns.net\/index.php?rest_route=\/wp\/v2\/posts\/32984\/revisions"}],"predecessor-version":[{"id":32986,"href":"https:\/\/antonini.ddns.net\/index.php?rest_route=\/wp\/v2\/posts\/32984\/revisions\/32986"}],"wp:attachment":[{"href":"https:\/\/antonini.ddns.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=32984"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/antonini.ddns.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=32984"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/antonini.ddns.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=32984"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}