{"id":10490,"date":"2015-06-18T08:29:54","date_gmt":"2015-06-18T11:29:54","guid":{"rendered":"http:\/\/www.telecelula.com.br\/wordpress\/?p=10490"},"modified":"2019-09-18T08:33:31","modified_gmt":"2019-09-18T11:33:31","slug":"detalhes-do-mediatek-particoes-e-pre-carregador","status":"publish","type":"post","link":"https:\/\/www.telecelula.com.br\/wordpress\/?p=10490","title":{"rendered":"Detalhes do MediaTek: Parti\u00e7\u00f5es e Pr\u00e9-carregador"},"content":{"rendered":"\n<p><em>NOTA: Esta \u00e9 uma continua\u00e7\u00e3o do\u00a0<a href=\"https:\/\/www.telecelula.com.br\/wordpress\/?p=10486\">artigo anterior<\/a>\u00a0da s\u00e9rie.\u00a0As informa\u00e7\u00f5es foram obtidas de v\u00e1rias fontes e, atrav\u00e9s da engenharia reversa, n\u00e3o tome como refer\u00eancia!<\/em><\/p>\n\n\n\n<p><em>ATUALIZA\u00c7\u00c3O 03.07.2015: Adicionar refer\u00eancias do Download Agent.<\/em><\/p>\n\n\n\n<p>Ap\u00f3s a ROM de inicializa\u00e7\u00e3o concluir a inicializa\u00e7\u00e3o do hardware principal, ela carrega o primeiro bloco do flash eMMC na SRAM On-chip e inicia a execu\u00e7\u00e3o.\u00a0Normalmente, esse seria o local do firmware do carregador de inicializa\u00e7\u00e3o do sistema operacional, mas nos SoCs do MediaTek, normalmente n\u00e3o \u00e9.\u00a0H\u00e1 um passo intermedi\u00e1rio: o Preloader.\u00a0\u00c9 um software que abstrai um pouco entre a plataforma e o carregador de inicializa\u00e7\u00e3o real e oferece alguns recursos adicionais, como a capacidade de inicializar a partir do MMC ou do NAND Flash ou de ler \/ gravar v\u00e1rias partes do flash via USB.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"overview\">vis\u00e3o global<\/h2>\n\n\n\n<p>Quando o MediaTek envia um pacote fonte do kernel para um fabricante, o pacote tamb\u00e9m cont\u00e9m o c\u00f3digo fonte do Preloader.&nbsp;Dependendo das altera\u00e7\u00f5es feitas pelo fabricante, o Preloader faz pequenas coisas diferentes em diferentes SoCs e placas, portanto, n\u00e3o \u00e9 f\u00e1cil criar uma descri\u00e7\u00e3o gen\u00e9rica que se adapte a todos os sistemas.<\/p>\n\n\n\n<p>A an\u00e1lise a seguir \u00e9 baseado no&nbsp;<a href=\"https:\/\/github.com\/suribi\/Thunder-Kernel\">ThunderKernel<\/a>&nbsp;c\u00f3digo fonte para o MT6582 SoC.&nbsp;A distribui\u00e7\u00e3o \u00e9 composta pelas seguintes partes:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Uma parte espec\u00edfica da plataforma&nbsp;<code>mediatek\/platform\/${platform}\/preloader<\/code>, cont\u00e9m a maior parte do c\u00f3digo.<\/li><li>Uma pe\u00e7a personalizada (espec\u00edfica do fabricante) no&nbsp;<code>mediatek\/custom\/${platform}\/preloader<\/code>.<\/li><li>Uma parte espec\u00edfica do dispositivo&nbsp;<code>mediatek\/custom\/${DEVICE}\/preloader<\/code>.<\/li><\/ul>\n\n\n\n<p>Agora vamos analisar o c\u00f3digo.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"cpu-init\">CPU Init<\/h2>\n\n\n\n<p>Quando o pr\u00e9-carregador \u00e9 iniciado, o SoC ainda n\u00e3o foi totalmente inicializado e muitas coisas est\u00e3o em um estado aleat\u00f3rio.&nbsp;Uma parte do c\u00f3digo do assembler&nbsp;<code>mediatek\/platform\/${platform}\/preloader\/src\/init\/init.s<\/code>executa as seguintes etapas para criar um estado limpo:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Limpe todos os registros.<\/li><li>Alterne para o modo privilegiado SVC32.<\/li><li>Desativar interrup\u00e7\u00f5es.<\/li><li>Configure os caches e outros detalhes menores (por exemplo, a pilha).<\/li><li>V\u00e1 para o&nbsp;<code>main<\/code>m\u00e9todo no c\u00f3digo C.<\/li><\/ol>\n\n\n\n<p>Agora a execu\u00e7\u00e3o continua&nbsp;<code>mediatek\/platform\/${platform}\/preloader\/src\/core\/main.c<\/code>, o que chama muitos outros m\u00e9todos, que novamente chamam muitos outros m\u00e9todos.&nbsp;N\u00e3o faz sentido desabilitar todas as linhas de c\u00f3digo deste artigo, portanto, darei uma vis\u00e3o de alto n\u00edvel do que est\u00e1 acontecendo e explicarei alguns detalhes quando necess\u00e1rio.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"platform-init\">Init da plataforma<\/h2>\n\n\n\n<p>O Preloader conta com alguns perif\u00e9ricos, por isso precisa inicializ\u00e1-los.&nbsp;Isso \u00e9 feito principalmente nos&nbsp;m\u00e9todos&nbsp;<code>platform_pre_init<\/code>e&nbsp;<code>platform_init<\/code>.&nbsp;A lista de perif\u00e9ricos cont\u00e9m o timer, o rel\u00f3gio PLL, o controlador de mem\u00f3ria DDR, o Watchdog, os pinos GPIO, o UART, a porta USB 1.1 e o circuito de gerenciamento de energia.<\/p>\n\n\n\n<p>H\u00e1 algo de especial aqui: ap\u00f3s a inicializa\u00e7\u00e3o do armazenamento flash, o Preloader oferece um modo de \u201cdownload de emerg\u00eancia\u201d precoce.&nbsp;O fabricante pode definir uma chave de hardware que, quando pressionada durante o init da plataforma Preloader, \u00e9 reiniciada imediatamente na ROM de inicializa\u00e7\u00e3o e aguarda o download.<\/p>\n\n\n\n<p>Nesse ponto, o Preloader tamb\u00e9m registra o motivo pelo qual o sistema foi inicializado:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>typedef enum {\n    BR_POWER_KEY = 0,\n    BR_USB,\n    BR_RTC,\n    BR_WDT,\n    BR_WDT_BY_PASS_PWK,\n    BR_TOOL_BY_PASS_PWK,\n    BR_2SEC_REBOOT,\n    BR_UNKNOWN\n} boot_reason_t;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"partitions\">Parti\u00e7\u00f5es<\/h2>\n\n\n\n<p>Depois de abrir a plataforma, o pr\u00e9-carregador tem acesso total ao armazenamento interno.&nbsp;O MediaTek decidiu particionar o armazenamento, mas a tabela de parti\u00e7\u00f5es est\u00e1 codificada.&nbsp;Ele \u00e9 gerado durante a gera\u00e7\u00e3o do Preloader a partir de um arquivo do Excel (sim, realmente)&nbsp;<code>mediatek\/build\/tools\/ptgen\/${platform}\/partition_table_${platform}.xls<\/code>pelo comando&nbsp;<code>.\/makeMtk -t ${device} ptgen<\/code>(aqui est\u00e1 um exemplo para o bq Aquaris E4.5 Ubuntu Edition):<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.lieberbiber.de\/wp-content\/uploads\/2015\/07\/partition_table_xls.jpg\" alt=\"\" class=\"wp-image-241\"\/><\/figure>\n\n\n\n<p>A estrutura da tabela de parti\u00e7\u00e3o gerada \u00e9 armazenada&nbsp;<code>out\/target\/product\/krillin\/obj\/PRELOADER_OBJ\/cust_part.c<\/code>e tem a seguinte apar\u00eancia (exemplo para o bq Aquaris E4.5 Ubuntu Edition):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static part_t platform_parts[PART_MAX_COUNT] = {\n        {PART_PRELOADER, 0, PART_SIZE_PRELOADER, 0,PART_FLAG_NONE},\n        {PART_MBR, 0, PART_SIZE_MBR, 0,PART_FLAG_NONE},\n        {PART_EBR1, 0, PART_SIZE_EBR1, 0,PART_FLAG_NONE},\n        {PART_PRO_INFO, 0, PART_SIZE_PRO_INFO, 0,PART_FLAG_NONE},\n        {PART_NVRAM, 0, PART_SIZE_NVRAM, 0,PART_FLAG_NONE},\n        {PART_PROTECT_F, 0, PART_SIZE_PROTECT_F, 0,PART_FLAG_NONE},\n        {PART_PROTECT_S, 0, PART_SIZE_PROTECT_S, 0,PART_FLAG_NONE},\n        {PART_SECURE, 0, PART_SIZE_SECCFG, 0,PART_FLAG_NONE},\n        {PART_UBOOT, 0, PART_SIZE_UBOOT, 0,PART_FLAG_NONE},\n        {PART_BOOTIMG, 0, PART_SIZE_BOOTIMG, 0,PART_FLAG_NONE},\n        {PART_RECOVERY, 0, PART_SIZE_RECOVERY, 0,PART_FLAG_NONE},\n        {PART_SECSTATIC, 0, PART_SIZE_SEC_RO, 0,PART_FLAG_NONE},\n        {PART_MISC, 0, PART_SIZE_MISC, 0,PART_FLAG_NONE},\n        {PART_LOGO, 0, PART_SIZE_LOGO, 0,PART_FLAG_NONE},\n        {PART_EXPDB, 0, PART_SIZE_EXPDB, 0,PART_FLAG_NONE},\n        {PART_ANDSYSIMG, 0, PART_SIZE_ANDROID, 0,PART_FLAG_NONE},\n        {PART_CACHE, 0, PART_SIZE_CACHE, 0,PART_FLAG_NONE},\n        {PART_USER, 0, PART_SIZE_USRDATA, 0,PART_FLAG_NONE},\n        {NULL,0,0,0,PART_FLAG_END},\n};<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"first-secure-boot-stage\">Primeiro est\u00e1gio de inicializa\u00e7\u00e3o segura<\/h2>\n\n\n\n<p>Ap\u00f3s carregar todas as parti\u00e7\u00f5es (e se o recurso estiver ativado), o Preloader inicializa o subsistema SecLib.&nbsp;O fornecedor do dispositivo fornece uma chave RSA de at\u00e9 2048 bits de comprimento (embora as chaves que eu vi tenham apenas 1024 bits).<\/p>\n\n\n\n<p>O que o SecLib faz exatamente \u00e9 desconhecido.&nbsp;Ele pega os dados de configura\u00e7\u00e3o da parti\u00e7\u00e3o SECURE (se existir) e a chave RSA e, em seguida, chama o blob bin\u00e1rio&nbsp;<code>mediatek\/platform\/${platform}\/preloader\/src\/SecLib.a<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"boot-mode-selection\">Sele\u00e7\u00e3o do modo de inicializa\u00e7\u00e3o<\/h2>\n\n\n\n<p>Ap\u00f3s (opcionalmente) confirmar a inicializa\u00e7\u00e3o segura, o Preloader decide qual modo de inicializa\u00e7\u00e3o usar.<\/p>\n\n\n\n<p><code>NORMAL_BOOT<\/code>ser\u00e1 usado se a inicializa\u00e7\u00e3o segura estiver desativada ou o m\u00f3dulo de inicializa\u00e7\u00e3o segura n\u00e3o disser o contr\u00e1rio.&nbsp;Se o Modo de Download estiver ativado, este modo tentar\u00e1 entrar imediatamente.<\/p>\n\n\n\n<p>H\u00e1 uma longa lista de outros modos de inicializa\u00e7\u00e3o poss\u00edveis, e nem todos s\u00e3o auto-explicativos:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>typedef enum\n{\n    NORMAL_BOOT = 0,\n    META_BOOT = 1,\n    RECOVERY_BOOT = 2,\n    SW_REBOOT = 3,\n    FACTORY_BOOT = 4,\n    ADVMETA_BOOT = 5,\n    ATE_FACTORY_BOOT = 6,\n    ALARM_BOOT = 7,\n#if defined (MTK_KERNEL_POWER_OFF_CHARGING)\n    KERNEL_POWER_OFF_CHARGING_BOOT = 8,\n    LOW_POWER_OFF_CHARGING_BOOT = 9,\n#endif\n    FASTBOOT = 99,\n    DOWNLOAD_BOOT = 100,\n    UNKNOWN_BOOT\n} BOOTMODE;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"download-mode\">Modo de download<\/h2>\n\n\n\n<p>Para poder entrar no modo Download, o Preloader precisa descobrir se um host est\u00e1 conectado via USB ou UART e executando a MTK SP Flash Tool.&nbsp;Isso \u00e9 feito atrav\u00e9s da configura\u00e7\u00e3o de uma disciplina virtual do CDC ACM no USB, para que ambas as linhas sejam de fato portas seriais e se comportem da mesma forma.<\/p>\n\n\n\n<p>A porta USB pressup\u00f5e que a ferramenta esteja conectada se receber uma mensagem CDC de \u201cset line coding\u201d (configura a taxa de transmiss\u00e3o etc.).&nbsp;Em seguida, envia a string&nbsp;<code>READY<\/code>para a ferramenta e aguarda a recep\u00e7\u00e3o de um token de oito bytes.<\/p>\n\n\n\n<p>Ap\u00f3s a detec\u00e7\u00e3o bem-sucedida, a ferramenta pode enviar a\u00a0<code>Start<\/code>sequ\u00eancia de comandos\u00a0especial\u00a0(\u00a0<code>0xa0 0x0a 0x50 0x05<\/code>) para entrar em um modo especial dispon\u00edvel apenas via USB.\u00a0Ele interpreta os seguintes comandos (deixei os marcados com \u201clegado\u201d de fora):<\/p>\n\n\n\n<table class=\"wp-block-table\"><thead><tr><th>Comando<\/th><th>Byte de comando<\/th><th>Fun\u00e7\u00e3o<\/th><\/tr><\/thead><tbody><tr><td><code>CMD_GET_BL_VER<\/code><\/td><td>0xfe<\/td><td>Obtenha a vers\u00e3o do Preloader (parece ser sempre &#8220;1&#8221;)<\/td><\/tr><tr><td><code>CMD_GET_HW_SW_VER<\/code><\/td><td>0xfc<\/td><td>Retornar subc\u00f3digo do hardware, vers\u00e3o do hardware e vers\u00e3o do software<\/td><\/tr><tr><td><code>CMD_GET_HW_CODE<\/code><\/td><td>0xfd<\/td><td>Retornar c\u00f3digo e status de hardware<\/td><\/tr><tr><td><code>CMD_SEND_DA<\/code><\/td><td>0xd7<\/td><td>Envie um bin\u00e1rio especial \u201cDownload Agent\u201d para o SoC, assinado com uma chave.<\/td><\/tr><tr><td><code>CMD_JUMP_DA<\/code><\/td><td>0xd5<\/td><td>Defina o modo de inicializa\u00e7\u00e3o&nbsp;<code>DOWNLOAD_BOOT<\/code>e inicie a execu\u00e7\u00e3o do Download Agent enviado na etapa anterior.<\/td><\/tr><tr><td><code>CMD_GET_TARGET_CONFIG<\/code><\/td><td>0xd8<\/td><td>Obtenha sinalizadores de configura\u00e7\u00e3o do Preloader suportados<\/td><\/tr><tr><td><code>CMD_READ16<\/code><\/td><td>0xa2<\/td><td>Ler dados da mem\u00f3ria SoC (par\u00e2metro de comprimento de 16 bits)<\/td><\/tr><tr><td><code>CMD_WRITE16<\/code><\/td><td>0xd2<\/td><td>Gravar dados na mem\u00f3ria SoC (par\u00e2metro de comprimento de 16 bits)<\/td><\/tr><tr><td><code>CMD_READ32<\/code><\/td><td>0xd1<\/td><td>Ler dados da mem\u00f3ria SoC (par\u00e2metro de comprimento de 32 bits)<\/td><\/tr><tr><td><code>CMD_WRITE32<\/code><\/td><td>0xd4<\/td><td>Gravar dados na mem\u00f3ria SoC (par\u00e2metro de comprimento de 32 bits)<\/td><\/tr><tr><td><code>CMD_PWR_INIT<\/code><\/td><td>0xc4<\/td><td>Inicialize o controlador de gerenciamento de energia (efetivamente uma opera\u00e7\u00e3o nula porque j\u00e1 est\u00e1 ativada)<\/td><\/tr><tr><td><code>CMD_PWR_DEINIT<\/code><\/td><td>0xc5<\/td><td>Desligue o controlador de gerenciamento de energia (efetivamente um nulo)<\/td><\/tr><tr><td><code>CMD_PWR_READ16<\/code><\/td><td>0xc6<\/td><td>Leia 16 bits de dados da mem\u00f3ria da interface do controlador de gerenciamento de energia<\/td><\/tr><tr><td><code>CMD_PWR_WRITE16<\/code><\/td><td>0xc7<\/td><td>Grave 16 bits de dados na mem\u00f3ria da interface do controlador de gerenciamento de energia<\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>A etapa Download Agent \u00e9 necess\u00e1ria porque, dessa forma, a Flash Tool sempre pode enviar uma vers\u00e3o atual para a vers\u00e3o exata do hardware que est\u00e1 sendo usada.<\/p>\n\n\n\n<p>O UART n\u00e3o tem possibilidade de detectar se a linha f\u00edsica est\u00e1 energizada; portanto, ele envia a string&nbsp;<code>READY<\/code>e espera receber um token de oito bytes de volta.&nbsp;Nesse caso, assume que a ferramenta est\u00e1 presente.<\/p>\n\n\n\n<p>Observe que os comandos especiais da tabela acima&nbsp;<em>n\u00e3o<\/em>&nbsp;est\u00e3o&nbsp;dispon\u00edveis ao se comunicar pelo UART, provavelmente porque a ROM de inicializa\u00e7\u00e3o j\u00e1 oferece a maioria desses comandos via UART.<\/p>\n\n\n\n<p>Se o&nbsp;<code>Start<\/code>comando&nbsp;especial&nbsp;n\u00e3o for emitido pelo host via USB, o Preloader entra em um modo comum no qual aceita os seguintes comandos por USB e UART:<\/p>\n\n\n\n<table class=\"wp-block-table\"><thead><tr><th>Comando<\/th><th>Cadeia de comando<\/th><th>Fun\u00e7\u00e3o<\/th><\/tr><\/thead><tbody><tr><td><code>SWITCH_MD_REQ<\/code><\/td><td><code>SWITCHMD<\/code><\/td><td>Provavelmente deve mudar o modem para o modo de download de firmware, mas parece n\u00e3o fazer nada no MT6582?<\/td><\/tr><tr><td><code>ATCMD_NBOOT_REQ<\/code><\/td><td><code>AT+NBOOT<\/code><\/td><td>Mudar para o&nbsp;<code>NORMAL_BOOT<\/code>modo<\/td><\/tr><tr><td><code>META_STR_REQ<\/code><\/td><td><code>METAMETA<\/code><\/td><td>Mudar para o&nbsp;<code>META_BOOT<\/code>modo<\/td><\/tr><tr><td><code>FACTORY_STR_REQ<\/code><\/td><td><code>FACTFACT<\/code><\/td><td>Mudar para o&nbsp;<code>FACTORY_BOOT<\/code>modo<\/td><\/tr><tr><td><code>META_ADV_REQ<\/code><\/td><td><code>ADVEMETA<\/code><\/td><td>Mudar para o&nbsp;<code>ADVMETA_BOOT<\/code>modo<\/td><\/tr><tr><td><code>ATE_STR_REQ<\/code><\/td><td><code>FACTORYM<\/code><\/td><td>Mudar para o&nbsp;<code>ATE_FACTORY_BOOT<\/code>modo<\/td><\/tr><tr><td><code>FB_STR_ACK<\/code><\/td><td><code>FASTBOOT<\/code><\/td><td>Mudar para o&nbsp;<code>FASTBOOT<\/code>modo<\/td><\/tr><\/tbody><\/table>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"second-secure-boot-stage\">Segundo est\u00e1gio de inicializa\u00e7\u00e3o segura<\/h2>\n\n\n\n<p>Novamente, n\u00e3o se sabe o que o SecLib faz nesse est\u00e1gio, ele chama o blob bin\u00e1rio na maioria das vezes.<\/p>\n\n\n\n<p>As seguintes informa\u00e7\u00f5es (question\u00e1veis) foram obtidas examinando o wrapper C e despejando os s\u00edmbolos e seq\u00fc\u00eancias de caracteres da biblioteca:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Os dados de seguran\u00e7a v\u00eam da&nbsp;<code>SECSTATIC<\/code>parti\u00e7\u00e3o<\/li><li>Valida\u00e7\u00e3o de assinaturas de imagem criptogr\u00e1fica usando RSA \/ SHA1<\/li><li>A&nbsp;<code>UBOOT<\/code>,&nbsp;<code>LOGO<\/code>,&nbsp;<code>BOOTIMG<\/code>,&nbsp;<code>RECOVERY<\/code>e&nbsp;<code>ANDROID<\/code>parti\u00e7\u00f5es parecem ser verificado em algum momento<\/li><li>O &#8220;nome do cliente&#8221; parece ter sido verificado de alguma forma, mas por qu\u00ea?<\/li><\/ul>\n\n\n\n<p>As imagens assinadas necess\u00e1rias provavelmente s\u00e3o geradas pelos&nbsp;<code>SignTool<\/code>bin\u00e1rios em&nbsp;<code>mediatek\/build\/tools\/SignTool<\/code>.<\/p>\n\n\n\n<p>O fabricante do dispositivo pode adicionar medidas de seguran\u00e7a adicionais.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"load-core-boot-images\">Carregar imagens principais de inicializa\u00e7\u00e3o<\/h2>\n\n\n\n<p>Agora que o Preloader sabe que o sistema \u00e9 seguro, ele pode carregar as imagens do firmware a partir do flash interno.<\/p>\n\n\n\n<p>Este \u00e9 um processo altamente especializado, porque cada imagem deve ser processada de maneira diferente.&nbsp;Por exemplo, o firmware do modem HSPA no MT6582 deve ser alimentado no modem usando registros e comandos especiais, enquanto o carregador de inicializa\u00e7\u00e3o u-Boot pode ser copiado no endere\u00e7o de mem\u00f3ria correto.&nbsp;Nesta etapa, o Preloader tamb\u00e9m decidir\u00e1 qual \u00e9 o pr\u00f3ximo componente que ser\u00e1 executado ap\u00f3s o t\u00e9rmino.&nbsp;Por padr\u00e3o, essa ser\u00e1 a imagem armazenada na&nbsp;<code>UBOOT<\/code>parti\u00e7\u00e3o.<\/p>\n\n\n\n<p>Observe que nesta etapa apenas o firmware mais b\u00e1sico \u00e9 carregado, geralmente esse \u00e9 apenas o modem e o carregador de inicializa\u00e7\u00e3o.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"platform-post-init\">Plataforma p\u00f3s init<\/h2>\n\n\n\n<p>Nesta etapa, a plataforma \u00e9 colocada em um estado definido para o pr\u00f3ximo componente do processo de inicializa\u00e7\u00e3o (carregador de inicializa\u00e7\u00e3o, Little Kernel).&nbsp;A etapa mais importante \u00e9 transmitir os argumentos de inicializa\u00e7\u00e3o que foram definidos durante a execu\u00e7\u00e3o do Preloader.&nbsp;Esperamos que isso fa\u00e7a mais sentido, quando examinarmos o que acontece ap\u00f3s o Preloader, todo o design do MediaTek \u00e9 um pouco complicado.<\/p>\n\n\n\n<p>A estrutura do argumento de inicializa\u00e7\u00e3o no MT6852 \u00e9 assim:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>typedef struct {\n    u32 magic;                \/\/ 0x504c504c\n    boot_mode_t mode;         \/\/ Boot mode\n    u32 e_flag;\n    u32 log_port;\n    u32 log_baudrate;\n    u8  log_enable;\n    u8  part_num;             \/\/ Number of partitions\n    u8  reserved[2];\n    u32 dram_rank_num;\n    u32 dram_rank_size[4];\n    u32 boot_reason;          \/\/ Boot reason\n    u32 meta_com_type;\n    u32 meta_com_id;\n    u32 boot_time;\n    da_info_t da_info;\n    SEC_LIMIT sec_limit;\n    part_hdr_t *part_info;    \/\/ Partition info\n    u8  md_type[4];\n    u32 ddr_reserve_enable;\n    u32 ddr_reserve_success;\n    u32 chip_ver;\n} boot_arg_t;<\/code><\/pre>\n\n\n\n<p>Ele \u00e9 colocado em um local de mem\u00f3ria definido, onde &#8220;sobrevive&#8221; at\u00e9 que o pr\u00f3ximo componente o pegue.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"boot-the-next-component\">Inicialize o pr\u00f3ximo componente<\/h2>\n\n\n\n<p>O \u00faltimo passo do Preloader \u00e9 pular para o local do pr\u00f3ximo componente, geralmente o \u201cLittle Kernel\u201d carregado na&nbsp;<code>UBOOT<\/code>parti\u00e7\u00e3o.<\/p>\n\n\n\n<p>Se voc\u00ea souber melhor e \/ ou algo mudou, me encontre no Launchpad.net ou no Freenode IRC e entre em contato!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"resources\">Recursos<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/github.com\/suribi\/Thunder-Kernel\">Thunder-Kernel<\/a><\/li><li><a href=\"http:\/\/blog.csdn.net\/loongembedded\/article\/details\/38143289\">MTK6577 Android Start &#8211; pr\u00e9-carregador<\/a>&nbsp;(em chin\u00eas)<\/li><li><a href=\"http:\/\/wenku.baidu.com\/view\/d44d5cd9ad51f01dc281f129.html\">Introdu\u00e7\u00e3o das ferramentas MTK<\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>NOTA: Esta \u00e9 uma continua\u00e7\u00e3o do\u00a0artigo anterior\u00a0da s\u00e9rie.\u00a0As informa\u00e7\u00f5es foram obtidas de v\u00e1rias fontes e, atrav\u00e9s da engenharia reversa, n\u00e3o tome como refer\u00eancia! ATUALIZA\u00c7\u00c3O 03.07.2015: Adicionar refer\u00eancias do Download Agent. Ap\u00f3s a ROM de inicializa\u00e7\u00e3o concluir a inicializa\u00e7\u00e3o do hardware principal, ela carrega o primeiro bloco do flash eMMC na SRAM On-chip e inicia a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-10490","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-treinamento-tecnico-em-video","7":"czr-hentry"},"_links":{"self":[{"href":"https:\/\/www.telecelula.com.br\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/10490","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.telecelula.com.br\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.telecelula.com.br\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.telecelula.com.br\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.telecelula.com.br\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10490"}],"version-history":[{"count":1,"href":"https:\/\/www.telecelula.com.br\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/10490\/revisions"}],"predecessor-version":[{"id":10491,"href":"https:\/\/www.telecelula.com.br\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/10490\/revisions\/10491"}],"wp:attachment":[{"href":"https:\/\/www.telecelula.com.br\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10490"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.telecelula.com.br\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10490"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.telecelula.com.br\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10490"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}