Подтвердить что ты не робот

Память кода повторного использования для данных

У меня есть C-код, который работает в системе с ограниченным объемом памяти. Исполнение кода имеет в основном две фазы, фазу запуска и основную фазу. Фаза запуска состоит из кода, который генерирует некоторые параметры, используемые основной фазой. Во время основной фазы генерируются данные.

Поскольку фаза запуска запускается только один раз, я хотел бы повторно использовать пространство памяти, используемое кодом запуска для хранения данных в основной фазе.

Я проверил один из способов справиться с этим:

  • Пользовательский компоновщик script размещения кода и данных, связанных с фазой запуска в разделе .startup. Этот раздел размещен по тому же адресу, что и .bss, который является секцией bss, используемой основной фазой.
    Код запуска вызывает точку входа для этапа запуска и когда он возвращается, прежде чем вызывать main в основной фазе, он очищает раздел .bss.
    Команды Xrossref используются в компоновщике script, чтобы помочь получить код и данные в нужном месте.

Это работает, но у него есть свои причуды. Чтобы получить код запуска и данные в разделе .startup, я должен перечислить их с именами разделов ввода, данными gcc во время компиляции.

Теперь я хотел бы включить lto (оптимизация времени ссылки), и это нарушает вышеуказанный метод, поскольку имена входов секции изменены.

Думая о тестировании нового подхода:

  • Создайте код запуска и основной код как две отдельные программы. Каждая программа создается и оптимизируется отдельно и объединяется в один загрузочный образ.
    Преимущество заключается в том, что нет никакого риска, что основной код вызывает функцию, случайно помещенную в секцию автозагрузки (которая больше не существует при выполнении основного кода). Другим преимуществом является то, что мне нужно только указать точку входа для каждой фазы, и компоновщик сделает остальную часть поиска кода и данных, необходимых для этой фазы.
    Данные параметров, выводимые из запуска и используемые главным образом, могут быть помещены в общую секцию bss или в стек.

Недостатком является то, что я не вижу, как код запуска и основной код могут совместно использовать функции, которые используются в обеих фазах. Если общие функции невелики, попытка их совместного использования может быть плохой идеей, поскольку lto будет более ограниченным или в конечном итоге встраивает две версии общей функции.

Кто-нибудь знает о предпочтительном методе для этого или имеет какой-либо комментарий к новому предлагаемому подходу?

4b9b3361

Ответ 1

Метод, который я видел (процессоры кролика), использует оверлеи. [Было задействовано некоторое аппаратное обеспечение, поэтому я не уверен, что аналогия прекрасна.] Во всяком случае, понятие, на мой взгляд, похоже на лифт. У вас есть небольшое количество программного пространства (клетка лифта), которое всегда безопасно и жизнеспособно. Но если вы хотите получить доступ к другому "полу", вернитесь в лифт (ПК находится в этом маленьком адресном пространстве), а затем переключите настройки, чтобы активировать другой банк памяти. Затем вы можете выйти из лифта и быть на новом этаже.

У вас немного другая проблема (вы хотите использовать меньше памяти вместо того, чтобы не иметь достаточного количества адресных строк), но может применяться одна и та же стратегия.

Начало в лифте. Запустите первый код запуска, который устанавливает определенные значения данных, также предположительно в безопасной зоне. Отходите обратно к лифту. Перезапишите начальное кодовое пространство. Теперь вы можете выйти из лифта. Но вам все равно нужны адреса нового пространства. Их нужно где-то хранить. Возможно, у вас есть два набора указателей на функции, с перекрывающимися адресами, один для использования при запуске, а другой для использования в основном коде. Просто используйте правильные функции в нужное время.