МАРСОХОД

Open Source Hardware Project

ARM System-on-Chip

Компиляция hello-world для Amber ARM SoC

Итак, для нашей системы на кристалле нужна программа, которая бы стартовала из bootrom. Естественно, нужно начинать с чего-то самого простого. В папке нашего проекта Amber есть такая программа sw/hello-world. Я так понимаю при включении процессора он должен выводить в консоль, в последовательный порт вот это сообщение “Hello, World!”.

Попробуем!

Я не стал вносить изменения в эту программу. Вместо этого я создал копию этой папки sw/hello-world-my и уже здесь буду делать изменения.

Собственно все изменения можно отслеживать в GitHub https://github.com/marsohod4you/Amber-Marsohod2 , где я работаю над проектом.

Компилировать программу очень легко. Компилятор Sourcery CodeBench у нас уже установлен. После запуска терминала в Linux нужно один раз набрать в консоли


source sw/init
чтобы установить нужные переменные окружения. Потом для компиляции:

make
После компиляции, если нет ошибок появляются много новых объектных и текстовых файлов *.o, *.elf, *.map, *.mem и другие. На самом деле меня интересует файл hello-world.mem в нем в текстовом виде описано содержимое памяти bootrom.

Выглядит этот файл как-то вот так:

// Section name .text
//  Type SHT_PROGBITS, Size 0xddc, Start address 0x00000000, File offset 0x8000, boffset 0
// Section name .text.startup
//  Type SHT_PROGBITS, Size 0x24, Start address 0x00000ddc, File offset 0x8ddc, boffset 0
// Section name .rodata.str1.4
//  Type SHT_PROGBITS, Size 0x24, Start address 0x00000e00, File offset 0x8e00, boffset 0
// Section name .rodata.str1.1
//  Type SHT_PROGBITS, Size 0x7, Start address 0x00000e24, File offset 0x8e24, boffset 0
// Section name .bss
//  Type SHT_NOBITS, Size 0x4, Start address 0x00000e2b, File offset 0x8e2b, boffset 3
// .bss Dump Zeros
// Section name .ARM.attributes
//  Type ???, Size 0x2b, Start address 0x00000000, File offset 0x8e2b, boffset 3
// Section name .shstrtab
//  Type SHT_STRTAB, Size 0x62, Start address 0x00000000, File offset 0x8e56, boffset 2
// Section name .symtab
//  Type SHT_SYMTAB, Size 0x3a0, Start address 0x00000000, File offset 0x9048, boffset 0
// Section name .strtab
//  Type SHT_STRTAB, Size 0x167, Start address 0x00000000, File offset 0x93e8, boffset 0
@00000000 e3a00000
@00000004 e13ff000
@00000008 e3e00000
@0000000c ee030f10
@00000010 e3a00001
@00000014 ee020f10
@00000018 e59fd004
@0000001c eb00036e
@00000020 ea000110

Тут есть проблемка – такой файл нельзя использовать в проектах Altera Quartus II. В среде Quartus II в ПЛИС можно создавать блоки статической памяти и задавать начальное содержимое памяти с помощью так называемых Memory Initialization File, MIF.

Поэтому я написал маленькую утилитку для преобразования MEM файла в MIF файл. Она находится в проекте в папке sw/tools/mem2mif. Ее то же нужно сперва скомпилировать: зайдите в sw/tools и наберите make. Теперь, находясь в папке hello-world можно преобразовать полученный mem файл в mif файл командой в консоли

../tools/mem2mif hello-world.mem > hello-world.mif

Теперь расскажу о сделанных мною изменениях:

Первое. Почему-то, непонятно почему в файле sections.lds начальный адрес программы был установлен в 0x8000

ENTRY(main)

SECTIONS {

        . = 0x008000;
                       
    .text   : {  start*(.text); *(.text); }
       
    .data : { *(.data); }

Это очень странно, так как в комментарии выше написано в этом же section.lds:

//  Description                                                 //
//  Sections linker file for the hello-world application.       //
//  Note that the address map starts at 0x0 because this is     //
//  a stand-alone application, not using the boot-loader.       //
//  As such, it would need to be put into the FPGA during       //
//  synthesis.

Я честно сказать не знаю, что такое этот файл section.lds, но обратил сюда внимание потому, что при компиляции в файле mem начальные адреса с нуля по 0x8000 содержали нули. Ну не может такого быть. Дело в том, что память в ПЛИС это довольно ограниченный ресурс. Не могу подумать, чтобы она так расточительно использовалась. В общем поставил базовый адрес ноль. Чисто из здравого смысла.

Второе изменение, которое я сделал – в файле start.S перенес адрес указателя стека. У них в системе была память DDR, а у нас пока нет внешней памяти. Я поставил стек под верх памяти bootrom – 0х1FF0 там пока похоже есть немного пустого места.

Ну и третье изменение, которое я сделал – исправил само сообщение “Hello, World!” на “ “Marsohod2: Hello, World!” ну это так – косметическое исправление.

Теперь компилирую и преобразовываю в MIF файл:

make
../tools/mem2mif hello-world.mem > hello-world.mif

Получается файл hello-world.mif который нам нужно как-то подключить к bootrom проекта. Как это сделать?

Если в Altera Quartus II выполнить команду меню Processing => Start => Analisis & Elaboration, то после этого в Project Navigator можно посмотреть иерархию проекта. Там есть компонент bootmem и видно компоненты из которых он простроен.

Altera Quartus II Project Navigator

Самый низкий в иерархии – sram_2048_32_byte_en:sram, он изображен с магической палочкой. Кликаем на него – открывается Wizard (которым я этот компонент и создавал в начале).

Altera Quartus II Wizard

На странице 4 wizarda можно задать начальное содержимое памяти после включения ПЛИС. Там я задаю hello-world.mif.

Altera Quartus II Wizard

Ну вот в общем, кажется все готово.
Компилирую проект. Запускаю программатор, еще запускаю программу терминала PUTTY и в ней открываю мой COM9, ожидая получить в консоли сообщение Marsohod2: Hello, World!

Загружаю проект в ПЛИС из программатора, и вот (там та-ра-рам!!!!) – ничего не происходит...

Ну, как бы так бывает. Что-то еще не учтено. Получается как в лучших детективных романах, пока только завязка сюжета Smile

На самом деле есть еще ряд непонятных моментов. Например, я не знаю, на какой скорости передает Amber данные в COM-порт. Хотя вариантов не так и много – попробовав открывать порт с разной скоростью приема я все больше убеждаюсь, что проект не работает.

Буду чинить.

Компиляция hello-world для Amber ARM SoC

 

Итак, для нашей системы на кристалле нужна программа, которая бы стартовала из bootrom. Естественно, нужно начинать с чего-то самого простого.

В папке нашего проекта Amber есть такая программа sw/hello-world.

Я так понимаю при включении процессора он должен выводить в консоль, в последовательный порт вот это сообщение “Hello, World!”.

 

Я не стал вносить изменения в эту программу. Вместо этого я создал копию этой папки sw/hello-world-my и уже здесь буду делать изменения.

 

Собственно все изменения можно отслеживать в GitHub https://github.com/marsohod4you/Amber-Marsohod2 , где я работаю над проектом.

 

Компилировать программу очень легко. Компилятор Sourcery CodeBench у нас уже установлен. После запуска терминала в Linux нужно один раз набрать в консоли

 

source sw/init

 

чтобы установить нужные переменные окружения. Потом для компиляции:

 

make

 

После компиляции, если нет ошибок появляются много новых объектных и текстовых файлов *.o, *.elf, *.map, *.mem и другие. На самом деле меня интересует файл hello-world.mem в нем в текстовом виде описано содержимое памяти bootrom. 

 

Выглядит этот файл как-то вот так:

 

// Section name .text

//  Type SHT_PROGBITS, Size 0xddc, Start address 0x00000000, File offset 0x8000, boffset 0

// Section name .text.startup

//  Type SHT_PROGBITS, Size 0x24, Start address 0x00000ddc, File offset 0x8ddc, boffset 0

// Section name .rodata.str1.4

//  Type SHT_PROGBITS, Size 0x24, Start address 0x00000e00, File offset 0x8e00, boffset 0

// Section name .rodata.str1.1

//  Type SHT_PROGBITS, Size 0x7, Start address 0x00000e24, File offset 0x8e24, boffset 0

// Section name .bss

//  Type SHT_NOBITS, Size 0x4, Start address 0x00000e2b, File offset 0x8e2b, boffset 3

// .bss Dump Zeros

// Section name .ARM.attributes

//  Type ???, Size 0x2b, Start address 0x00000000, File offset 0x8e2b, boffset 3

// Section name .shstrtab

//  Type SHT_STRTAB, Size 0x62, Start address 0x00000000, File offset 0x8e56, boffset 2

// Section name .symtab

//  Type SHT_SYMTAB, Size 0x3a0, Start address 0x00000000, File offset 0x9048, boffset 0

// Section name .strtab

//  Type SHT_STRTAB, Size 0x167, Start address 0x00000000, File offset 0x93e8, boffset 0

@00000000 e3a00000

@00000004 e13ff000

@00000008 e3e00000

@0000000c ee030f10

@00000010 e3a00001

@00000014 ee020f10

@00000018 e59fd004

@0000001c eb00036e

@00000020 ea000110

 

Тут есть проблемка – такой файл нельзя использовать в проектах Altera Quartus II. В среде Quartus II в ПЛИС можно создавать блоки статической памяти и задавать начальное содержимое памяти с помощью так называемых Memory Initialization File, MIF.

 

Поэтому я написал маленькую утилитку для преобразования MEM файла в MIF файл. Она находится в sw/tools/mem2mif. Ее то же нужно сперва скомпилировать: зайдите в sw/tools и наберите make. Теперь, находясь в папке hello-world можно преобразовать полученный mem файл в mif файл командой в консоли

 

../tools/mem2mif hello-world.mem > hello-world.mif

 

Теперь расскажу о сделанных мною изменениях:

 

Первое. Почему-то, непонятно почему в файле sections.lds начальный адрес программы был установлен в 0x8000

 

ENTRY(main)
 
 
SECTIONS {
 
        . = 0x008000;
                        
        .text   : {  start*(.text); *(.text); }
        
        .data : { *(.data); }

 

Это очень странно, так как в комментарии выше написано

 

//  Description                                                 //
//  Sections linker file for the hello-world application.       //
//  Note that the address map starts at 0x0 because this is     //
//  a stand-alone application, not using the boot-loader.       //
//  As such, it would need to be put into the FPGA during       //
//  synthesis.

 

Я обратил сюда внимание потому, что при компиляции в файле mem начальные адреса с нуля по 0x8000 содержали нули. Ну не может такого быть. Дело в том, что память в ПЛИС это довольно ограниченный ресурс. Не могу подумать, чтобы она так расточительно использовалась. В общем поставил базовый адрес ноль.

 

Второе изменение, которое я сделал – в файле start.S перенес адрес указателя стека. У них в системе была память DDR, а у нас пока нет внешней памяти. Я поставил стек под верх памяти bootrom – там пока похоже есть немного пустого места.

 

Ну и третье изменение, которое я сделал – исправил само сообщение “Hello, World!” на “ “Marsohod2: Hello, World!” ну это так – косметическое исправление.

 

Теперь компилирую и преобразовываю в MIF файл:

 

Make

../tools/mem2mif hello-world.mem > hello-world.mif

 

Получается файл hello-world.mif который нам нужно как-то подключить к bootrom проекта. Как это сделать?

 

Если в Altera Quartus II выполнить команду меню Processing => Start => Analisis & Elaboration, то после этого в Project Navigator можно посмотреть иерархию проекта. Там есть компонент bootmem и видно компоненты из которых он простроен. Самый низкий в иерархии – sram_2048_32_byte_en:sram, он изображен с магической палочкой. Кликаем на него – открывается Wizard (которым я этот компонент и создавал в начале).

 

На странице 4 wizarda можно задать начальное содержимое памяти после включения ПЛИС. Там я задаю hello-world.mif.

 

Ну вот в общем, кажется все готово.

Компилирую проект. Запускаю программатор, еще запускаю программу терминала PUTTY и в ней открываю мой COM9, ожидая получить в консоли сообщение Marsohod2: Hello, World! 

 

Загружаю проект в ПЛИС из программатора, и вот (там та-ра-рам!!!!) – ничего не происходит...

 

Ну, как бы так бывает. Что-то еще не учтено. Получается как в лучших детективных романах, пока только завязка сюжета J

 

На самом деле есть еще ряд непонятных моментов. Например, я не знаю, на какой скорости передает Amber данные в COM-порт. Хотя вариантов не так и много – попробовав открывать порт с разной скоростью приема я все больше убеждаюсь, что проект не работает.

 

Буду чинить.

Комментарии  

0 #7 pkuz 04.08.2014 14:21
:-) физический адрес в памяти 0х00
В архитектуре процессора адрес будет смещен,тк мы загружаем бут и образ системы с адреса 0х8000
Архитектура отображает ядро и элементы и порты как адресное пространство,об ъемом до 4гбайт
0 #6 zrewa 24.09.2012 14:57
Цитирую nckm:
Цитирую zrewa:
Возможно адрес 0x8000 - адрес reset вектора. То есть при старте на адресной шине стоит алрес 0x8000 там лежит программа биоса, а затем long jump to main memory.

По крайней мере, когда я разбирался с zet x86 так и было

там в проекте рядом программой hello-world есть еще программа boot-loader - так вот в ней начальный адрес ноль


Ну и в симуляции я смотрю начальный адрес 0. Может print не на uart печатает. А может варнинги в квартусе посмотреть :-) На форуме у вас кто-то выкладывал проект.
+1 #5 nckm 24.09.2012 10:07
Цитирую zrewa:
Возможно адрес 0x8000 - адрес reset вектора. То есть при старте на адресной шине стоит алрес 0x8000 там лежит программа биоса, а затем long jump to main memory.

По крайней мере, когда я разбирался с zet x86 так и было

там в проекте рядом программой hello-world есть еще программа boot-loader - так вот в ней начальный адрес ноль
+1 #4 nckm 24.09.2012 10:05
Цитирую caro:
В файле system_config_defines.v задана
скорость работы UART:
`define AMBER_UART_BAUD 921600
Наверное следует ее изменить на 115200

ну можно и открывать COM порт с этой скоростью, так что особо менять не нужно
+1 #3 caro 22.09.2012 22:30
В файле system_config_d efines.v задана
скорость работы UART:
`define AMBER_UART_BAUD 921600
Наверное следует ее изменить на 115200
+2 #2 zrewa 22.09.2012 09:54
Возможно адрес 0x8000 - адрес reset вектора. То есть при старте на адресной шине стоит алрес 0x8000 там лежит программа биоса, а затем long jump to main memory.

По крайней мере, когда я разбирался с zet x86 так и было
+2 #1 Angel007 22.09.2012 09:05
Браво! Ждемс продолжения! :-)

Добавить комментарий


Защитный код
Обновить


GitHub YouTube Twitter
Вы здесь: Начало Проекты Проект Марсоход2 Amber ARM SoC Компиляция hello-world для Amber ARM SoC