Выпечка 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
), средства обработки ошибок, такие какsetjmp
longjmp
и больше. - Подумайте: как бы вы реализовали
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.