Выпечка PI с C и основными библиотеками

У меня возникла следующая проблема - я выполнил курс pi без проблем, и затем я решил связать этот чистый asm с некоторым C. И я сделал это, и все работает хорошо, поскольку я решил использовать функцию sprintf для конвертировать int в char*. Теперь, когда я пытаюсь скомпилировать, я наслаждаюсь следующей ошибкой

ctesty.c:(.text+0x20): undefined reference to 'sprintf' make: *** [build/output.elf] Error 1

Конечно, я включил stdio.h, я также попытался включить эту библиотеку непосредственно в make-файл, но безуспешно.

1 ответ

Решение

Вы хотите связаться с libc.so, Попробуйте добавить -lc в шаге ссылки в ваших make-файлах.

Обновление после лучшего понимания вопроса

Примеры выпечки Пи построить kernel.img это работает вместо обычного ядра Linux. Это означает, что стандартная библиотека C недоступна. Вам нужно будет предоставить свой собственный sprintf() реализация, например:

  • Адаптируйте эту лицензию BSD ee_printf.c
  • Удалить uart_send_char()
  • адаптироваться ee_printf() в sprintf() делая buf параметр функции

Почему libc Userspace не будет работать без изменений исходного кода в любом ядре

Концептуально:

  • Стандартная библиотека C содержит средства для динамического распределения памяти (malloc, free), файловая система (fopen, fclose и все из stdio), переменные окружения (getenv), средства обработки ошибок, такие как setjmplongjmp и больше.
  • Подумайте: как бы вы реализовали malloc в программе, работающей под операционной системой?
    • Ответ: Вам понадобится некоторый интерфейс для запроса дополнительной памяти от ОС, такой как brk, sbrk а также mmap под линуксом.
    • В ядре ОС brk, mmap и т. д. не будет подходящих интерфейсов для выделения памяти.
    • Таким образом, хотя большинство неигровых ядер обеспечивают malloc как объекты, они не смогут использовать пространство пользователя malloc реализации без изменений.
  • В ядре ОС такие функции как fopen, getenv не очень полезны. Большинство авторов ядра предпочитают не включать их.
  • Таким образом, большинство ядер не включают полных реализаций стандартной библиотеки C, а только те функции, которые авторы ядра считают полезными.

В более механическом смысле:

  • Makefile Baking Pi создает образ ядра ELF с помощью команды $(ARMGNU)-ld --no-undefined $(OBJECTS) -Map $(MAP) -o $(BUILD)output.elf -T $(LINKER), Это не ссылка build/output.elf с любой реализацией libc, чтобы компоновщик не смог найти символ с именем sprintf,
  • Когда вы создаете программу с gcc T.c -o T, gcc неявно ссылается на libc, если опция не похожа -nostdlib передается.

Но концептуально важные моменты:

  • Части стандартной библиотеки C, которые полезны в ядре, потребуют разных реализаций
  • Многие другие части libc не будут так полезны в ядре

Существуют стандартные реализации библиотеки C, ориентированные на использование в чистых средах. Смотрите, например, newlib.

Другие вопросы по тегам