Как исправить предупреждение компоновщика: «функция не определена» в пространстве ядра? - PullRequest
0 голосов
/ 06 мая 2019

Я работаю над интегрированным SDK для микропроцессора powerpc, в котором есть несколько модулей ядра.
Ядро (3.12.37) и набор инструментов (powerpc gcc 4.9.2), предоставленные проектом Yocto.
Когда я делаю SDK на собственной машине (x86_64bit Ubuntu 14) с помощью упомянутого набора инструментов и источника ядра, я вижу эти предупреждения во время компиляции модуля ядра:

WARNING: "__udivdi3" [modules/foo.ko] undefined!
WARNING: "__umoddi3" [modules/foo.ko] undefined!

Эти предупреждения появляются, когда я insmod модуль ядра. Я понял, что эти функции используются для 64-битных операций, и libgcc имеет эти функции. это флаги компиляции:

"-Wall -Werror -gdwarf-3 -Wframe-larger-than=16384 -mcpu=powerpc"  

также, я дал этот флаг для статической компиляции "-Wl,-static-libgcc" и не работал.

мои вопросы:

  1. почему компоновщик будет использовать 64-битные функции, которых нет в powerpc arch ($ KERNELDIR / arch / powerpc)? (Линкер знает, что ARCH - powerpc)

  2. "в пространстве ядра компилятор не использует libgcc или другие функции и библиотеки пользовательского пространства", это правильно? если нет, пожалуйста, объясните мне.

  3. и, наконец, как я могу решить эту проблему?

Спасибо.

1 Ответ

0 голосов
/ 07 мая 2019
  1. Компилятор сгенерирует код, который вызывает функции в libgcc для выполнения определенных операций.В этом случае их вызывают для выполнения операций обычного деления (/) и по модулю (%) на 64-разрядных величинах.

  2. Правильно, ядро ​​не 't использовать libgcc.Код ядра должен быть написан для предотвращения вызова компилятором функций в libgcc (в данном случае для операций деления и модуля на 64-битных количествах).

  3. Любой код, который выполняет деление илиОперации по модулю над 64-разрядными величинами (за исключением собственных типов со знаком * и без знака long на 64-разрядных архитектурах) должны быть переписаны для использования специальных 64-разрядных функций деления и макросов, предоставляемых ядром Linux вместо обычных / и % операторы.

    В старые времена это делалось путем вызова макроса do_div(n,base), определенного #include <asm/div64.h>, но он имеет необычный нефункциональный интерфейс, так как он изменяет вызывающую функцию.n параметр, чтобы стать дивидендом n / base в дополнение к возврату остатка n % base.

    Для нового кода лучше избегать старого макроса do_div(n,base) и использовать функцииобъявлено #include <linux/math64.h>.Здесь определены различные функции для аргументов со знаком и без знака, а также для 32-битных и 64-битных остатков.Вам нужно выбрать наиболее подходящую функцию, соответствующую требованиям вашего кода.

...