2013-11-07 3 views
2

Мой родной gcc говорит, что его триплет следующий.Компиляция ядра GNU Triplet, GCC и Linux

> gcc -dumpmachine 
x86_64-suse-linux 

Где CPU-поставщика ОС являются соответственно x86_64, SuSE Linux. Последнее означает, что используются глифы (?). Когда я выполняю кросс-компиляцию системы на основе busybux, триплет компилятора - это что-то вроде avr32-linux-uclibc, где os - это «linux-uclibc», что означает, что используется uclibc.

Разница между 'linux-glibc' и 'linux-uclibc' (AFAIU) в поведении collect2 и содержимом libgcc.a. Либо glibc, либо uclibs молча связаны с целевым двоичным кодом.

Вопрос заключается в том, как как ядро ​​linux было скомпилировано одними и теми же компиляторами? Как только ядро ​​работает на bare-metal, оно не должно быть связано с каким-либо пользовательским пространством libc и должно использовать соответствующий libgcc.a

+0

Некоторые компиляторы используют * квадруплет *. Форма: * architechure * - * vendor * - * os * - * library *. Но даже этого недостаточно, поскольку * FPU *, * формат объекта * и другие соглашения могут применяться. В корневом каталоге 'gcc' просто поддерживает префикс, который является свободной формой. Люди придумывают имена, и нет единого объединяющего органа, чтобы сделать их уникальными. '-dumpspecs' и т. д. могут использоваться для идентификации компилятора. –

ответ

2

В gcc есть все возможности для управления тем, как он работает. Вот несколько значимых из них:

  • -nostdlib опустить ссылки на стандартные библиотеки и коды запуска
  • -nostdinc для опускает поиск заголовочных файлов в стандартных местах.
  • -ffreestanding компилировать для автономной среды (например, ядро)

Вам также не нужно использовать GCC для связывания. Вы можете напрямую ссылаться на компоновщик, поставлять его с вашей собственной компоновкой, кодом объекта запуска и всем остальным, что вам нужно.

Строка ядра linux по каким-либо причинам не использует -ffreestanding, однако она контролирует этап компоновки и гарантирует, что ядро ​​связывается без привлечения какого-либо кода пользовательского пространства.

+0

В этом случае можно было бы использовать x86_64-suse-linux-uclibc вместо x86_64-suse-linux-glibc, просто указав '-nostdlib -nostdinc -I ... -L ... -l ...' ? Это означает, что указание linux-uclibc является избыточным. – 0x2207

+0

Для компиляции ядра не должно иметь значения, какой из двух вы используете, для приложений пользовательского пространства это должно быть возможно, но довольно громоздко, поскольку вам придется вручную вытащить правильный код запуска и библиотеки и, возможно, другой компоновщик карты, а также для подачи или переопределения макросов препроцессора, если есть какой-либо код, который опирается, например, на #define присутствует для указания разницы между glibc и uClibc. – nos

+1

В Linux есть встроенная функциональность, обычно предоставляемая * libgcc *. Я надеюсь, что это не зависит от используемого * libc *. Для ARM вы все равно можете испортить ядро, если используете компилятор с различными соглашениями о регистре. Для идентичных параметров компилятора, кроме библиотеки (glibc/eglibc vs uclibc vs newlib), ваш ответ может быть правильным. Вот пример [пример] (http://stackoverflow.com/questions/12174247/android-ndk-8b-cannot-load-library) libgcc, сгенерированный компилятором, но недоступный в системе. Linux имеет множество внутренних функций * libgcc * в своем источнике. –

Смежные вопросы