Библиотека elcore

Библиотека elcore для DSP предоставляет интерфейс для создания заданий, ожидания завершения экземпляра заданий, а также обработки системных вызовов DSP. Данная библиотека не реализует функционал для создания экземпляров заданий, а также настройки передачи аргументов для экземпляров заданий.

Библиотека elcore имеет следующие особенности:

Создание ELFParser

Класс ELFParser предназначен для разбора ELF-файла.

Примечание

Во время разбора ELF-файла проверяется, что стек (метка ___stack) находится после кучи (метка __end).

Класс не имеет публичных полей и методов. Объект класса ELFParser используется при создании объектов класса ElcoreELF и ElcoreJob.

class ElcoreParser
std::shared_ptr<ELFParser> CreateELFParser(const unsigned char *binary, size_t binary_size)

Описание аргументов функции CreateELFParser():

  • binary - указатель на буфер с данными ELF-файла;

  • binary_size - размер буфера.

Для создания объекта класса ELFParser используется функция CreateELFParser().

Создание ELF

Класс ElcoreELF является обёрткой над ELF-файлом и имеет следующие публичные методы:

typedef std::map<std::string, uint32_t> KernelMap
class ElcoreELF
const uint32_t GetEntryPoint() const

Возвращает виртуальный адрес точки входа.

const uint32_t GetBinarySize() const

Возвращает размер ELF-файла.

const uint8_t *GetBinaryData() const

Возвращает байтовый массив данных ELF-файла.

const KernelMap GetKernels() const

Возвращает список доступных кернелов в виде ассоциативного массива.

const uint32_t GetStackPointer()

Возвращает виртуальный адрес дна стека из ELF-файла.

const uint32_t GetKernelVirtualAddress(const char *kernel_name)

Возвращает виртуальный адрес кернела по его названию.

static std::shared_ptr<ElcoreELF> CreateELF(std::shared_ptr<ELFParser> elf_parser)

Создает экземпляр класса ElcoreELF. В качестве аргумента принимает указатель на объект класса ELFParser.

Для создания объекта класса ELF необходимо вызвать метод CreateELF().

Создание заданий

struct ElcoreSharedSection

Область памяти, размещаемая по фиксированному адресу в пространстве DSP.

int mapper_fd

Файловый дескриптор созданного mapper’а.

size_t size

Размер mapper’а.

uint64_t vaddr

Адрес, по которому должна располагаться секция в адресном пространстве DSP.

class ElcoreJob
const int GetFD() const

Возвращает файловый дескриптор задания

static std::shared_ptr<ElcoreJob> CreateElcoreJob(std::shared_ptr<ELFParser> elf_parser, std::shared_ptr<ElcoreELF> elf, int elcore_fd)

Создает экземпляр класса ElcoreJob. Описание аргументов метода CreateElcoreJob():

  • elf_parser — объект ELF-парсера, созданный с помощью CreateELFParser();

  • elf — объект ELF, созданный с помощью CreateELF();

  • elcore_fd — файловый дескриптор устройства, открытого с помощью open(2).

static std::shared_ptr<ElcoreJob> CreateElcoreJobWithSharedSections(std::shared_ptr<ELFParser> elf_parser, std::shared_ptr<ElcoreELF> elf, int elcore_fd, std::vector<ElcoreSharedSection> sections)

Создает экземпляр класса ElcoreJob. Описание аргументов метода CreateElcoreJobWithSharedSections():

  • elf_parser — объект ELF-парсера, созданный с помощью CreateELFParser();

  • elf — объект ELF, созданный с помощью CreateELF();

  • elcore_fd — файловый дескриптор устройства, открытого с помощью open(2);

  • sections — вектор элементов типа ElcoreSharedSection.

Метод позволяет на этапе создания задания отмапировать в адресное пространство DSP область памяти по фиксированным адресам по аналогии с ELF-секциями. Это позволяет в некоторых случаях снизить накладные расходы на создание экземпляров заданий.

Для создания нового задания необходимо вызвать метод CreateElcoreJob() или CreateElcoreJobWithSharedSections(). В случае успеха метод возвращает указатель на объект класса ElcoreJob.

Ожидание завершения экземпляра задания

int ElcoreJobInstancePoll(int job_instance_fd, int elcore_fd);

Описание аргументов функции ElcoreJobInstancePoll():

  • job_instance_fd — файловый дескриптор созданного экземпляра задания;

  • elcore_fd — файловый дескриптор открытого устройства /dev/elcoreX;

Функция ElcoreJobInstancePoll() обрабатывает события, приходящие от драйвера elcore50. Функция обрабатывает системные вызовы в случае прихода соответствующего события (см. Обработка системных вызовов DSP). В случае успешного завершения экземпляра задания функция ElcoreJobInstancePoll() возвращает 0, в противном случае — 1.

Обработка системных вызовов DSP

Библиотека elcore выполняет обработку системных вызовов DSP по сигналу из драйвера elcore50. Ниже представлена диаграмма последовательности, согласно которой осуществляется обработка системных вызовов.

box
    participant "Приложение DSP" as DSP
end box


box
    participant "Драйвер elcore50" as driver
end box

box
    participant "elcore" as elcore
end box

activate DSP
DSP -> driver: Исключение
deactivate DSP
activate driver
driver -> driver: Обработка аргументов системного вызова,\nЗаполнение структуры сообщения
driver -> elcore: Отправка события,\nОжидание окончания обработки
deactivate driver
activate elcore
elcore -> driver: Чтение сообщения из файла задания
activate driver
elcore <- driver: Копирование сообщения
deactivate driver
elcore -> elcore: Чтение сообщения,\nОбработка системного вызова,\nЗапись кода возрата в сообщение
elcore -> driver: Запись сообщение в файл задания
activate driver
elcore <- driver: Подтверждение записи
deactivate elcore
driver -> DSP: Запуск DSP
deactivate driver
activate DSP

Обработка системных вызовов DSP в elcore.

Форматирование вывода DSP

Библиотека elcore позволяет при каждом вызове write(2) со стороны DSP перед началом выводимой строки дополнительно печатать текущее время и номер ядра, на котором был вызван данный системный вызов. Управление данными опциями осуществляется с помощью переменных окружений ELCORE_WRITE_TIMESTAMP и ELCORE_WRITE_CORENUM соответственно, которые необходимо устанавливать перед запуском приложения, связанного с библиотекой elcore.

Допустимые значения переменной окружения ELCORE_WRITE_TIMESTAMP:

  • 0 — вывод времени не включен;

  • 1 — вывод времени включен.

Случай, когда переменная окружения ELCORE_WRITE_TIMESTAMP не определена, аналогичен случаю, когда переменная окружения равна 0.

Допустимые значения переменной окружения ELCORE_WRITE_CORENUM:

  • 0 — вывод номера ядра не включен;

  • 1 — вывод ядра включен.

Случай, когда переменная окружения ELCORE_WRITE_CORENUM не определена, аналогичен случаю, когда переменная окружения равна 0.

Использование данных опций может быть полезно при запуске программ на нескольких DSP, активно использующих write(2).

Управление страницами DSP

Библиотека elcore позволяет управлять размером страниц DSP. Управление осуществляется переменной окружения ELCORE_HUGEPAGE_ENABLE, которую необходимо устанавливать перед запуском приложения, связанного с библиотекой elcore. Допустимые значения переменной окружения ELCORE_HUGEPAGE_ENABLE:

  • 0 — используются только страницы размером 4К;

  • 1 — используются страницы размером 4К и 2М. Для того, чтобы драйвер гарантированно использовал 2М страницы необходимо, чтобы память была физически выровнена на 2М и состояла из фрагментированных частей, размер которых кратен 2М. Для ELF-секций управление выравниваний осуществляется переменной окружений ELCORE_HUGEPAGE_SECTIONS, см. Управление выравниванием ELF-секций. Для остальных буферов пользователь должен сам обеспечивать физическое выравнивание, например, используя posix_memalign(3).

Случай, когда переменная окружения ELCORE_HUGEPAGE_ENABLE не определена, аналогичен случаю, когда переменная окружения равна 1.

Управление выравниванием ELF-секций

Библиотека elcore позволяет управлять выравниванием ELF-секций DSP. Управление осуществляется переменной окружения ELCORE_HUGEPAGE_SECTIONS, которую необходимо устанавливать перед запуском приложения, связанного с библиотекой elcore. Допустимые значения переменной окружения ELCORE_HUGEPAGE_SECTIONS:

  • 0 — выравнивание осуществляется по размеру CPU-страницы, возвращаемой getpagesize(2);

  • 1 — выравнивание осуществляется по размеру большой CPU-страницы, получаемой из файла /proc/meminfo.

Случай, когда переменная окружения ELCORE_HUGEPAGE_SECTIONS не определена, аналогичен случаю, когда переменная окружения равна 1.