Вопрос о связывании / загрузке и симуляторе

Я разработал симулятор MIPS I с помощью Verilator, который позволяет мне переносить код Verilog в C ++. Я пытаюсь запустить программу на C ++ на своем процессоре, но у меня возникли проблемы. Моя цель:

  1. написать тестовую программу на c ++
  2. скомпилируйте эту программу с помощью кросс-компилятора g ++ (mips-linux)
  3. возьмите сгенерированный файл ELF и разберите его с помощью objdump
  4. хранить весь дамп двоичного объекта в текстовом файле
  5. открыть текстовый файл в моем симуляторе
  6. запустить некоторые функции манипулирования текстом, чтобы изолировать HEX-часть дампа objdump
  7. загрузить весь шестнадцатеричный дамп эльфа в память моего процессора (карта памяти C ++, содержащая элементы, привязанные к их адресам в памяти, как определено файлом ELF.)
  8. запустите программу, установив счетчик программ и отпустив его до выхода из системного вызова программы.

Проблема будет в шагах 7 и 8. У меня очень элементарное представление о формате файла ELF. Насколько я могу судить (readelf можно использовать для вывода начальной точки программы), счетчик программы должен быть изначально установлен по адресу начала раздела .text. К сожалению, это не приводит к правильному запуску программы на моем процессоре.

Я проверил правильность выполнения программы на моем процессоре, написав ассемблерные программы, загрузив их в симуляторы сборки MIPS и проверив, инструкция за инструкцией, что регистровый файл и сгенерированная адресация совпадают. Я не понимаю, почему я не могу запустить даже программу helloworld, написав на C ++, скомпилировав и загрузив в мою «память»? Я не особо разбираюсь в этой области. Мне действительно нужна помощь, чтобы разобраться в этом.

Насколько я понимаю, .text и .data содержат все необходимое для запуска моей программы. Очевидно, это не так, потому что, когда я просматриваю раздел .text, моя программа не выполняется правильно. Есть ли что-то еще, что мне нужно сделать с файлом ELF перед его загрузкой в ​​память?


person Dan Snyder    schedule 12.07.2010    source источник
comment
Кроме того, я пробовал писать встроенную сборку и компиляцию, чтобы проверить свой процессор, но после компиляции я не могу найти свою программу (я просто повторяю addi $ 0x12ab ... снова и снова. Затем я ищу 0x12ab в шестнадцатеричном формате дамп файла elf.Таким образом мне не удалось найти свою программу в файле elf.   -  person Dan Snyder    schedule 12.07.2010
comment
Итак, глядя на симулятор ZVRBA, кажется, что файл ELF загружается в память очень похоже на то, как я это делаю. Я в основном вырезаю все символы из файла elf после его HEX-дампа и добавляю элемент в карту памяти, используя каждую шестнадцатеричную инструкцию / адрес данных в качестве ключа. Затем я получаю доступ с помощью адресного ключа. Таким образом, важными аспектами этого процесса являются загрузка всех элементов по их правильным адресам и установка программных, глобальных, стековых и фреймовых указателей в их требуемые местоположения. Поскольку это то, что я делаю, я думаю, что могу предположить, что мне следует сменить компилятор.   -  person Dan Snyder    schedule 13.07.2010


Ответы (3)


Я написал полный симулятор MIPS I, который может загружать двоичные файлы ELF. Вы можете получить исходный код здесь, возможно, вы получите ответы на свои вопросы. Есть также несколько демонстрационных программ. Ключевой момент - заставить компилятор генерировать автономный исполняемый файл, который не использует какую-либо библиотеку времени выполнения, даже библиотеку поддержки gcc.

person zvrba    schedule 12.07.2010
comment
Я также написал статью, в которой подробно описывается работа симулятора (включая некоторые аспекты ELF). Реферат находится здесь: computer.org/portal/web/ csdl / doi / 10.1109 / ARES.2010.47 Отправьте мне электронное письмо, чтобы я мог отправить вам статью (я не могу опубликовать ее в Интернете из-за проблем с авторским правом). - person zvrba; 13.07.2010
comment
Я думаю, что для меня было бы хорошей идеей создать свой собственный кросс-компилятор (вместо того, чтобы использовать предоставленный мне глючный компилятор). Вы знаете хороший ресурс, описывающий этот процесс? Специально для цели mipsel-elf gcc? - person Dan Snyder; 13.07.2010
comment
Я послал тебе письмо. Не уверен, что он прошел через вашу фильтрацию. - person Dan Snyder; 13.07.2010
comment
Хм, создать кросс-компилятор gcc не так уж и сложно. Я удалил виртуальную машину, на которой она находилась, поэтому я потерял параметры настройки :-( В более новых версиях gcc мне пришлось опустить код проверки стека и что-то, связанное с библиотекой mfpr, чтобы получить работающий кросс-компилятор. - person zvrba; 13.07.2010
comment
Хм, ну у меня сейчас 2 варианта. Либо исправьте мой текущий кросс-компилятор, либо создайте его самостоятельно. Я полагаю, что построить такой будет лучше, так как тогда я буду иметь представление о том, как он работает. (Моя степень бакалавра ECE не была слишком сосредоточена на концепциях связывания и загрузки). На данный момент у меня есть только компилятор, который, насколько я могу судить, не отвечает ни на ЛЮБЫЕ флаги. Есть ли простое решение для этого или лучше начать все сначала? - person Dan Snyder; 13.07.2010
comment
Не могли бы вы объяснить, почему исполняемый файл не должен использовать какие-либо библиотеки времени выполнения? Мой процессор может открывать, закрывать, читать и записывать файлы, если это необходимо, поэтому кажется, что любое использование библиотек во время выполнения не должно влиять на запуск программы или нет. В любом случае кажется, что я должен иметь доступ к своей программе в файле ELF, но когда я запускаю текстовый раздел с данными, доступными процессору, мой процессор не работает. Я проверил функциональность с золотым стандартом, поэтому я думаю, что что-то упустил ... - person Dan Snyder; 13.07.2010

Вот объяснение эльфа, которое мне понравилось, хотя похоже, что вы разбираетесь в эльфийских проблемах. Они также объясняют, как g ++ выводит файлы elf, поэтому он может помочь вам проанализировать ваш выходной файл (более подробная информация в тоже часть 1).

Надеюсь, что часть этой информации поможет.

person Adam Shiemke    schedule 12.07.2010
comment
Хорошее объяснение. Проще разобраться, чем статью в Википедии. Спасибо. - person Dan Snyder; 13.07.2010

zvrba, возможно, попал в точку, вы не можете / не должны вызывать функции библиотеки C, такие как printf, в своей программе.

Напишите простую программу на C, чтобы начать с:

const unsigned char hello[]="helloworld";

void notmain ( void )
{
   unsigned int ra;

   for(ra=0;hello[ra];ra++)
   {
       PUT32(0x1234,hello[ra]);
   }
}

и вызывать notmain из программ на ассемблере, которые вы написали и которые работают, и скомпоновать вместе.

PUT32 просто записывает некоторые данные по какому-то адресу, я обычно реализую их на ассемблере, ymmv.

Выберите какой-либо адрес, отличный от 0x1234, я предполагаю, что с вашей сим-средой вы можете наблюдать за доступом к местоположению адреса и наблюдать за персонажами. пока нет необходимости разговаривать с uart и декодировать последовательный порт в симуляции, когда вы можете смотреть байты на шине.

Файлы Elf действительно просто анализировать, если вы написали симулятор, чтение файла elf не составляет большого труда. Я не заморачиваюсь с библиотеками, они просто усложняют задачу. Если вы решили использовать структуры, то это несколько структур. Я могу предоставить вам код, который поможет вам начать, если хотите. Альтернативой является использование инструментов GNU для преобразования эльфа в двоичный файл (mips-any-objcopy file.elf -O binary file.bin). Если ваши .text и .data не близки друг к другу, программа objcopy создаст огромный файл с нулями для заполнения между двумя адресными пространствами. Для встраиваемых систем вы все равно хотите, чтобы в вашем разделе .data ничего не было, всегда инициализируйте переменные в программе не раньше времени, а таблицы только для чтения сделайте const, чтобы они находились в .text вместо .data

это проект для развлечения, работы или широкого общественного потребления? Мне может быть интересно использовать его когда-нибудь. Мне нравится концепция верилятора, но он либо ограничен, либо слишком жесток по отношению к стандарту Verilog, и так много Verilog там не будет работать под ним без работы, так что мне не удалось по-настоящему с ним поиграться.

удачи.

person old_timer    schedule 13.07.2010
comment
Основная причина, по которой я использовал карту на C ++ для представления моей памяти, заключается в том, что подразумеваются все пустые ячейки памяти. Если пара элемент / ключ была установлена, значит, в памяти есть элемент, если ничего не было выделено для определенного пространства, когда симулятор обращается к нему, возвращаемое значение по умолчанию равно 0. - person Dan Snyder; 13.07.2010
comment
Этот проект предназначен для исследований, но симулятор, который я конструирую, на самом деле не является частной собственностью. Это просто инструмент, который я буду использовать, чтобы опробовать различные суперпороговые архитектуры, чтобы компенсировать снижение производительности при падении напряжения питания почти до подпороговых уровней. Я буду счастлив отправить его вам, когда он будет запущен. - person Dan Snyder; 13.07.2010
comment
Самым большим преимуществом Verilator является то, что он очень быстрый. В основном это связано с тем, что он компилирует только синтезируемый verilog, который накладывает ограничение на вашу свободу кодирования, но поскольку вы также можете писать все непосредственно на C ++, есть приятное место, где можно использовать как Verilog, так и C ++. Кроме того, с основателем Verilator очень легко связаться, чтобы задать вопросы, поэтому его легко понять. - person Dan Snyder; 13.07.2010
comment
Кроме того, я использую objdump для дизассемблирования файла ELF. Раньше я использовал readelf, но кажется бессмысленным отдельно загружать каждый сегмент файл за файлом. Я просто запускаю obj dump, помещаю дизассемблированный вывод в текстовый файл, удаляю все, кроме адресации и шестнадцатеричных слов, и загружаю. Работает хорошо. Я попробую PUT32 и посмотрю, действительно ли я могу получить доступ к этому элементу в памяти. На данный момент мой компилятор заявляет, что PUT32 не заботится. Я посмотрю, что с ним. - person Dan Snyder; 13.07.2010
comment
PUT32 - это моя собственная функция, а не библиотека C, которую легко реализовать. Esp в вашей среде, которая похожа на то, где я живу, вы можете написать одну программу на C, обратите внимание, что PUT32 не находится в том же исходном файле, он реализован в отдельном файле. Вы можете реализовать PUT32 так, чтобы он доходил до симуляции верилятора через C ++ и попадал в оборудование, но программа работает на хосте, или скомпилировать программу для цели и использовать другую реализацию PUT32 для цели и запускать на цели. в симуляции - person old_timer; 15.07.2010
comment
позже, если / когда цель станет кремниевой, вы можете снова запустить встроенный с PUT32, реализованный для встроенного в эту цель, или реализовать PUT32, чтобы сделать вызов через операционную систему или драйвер ядра и запустить ту же исходную тестовую / прикладную программу. Требуется некоторая практика, чтобы получить независимую от операционной системы отдельную программу тестирования / приложения. В последнее время я добился большого успеха с этим подходом благодаря дизайну микросхемы и кремнию. - person old_timer; 15.07.2010
comment
У нас были профессиональные инструменты, это было тогда, когда количество общих лицензий было израсходовано, и мы сидели без дела, вертя пальцами, когда мы хотели, чтобы проект, и без того большой, строился под verilator или icarus verilog. Время на сборку нашего проекта с помощью verilator не того стоило, особенно, поскольку это был чужой код (и мы не смогли бы оправдать или сохранить эти изменения), нашей задачей было тестирование микросхемы и установка платы (программного обеспечения). - person old_timer; 15.07.2010