Configurar o Linux na placa de desenvolvimento como o SocKit com um ARM Cortex A9 de núcleo duplo não é ciência do foguete. Um fabricante da placa suporta a imagem pronta para uso, apropriada para instalação no cartão SD ou outra mídia. Mas e se você deseja tocar nu metal, se aproximando de uma velocidade impressionante de código não restringida por um núcleo de sistema operacional? Bem, é possível, mas não tão fácil e óbvio. Neste breve ensaio, darei instruções passo a passo sobre como criar e executar seu primeiro aplicativo bare-metal no Cyclone V SoC, que usa o núcleo do ARM Cortex A9 do subsistema HPS do SoC.
Você precisa ter a placa de desenvolvimento com o Intel (Altera) Cyclone V SoC. Eu usei a placa SoCKit:

Eu tenho feito todas as coisas descritas neste artigo no Debian Jessie. Você pode usar outro sistema Linux ou Windows com as alterações correspondentes.
E você precisa do DS-5 IDE. E, infelizmente, a edição gratuita não permite compilar um código bare-metal. Você precisa da versão completa.
1. Preparação
Apesar de você ter a versão completa do DS-5, você precisa instalar o DS-5 Altera Edition gratuito. Ambas as versões devem ser instaladas no modo
sudo , em diretórios diferentes, por exemplo:
/ home / user / intelFPGA para DS-5 Altera Edition e
/ home / user / DS-5 para a versão completa do DS-5. Você deve inserir os caminhos manualmente durante o processo de instalação.
2. Execução do IDE
2.1 Primeiro, execute o script
/home/user/intelFPGA/16.1/embedded/embedded_command_shell.sh , altere um diretório para
/ home / user / DS-5 / bin e execute o IDE:
$ ./eclipse &
O script configurou variáveis de ambiente. Para definir as variáveis quando um sistema é iniciado, você deve adicionar a seguinte linha ao arquivo
/home/user/.profile :
QUARTUS_ROOTDIR=/home/user/intelFPGA/16.1/qprogrammer export PATH=$PATH:/usr/local/gcc-arm-none-eabi-5_4-2016q3/bin/:/home/user/intelFPGA/16.1/embedded/host_tools/mentor/gnu/arm/baremetal/bin/
Se necessário, adicione uma linha semelhante para as variáveis necessárias para a lontra, como QSYS_ROOTDIR.
Além disso, você precisa instalar e executar o Quartus Prime. Vamos considerar que o diretório de instalação do Quartus é
/home/user/intelFPGA/16.1/quartus/ .
Execute o Quartus Prime, localizado em
/home/user/intelFPGA/16.1/quartus/bin/quartus , e é o utilitário do programador JTAG, localizado em
/home/user/intelFPGA/16.1/qprogrammer/bin/quartus_pgmw .
3. Conectando o SoCkit
3.1 Conecte a placa SoCkit a um computador. Conecte os cabos microUSB às portas da placa, denominadas "USB Blaster (JTAG)" e "USB to UART".
3.2 Ligue a placa e digite:
$ ls /dev/bus/usb/001 001 002 003
O último número (003) é uma interface JTAG. Defina as permissões para escrever:
$ sudo chmod 666 /dev/bus/usb/001/003
Você precisa fazer isso toda vez que liga o quadro.
3.3 Configurações do terminal TTY
Você pode usar este comando:
screen /dev/ttyUSB0 115200
4. Construindo o pré-carregador (u-boot-spl)
4.1 Faça o download do arquivo
sockit_ghrd_16.0.tar.gz e descompacte-o. Por exemplo, descompacte-o em
/ home / user / ghrd-16 / sockit_ghrd .
4.2 Execute o Quartus Prime e abra o arquivo
/home/user/ghrd-16/sockit_ghrd/soc_system.qpf.4.3 Execute o Qsys (Ferramentas / Qsys). Abra o
arquivo /home/user/ghrd-16/sockit_ghrd/soc_system.qsys. Gere / gere HDL e saia do Qsys.
4.4 Execute o Assembler no Quartus Prime.
4.5 Execute o editor bsp:
/home/user/intelFPGA/16.1/embedded/host_tools/altera/preloadergen/bsp-editor . Crie um novo projeto: Arquivo / Novo HPS BSP. No campo "
Diretório de configuração do pré- carregador ",
grave "
/ home / user / ghrd-16 / sockit_ghrd / hps_isw_handoff / soc_system_hps_0. "
4.6 Configure o Preloader. Vá para a guia Avançado. Desative o
Watchdog_enable . Se você deseja ver as mensagens de depuração por meio do JTAG, é possível ativar o
Semihosting . Depois disso, pressione
Gerar e saia.
4.7 É possível alterar a mensagem de inicialização. Por exemplo, no arquivo de software / spl_bsp / uboot-socfpga / board / altera / socfpga / socfpga_cyclone5.c, altere a sequência "
PLACA: Placa Altera SOCFPGA Cyclone V " em outra:
int checkboard(void) { #ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET puts("BOARD : Altera VTDEV5XS1 Virtual Board\n"); #else
4.8 A variável de ambiente SOCEDS_DEST_ROOT deve ser configurada como
/home/user/intelFPGA/16.1/embedded :
export SOCEDS_DEST_ROOT=/home/user/intelFPGA/16.1/embedded
Agora vá para o diretório
/home/user/ghrd-16/sockit_ghrd/software/spl_bsp
e
faça . Make pode falhar com o erro "make: mkpimage: Command not found", mas deve criar o arquivo
u-boot-spl no caminho
/ home / user / ghrd-16 / sockit_ghrd / software / spl_bsp / uboot-socfpga / spl / u-boot-spl .
4.9 Testando o pré-carregador
4.9.1 Você não precisa de uma imagem FPGA (que possui uma extensão ".sof") para executar o pré-carregador. Execute o DS-5 e abra "Configurações de execução / depuração".
4.9.2 No campo
Conexão deve ser configurada a opção
CV SoCKit 1-1 . Caso contrário, pressione o botão "Procurar" e defina esta opção. Se um erro aparecer, faça 3.1-3.2.
4.9.3 Defina o arquivo
u-boot-spl na guia Arquivos, no campo "Aplicativo no host para download": / home / user / ghrd-16 / sockit_ghrd / software / spl_bsp / uboot-socfpga / spl / u-boot-spl . Defina a bandeira "Carregar símbolos". O campo "Arquivos" permanece vazio.
4.9.4 Desative um script de depuração iniciando na guia Depuração.
4.9.5 Execute o utilitário do terminal (por exemplo,
tela ) e pressione o botão "Debug". O pré-carregador é carregado na memória e um depurador está pronto para iniciar. Pressione o botão "Continuar" (ou F8) e veja a mensagem:
U-Boot SPL 2013.01.01 (Jun 24 2017 - 19:49:33) ARM preloader build by 32-bit.me CLOCK: EOSC1 clock 25000 KHz CLOCK: EOSC2 clock 25000 KHz CLOCK: F2S_SDR_REF clock 0 KHz CLOCK: F2S_PER_REF clock 0 KHz CLOCK: MPU clock 925 MHz CLOCK: DDR clock 400 MHz CLOCK: UART clock 100000 KHz CLOCK: MMC clock 50000 KHz CLOCK: QSPI clock 370000 KHz RESET: COLD SDRAM: Initializing MMR registers SDRAM: Calibrating PHY SEQ.C: Preparing to start memory calibration SEQ.C: CALIBRATION PASSED SDRAM: 1024 MiB ALTERA DWMMC: 0 Card did not respond to voltage select! spl: mmc init failed: err - -17
Isso significa que o pré-carregador foi iniciado com sucesso.
4.9.6 Após a sessão de depuração, pressione os botões "Desconectar do destino" e "Remover conexão".
5. Escreva um Hello World para o modo bare-metal.
5.1 Faça o download do projeto ArrowSocKit_BareMetal_GNU.zip. Defina as variáveis de ambiente como em 2.1., Execute o DS-5, importe o projeto do archive (
Arquivo / Importar / Projeto Existente para a Área de Trabalho ,
Selecionar arquivo de arquivo ). O projeto descompactado aparece no diretório / home / user / DS-5-Workspace / BareMetalBoot-GNU.
5.2 Você pode tentar compilar o projeto com o
make
, mas ele ainda não pode ser compilado. Para criar o projeto, faça o seguinte.
5.3 Copie o diretório
/home/user/intelFPGA/16.1/embedded/ip/altera/hps/altera_hps/hwlib em
/ home / user / DS-5-Workspace / . Aqui estão as pastas
src e
include , e em cada uma delas há os diretórios
soc_cv_av e
soc_a10 . Você pode remover os diretórios chamados
soc_a10 . Em seguida, copie os arquivos libcs3.a, libcs3arm.a, libcs3unhosted.a de
/home/user/intelFPGA/16.1/embedded/host_tools/mentor/gnu/arm/baremetal/arm-altera-eabi/lib. para o diretório do projeto (/ home / user / DS-5-Workspace / BareMetalBoot-GNU). Copie o arquivo arm-names.inc de
/home/user/intelFPGA/16.1/embedded/host_tools/mentor/gnu/arm/baremetal/arm-altera-eabi/lib/cortex-a9/ para
/ home / user / DS- 5-Espaço de trabalho / BareMetalBoot-GNU / .
5.4 No Makefile, altere "CROSS_COMPILE: = arm-none-eabi-" para "CROSS_COMPILE: = arm-altera-eabi-". Altere também o caminho para
hlib
: HWLIBS_ROOT: = / home / user / DS-5-Workspace / hwlib
5.5 Agora execute
make
. e leia todas as mensagens de erro. Se o
make
não conseguir encontrar algum símbolo, você deve encontrá-lo nos diretórios hwlib / src / soc_cv_av e hwlib / include / soc_cv_av e faça uma cópia em hwlib / src e hwlib / include correspondentemente. Depois de encontrar todos os fules, faça falhas com o erro "mkimage: not found", mas isso não é importante, porque precisamos apenas do arquivo
test.axf .
5.6 Executando um aplicativo
5.6.1 Para executar um aplicativo, é necessário carregar uma imagem FPGA (arquivo .sof) gerada quando construímos o pré-carregador. Execute o programador como fizemos no 2.1. Deve haver o texto "CV SoCKit [1-1]" à direita da parte inferior "Configuração do hardware". Se não houver, defina a permissão de gravação para a porta JTAG (veja acima) e clique no botão Configuração do hardware.
5.6.2 Clique em "Detecção automática" e selecione uma opção arbitrária em uma lista. Você vê uma configuração de dois dispositivos: um é o que você selecionou (por exemplo, 5CSEBA6) e o segundo é SOCVHPS. Remova o primeiro dispositivo: selecione-o e pressione Excluir. Pressione “Adicionar arquivo” e abra o arquivo de imagem (/home/user/ghrd-16/sockit_ghrd/output_files/soc_system.sof). Um novo dispositivo apareceu à direita do SOCVHPS. Mova-o com o mouse para o primeiro lugar na cadeia. Depois disso, pressione Iniciar e faça o upload da imagem.
5.6.3 No DS-5, abra "Configuração de depuração" na guia "Arquivos". Defina o arquivo
u-boot-spl na linha "Aplicativo no host para download". Remova uma marca em "Carregar símbolos". Defina o arquivo "test.axf" na linha "Arquivos". Na guia Depurador, verifique o "Executar script de depuração de inicialização de destino" e defina o arquivo de script "debug-unhosted.ds", localizado no diretório do projeto. No arquivo, edite o caminho para o pré-carregador:
# Load the SPL preloader into memory.
#
loadfile "/home/user/ghrd-16/sockit_ghrd/software/spl_bsp/uboot-socfpga/spl/u-boot-spl" 0x0
Execute a
tela do terminal TTY e pressione Debug. Em seguida, o pré-carregador iniciará, um aplicativo será carregado e um depurador será definido no ponto de início do programa. Pressione o botão "Continuar". Na janela de um terminal, você verá a saída do pré-carregador, como foi mostrado acima, e o seguinte:
Disabled interrupts because preloader enabled ECC interrupts. Global Timer value at startup = 0x000000005A10B609 CPU frequency is 925000000 hertz. DDR frequency is 400000000 hertz. MPU peripheral frequency is 231250000 hertz. MB ZERO remapped to SDRAM. L3 interconnect remapped as inaccessible and SDRAM. Interrupt controller system API initialized. MMU initialized and enabled. L1 and L2 cache system initialized and enabled. GIC interrupts enabled. PIT started. PIT interrupt registered and enabled. GPIOs initialized. UART0 initialized. L3 interconnect remapped as accessible and SDRAM. Bridges initialized. Boot completed. Boot milestones: New buffer !ESTONE : GT TICKCOUNT : INCREMENTAL : CUMULATIVE initial GT : 0x000000005A10B609 : 0.000us : 0.000us frequency capture : 0x000000005A119D58 : 256.065us : 256.065us initial remapping : 0x000000005A11C936 : 48.562us : 304.627us interrupt sys init : 0x000000005A139FED : 521.094us : 825.721us mmu init : 0x000000005A62D774 : 22449.985us : 23275.706us cache init : 0x000000005A65CF96 : 841.488us : 24117.194us interrupts enabled : 0x000000005A65D0D7 : 1.388us : 24118.582us pit start : 0x000000005A65DD2E : 13.661us : 24132.242us pit enabled : 0x000000005A65DF67 : 2.461us : 24134.703us gpio init : 0x000000005A65FC12 : 31.736us : 24166.439us uart0 init : 0x000000005A66084D : 13.539us : 24179.978us fpga config : 0x0000000000000000 : 79769704095969360.000us : 79769704095993552.000us last remapping : 0x000000005A660981 : 6558428.303us : 24181.310us bridge init : 0x000000005A6611B6 : 9.085us : 24190.396us complete : 0x000000005A661222 : 0.467us : 24190.863us Hello world, 32bit-me!
Parabéns! Você acabou de executar seu primeiro aplicativo bare-metal no núcleo Cortex-A9.