mirror of
https://github.com/elua/elua.git
synced 2025-01-08 20:56:17 +08:00
286 lines
15 KiB
HTML
286 lines
15 KiB
HTML
$$HEADER$$
|
|
<h3><a name="title" href="http://www.eluaproject.net/en/Building_GCC_for_Cortex" class="local">Construindo GCC para o Cortex</a></h3>
|
|
|
|
<p>Este tutorial explica como criar um CCG+Newlib toolchain que poderá ser usado para compilar programas na arquitetura Cortex(Thumb2), tornando assim possível a compilação de programas para um grande número de CPUs Cortex(<a href="http://www.luminarymicro.com/">Luminary Micro</a>, <a href="http://www.st.com/mcu/inchtml-pages-stm32.html">ST</a>, com nova CPU Cortex sendo anunciada pela Atmel e outras companhias). Estou escrevendo este tutorial porque eu precisei trabalhar com uma CPU Cortex para o projeto eLua e não consegui encontrar em lugar nenhum, alguma ajuda para construir uma GCC para essa arquitetura. Você precisará de uma toolchain se quiser compilar eLua para CPUs Cortex-M3.</p>
|
|
|
|
<p><strong>
|
|
AVISO: Não sou um especialista no processo de compilação de CGC/newlib/binutils. Tenho certeza de que existem melhores formas de realizar o que estou descrevendo aqui, no entanto desejo apenas uma maneira rápida de construir um toolchain, não tenho nenhuma intenção de ficar muito íntimo do processo de construção. Se você acha que o que fiz aqui está errado, impreciso ou, simplesmente, escandalosamente feio, não hesite em <a href="http://www.eluaproject.net/en/Contact">contactar-me</a> e farei as correcções necessárias. E claro, este tutorial é fornecido sem qualquer garantia.</strong></p>
|
|
|
|
<h2>Pré-requisitos</h2>
|
|
<p>Para construir seu toolchain você precisará de:</p>
|
|
|
|
<ul>
|
|
|
|
<li>Um computador rodando Linux: Eu uso Ubuntu 8.04, mas qualquer Linux irá fazer desde que você saiba como encontrar o equivalente do "apt-get" para a sua distribuição. Não entrarei em detalhes sobre isso, pesquise no Google e você encontrará o que você precisa. Assumimos também que o Linux já tem uma "base" nativa toolchain instalada (gcc/make e afins). Isto é verdadeiro para o Ubuntu após a sua instalação. Novamente, você precisa verificar a sua distribuição específica.</li>
|
|
|
|
|
|
<li>GNU binutils: faça o download clicando <a href="http://ftp.gnu.org/gnu/binutils/">aqui</a>. No momento em que escrevia este tutorial, as versões mais recentes eram 2,18, que por algum motivo estranho recusou-se a compilar no meu sistema, por isso estou usando a versão 2,17. UPDATE: você deve usar a nova distribuição binutils 2.19 para o Cortex toolchain, desde que este corrigiu alguns problemas do compilador. Você não conseguirá compilar o eLua 0.5 ou maior se não utilizar binutils 2.19.</li>
|
|
|
|
<li>GCC: A partir do suporte para Cortex (Thumb2) iniciado na versão 4.3.0, você deve fazer o download desta versão ou mais recente. Enquanto preparava esse tutorial, a versão mais recente era a 4.3.1, a qual foi utilizada para esse tutorial. Faça o download <a href="http://gcc.gnu.org/mirrors.html">aqui</a> depois de escolher um bom servidor mirror.</li>
|
|
|
|
<li>Newlib: Enquanto escrevia este tutorial, a versão mais recentes era a 1.16.0. Entretanto, a versão CVS contêm algumas correções para a arquitetura Thumb2, algumas delas muito importantes (como setjmp/longjmp), logo você precisará obter os fontes do CVS(isto mudará bastante quando a nova versão oficial da NewLib for liberada). Então faça o download do diretório <a href="http://sourceware.org/newlib/download.html">http://sourceware.org/newlib/download.html</a> e siga as instruções para obter os fontes CVS mais recentes.</li>
|
|
|
|
<li>Além disso, o tutorial assume que você está usando o bash como seu shell. Se você usar qualquer outra coisa, talvez seja necessário ajustar alguns comandos do shell específico.</li>
|
|
|
|
</ul>
|
|
|
|
|
|
<p>Você ainda precisará de outros programas e bibliotecas a fim de montar o toolchain. Para instalá-los execute o seguinte comando:</p>
|
|
|
|
<p><br></p>
|
|
|
|
<table class="table_cod">
|
|
<tbody><tr>
|
|
<th>$ sudo apt-get install flex bison libgmp3-dev libmpfr-dev autoconf texinfo build-essential</th>
|
|
</tr>
|
|
</tbody></table>
|
|
|
|
|
|
<p>Em seguida, decida onde pretende instalar o seu toolchain. Eles geralmente são instalados no diretório /usr/local/, logo, assumiremos o diretório /usr/local/cross-cortex para este tutorial. Para agilizar a digitação, defina este caminho como padrão na variável do ambiente:</p>
|
|
|
|
<p><br></p>
|
|
|
|
<table class="table_cod">
|
|
<tbody><tr>
|
|
<th>$ export TOOLPATH=/usr/local/cross-cortex</th>
|
|
</tr>
|
|
</tbody></table>
|
|
|
|
|
|
|
|
<h2>Passo 1: binutils</h2>
|
|
|
|
<p>Este é o passo mais fácil: descompactar, configurar, montar.</p>
|
|
|
|
<p><br></p>
|
|
|
|
<table class="table_cod">
|
|
<tbody><tr align="left">
|
|
<th>$ tar -xvjf binutils-2.19.tar.bz2</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ cd binutils-2.19</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ mkdir build</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ cd build</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$
|
|
../configure --target=arm-elf --prefix=$TOOLPATH --enable-interwork
|
|
--enable-multilib --with-gnu-as --with-gnu-ld --disable-nls</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ make all</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ sudo make install</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ export PATH=${TOOLPATH}/bin:$PATH</th>
|
|
</tr>
|
|
</tbody></table>
|
|
|
|
|
|
|
|
<p>Agora você tem os "binutils" da CPU Cortex(assembler, linker, disassembler ...) em seu PATH. Eles funcionam com a arquitetura Thumb2.</p>
|
|
|
|
<h2>Passo 2: GCC básico</h2>
|
|
|
|
<p>Nesta etapa vamos construir um GCC "básico" (ou seja, uma GCC sem nenhuma lib, a qual usaremos, a fim de criar todas as bibliotecas para o nosso objetivo). Mas primeiro temos de fazer uma rápida modificação nos arquivos de configuração. Fora desse ambiente, o pacote GCC 4.3.1/newlib não compilará corretamente, dando um erro muito estranho "Link tests are not allowed after GCC_NO_EXECUTABLES". Após googlear um pouco, encontrei a solução para isso:</p>
|
|
|
|
<p><br></p>
|
|
|
|
<table class="table_cod">
|
|
<tbody><tr align="left">
|
|
<th>$ tar -xvjf gcc-4.3.1.tar.bz2</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ cd gcc-4.3.1/libstdc++-v3</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ joe configure.ac </th>
|
|
</tr>
|
|
</tbody></table>
|
|
|
|
|
|
<p>Estou usando "joe" aqui como meu editor de texto Linux favorito, você pode usar qualquer outro editor de texto. Agora encontre a linha que tem "AC_LIBTOOL_DLOPEN" e adicione um "#" no inicio da linha:</p>
|
|
|
|
|
|
<code># AC_LIBTOOL_DLOPEN<br></code>
|
|
|
|
<p>Salve o arquivo e saia do editor de texto.</p>
|
|
|
|
<p><br></p>
|
|
|
|
<table class="table_cod">
|
|
<tbody><tr>
|
|
<th>$ autoconf</th>
|
|
</tr>
|
|
<tr>
|
|
<th style="text-align: left;">$ cd ..</th>
|
|
</tr>
|
|
</tbody></table>
|
|
|
|
|
|
|
|
<p>Ótimo, agora sabemos que podemos compilar, então vamos em frente:</p>
|
|
|
|
|
|
<p><br></p>
|
|
|
|
<table class="table_cod">
|
|
<tbody><tr align="left">
|
|
<th>$ mkdir build</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ cd build</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$
|
|
../configure --target=arm-elf --prefix=$TOOLPATH --enable-interwork
|
|
--enable-multilib --enable-languages="c,c++" --with-newlib
|
|
--without-headers --disable-shared --with-gnu-as --with-gnu-ld</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ make all-gcc</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ sudo make install-gcc</th>
|
|
</tr>
|
|
</tbody></table>
|
|
|
|
|
|
|
|
<p>No meu sistema, a execução da última linha acima(sudo make install-gcc) gera um erro, devido a impossibilidade de encontrar o arquivo binutils. Se isso também acontece no seu sistema, aqui está uma maneira rápida de resolver:</p>
|
|
|
|
|
|
<p><br></p>
|
|
|
|
<table style="width: 376px; height: 157px;" class="table_cod">
|
|
<tbody><tr>
|
|
<th>$ sudo -s -H</th>
|
|
</tr><tr><td align="undefined" valign="undefined"><code># export PATH=/usr/local/cross-cortex/bin:$PATH</code></td></tr><tr><td align="undefined" valign="undefined"><code># make install-gcc</code></td></tr><tr><td align="undefined" valign="undefined"><code># exit</code></td></tr>
|
|
</tbody></table>
|
|
|
|
|
|
<code><br><br><br></code>
|
|
|
|
|
|
<h2>Passo 3: Newlib</h2>
|
|
|
|
<p>Mais uma vez, algumas modificações s;ão necessárias antes de começarmos a compilação. Devido a versão CVS da NewLib parecer não permitir o suporte necessário para o Thumb2, precisamos fazer a NewLib saltar algumas de suas libraries durante a compilação:</p>
|
|
|
|
|
|
<p><br></p>
|
|
|
|
<table class="table_cod">
|
|
<tbody><tr>
|
|
<th>$ cd [directory where the newlib CVS is located]</th>
|
|
</tr>
|
|
<tr>
|
|
<th style="text-align: left;">$ joe configure.ac</th>
|
|
</tr>
|
|
</tbody></table>
|
|
|
|
|
|
|
|
<p>Localize o código abaixo:</p>
|
|
|
|
<pre><code> arm-*-elf* | strongarm-*-elf* | xscale-*-elf* | arm*-*-eabi* )<br> noconfigdirs="$noconfigdirs target-libffi target-qthreads"<br> libgloss_dir=arm<br> ;;<br><br> And add "target-libgloss" to the "noconfigdirs" variable:<br><br> arm-*-elf* | strongarm-*-elf* | xscale-*-elf* | arm*-*-eabi* )<br> noconfigdirs="$noconfigdirs target-libffi target-qthreads target-libgloss"<br> libgloss_dir=arm<br> ;;<br><br> Salve o arquivo e saia do editor<br> $ autoconf<br></code></pre>
|
|
|
|
|
|
<p>Em um dos sistemas onde executei a sequência acima, aconteceram erros, indicando que o arquivo autoconf 2.59 não tinha sido encontrado. Não entendi porque isto aconteceu. Como a vers;ão 2.59 já não é tão recente, e a compilação roda muito bem com a 2.61 (a vers;ão do autoconf no sistema que apresentou erro). Se isto acontece com você, execute inicialmente o autoconf --version para saber qual a versão corrente de seu autoconf, e então faça o seguinte:</p>
|
|
|
|
|
|
<p><br></p>
|
|
|
|
<table class="table_cod">
|
|
<tbody><tr>
|
|
<th></th>
|
|
</tr>
|
|
</tbody></table>
|
|
|
|
<pre><code>$ joe config/override.m4<br><br> Localize esta linha:<br><br> [m4_define([_GCC_AUTOCONF_VERSION], [2.59])])<br><br> E substitua 2.59 pela sua versão atual (no meu caso 2.61).<br> $ autoconf<br></code></pre>
|
|
|
|
|
|
<p>Agora estamos prontos para compilar a Newlib. Mas é necessário informar que a compilação será feita para Thumb2. Como já foi dito antes, eu não sou um especialista, e quando se trata de montar uma Newlib, escolhi uma solução rápida, porém não tão elegante para passar os parametros de compilação diretamente na linha de comando. Além disso, como eu prefiro que a minha biblioteca tenha o menor tamanho possível (em contraposição a maior performance possível) e manter no programa executável somente o necessário, acrescentei o parametro "-ffunction-seções-fdata-sections" para permitir que o linker possa executar dead code stripping:</p>
|
|
|
|
|
|
<p><br></p>
|
|
|
|
<table class="table_cod">
|
|
<tbody><tr align="left">
|
|
<th>$ mkdir build</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ cd build</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$
|
|
../configure --target=arm-elf --prefix=$TOOLPATH --enable-interwork
|
|
--disable-newlib-supplied-syscalls --with-gnu-ld --with-gnu-as
|
|
--disable-shared</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ make
|
|
CFLAGS_FOR_TARGET="-ffunction-sections -fdata-sections
|
|
-DPREFER_SIZE_OVER_SPEED -D__OPTIMIZE_SIZE__ -Os -fomit-frame-pointer
|
|
-mcpu=cortex-m3 -mthumb -D__thumb2__ -D__BUFSIZ__=256"
|
|
CCASFLAGS="-mcpu=cortex-m3 -mthumb -D__thumb2__"</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ sudo make install</th>
|
|
</tr>
|
|
</tbody></table>
|
|
|
|
|
|
|
|
<p>Algumas observações sobre os parâmetros usados na sequência acima:</p>
|
|
|
|
<ul>
|
|
<li><code>--disable-newlib-supplied-syscalls:</code> isso merece um capítulo a parte, porém n&ão agora. Apenas como esclarecimento, veja os exemplos <a href="http://openhardware.net/Embedded_ARM/NewLib_Stubs/">nesta página</a>.</li>
|
|
|
|
<li><code>-DPREFER_SIZE_OVER_SPEED -D__OPTIMIZE_SIZE__:</code> compile a Newlib otimizando o tamanho, e não a performance (utilizado para Newlib específica).</li>
|
|
|
|
<li><code>-mcpu=cortex-m3 -mthumb:</code> indica para a GCC que a compilação é para Cortex. É necessário utilizar os dois flags.</li>
|
|
|
|
<li><code>-D__thumb2__:</code> É necessário quando compilando a Newlib para o Cortex.</li>
|
|
|
|
<li><code>-Os -fomit-frame-pointer:</code> indica para a GCC para otimizar pelo tamanho, e não pela performance.</li>
|
|
|
|
<li><code>-D__BUFSIZ__=256:</code>
|
|
parâmetro específico navamente, este é o tamanho do buffer alocado por default para arquivos abertos via fopen(). O default é 1024, o qual acredito ser muito para eLua, logo utilizo aqui 256. Certamente, você poderá mudar este valor.</li>
|
|
|
|
</ul>
|
|
|
|
|
|
<h2>Passo 4: GCC completa</h2>
|
|
|
|
<p>Finalmente, no último passo deste nosso tutorial, completamos a montagem do GCC. Nesta etapa, várias bibliotecas de suporte do compilador foram montadas (sendo a mais importante a libgcc.a). Felizmente este é o passo mais simples para a montagem da NewLib, e como você se lembra, ainda queremos montar nosso compilador para a arquitetura Cortex:</p>
|
|
|
|
|
|
<p><br></p>
|
|
|
|
<table class="table_cod">
|
|
<tbody><tr align="left">
|
|
<th>$ cd gcc-4.3.1/build</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ make CFLAGS="-mcpu=cortex-m3 -mthumb" CXXFLAGS="-mcpu=cortex-m3 -mthumb" LIBCXXFLAGS="-mcpu=cortex-m3 -mthumb" all</th>
|
|
</tr>
|
|
<tr align="left">
|
|
<th>$ sudo make install</th>
|
|
</tr>
|
|
</tbody></table>
|
|
|
|
|
|
|
|
|
|
<h2>Tudo pronto!</h2>
|
|
<p>
|
|
UFA! Esse tutorial foi um pouco confuso, com um monte de flags e linhas de comando muito longas :) No entanto, você possui agora um GCC toolchain para Cortex funcionando, o que parece ser uma coisa bastante rara hoje, então aproveite com orgulho. Se você precisar de mais explicações, ou se as instruções acima não funcionaram para você, sinta-se a vontade para <a href="http://www.eluaproject.net/en/Contact">contactar-me</a>.</p><p></p><p></p>
|
|
$$FOOTER$$
|