Eudyptula Challenge и путь ядра

Я решил принять Eudyptula Challenge. После того, как я представил первую задачу, которая заключается в создании простого "Hello World!" модуль, я получил следующий ответ.

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

Требования:

Makefile должен иметь возможность создавать модуль ядра против источник текущего ядра, а также возможность принимать произвольный каталог источников ядра из переменной среды.

То, что я делаю, проверяет, установлена ​​ли переменная среды KERNELRELEASE. Если я создаю модуль против

$(KERNELRELEASE)/build  

и если он не против

/lib/modules/$(shell uname -r)/build

Я не понимаю, почему это не удовлетворяет требованиям этой задачи.

Ответ 1

Согласно правилам Eudyptula challenge, вам запрещено прямое решение, поэтому я попытаюсь описать элементы ответа, так что вы можете придумайте решение самостоятельно. В принципе, все, что я написал ниже, описано довольно подробно в файле Documentation/kbuild/modules.txt (особенно в раздел 3.1 - Shared Makefile), поэтому я не думаю, что это будет какое-то нарушение правил. Ниже приведено просто объяснение того, что описано в указанной документации.

KERNELRELEASE переменная

В чем вы ошибаетесь, думайте, что $(KERNELRELEASE) предназначен для сохранения пути к ядру. Какая $(KERNELRELEASE) переменная на самом деле означает - вы можете найти ее в Documentation/kbuild/makefiles.txt:

KERNELRELEASE

$(KERNELRELEASE) - это одна строка, такая как "2.4.0-pre4", подходящая для создания имен каталогов установки или отображения в строки версии. Некоторые арки Makefiles используют его для этой цели.

Дело в том, что ваш Makefile будет выполняться 2 раза: от вашей make и от ядра Makefile. И $(KERNELRELEASE) может быть полезным для выяснения:

  • Если эта переменная не определена, ваш Makefile работает от вашей команды make; на этом этапе вы будете запускать ядро ​​Makefile (предоставление каталога ядра с использованием параметра -C). После запуска make для файла Makefile ядра (из внутри вашего Makefile) ваш Makefile будет выполнен второй раз (см. Следующий элемент).
  • Если эта переменная определена, ваш Makefile выполняется из ядра Makefile (который определил эту переменную и вызвал ваш Makefile назад). На этом этапе вы можете использовать функции системы сборки ядра, такие как obj-m.

-C param

Что вам действительно нужно сделать, так это определить пользовательскую переменную в Makefile, которая будет содержать путь к каталогу ядра. Вы можете назвать его KDIR, например. Как вы знаете, ваши источники ядра расположены по этому пути: /lib/modules/$(shell uname -r)/build. Затем вы можете указать эту переменную в -C param (см. man 1 make) при выполнении файла Makefile ядра.

Далее вам нужно передать эту переменную извне вашего Makefile. Для этого можно использовать оператор присваивания условных переменных:

KDIR ?= /lib/modules/$(shell uname -r)/build

Таким образом, если вы передадите переменную KDIR в свой файл Makefile, например:

$ make KDIR=bla-bla-bla

переменная KDIR будет иметь значение, которое вы передали. В противном случае оно будет содержать значение по умолчанию, которое равно /lib/modules/$(shell uname -r)/build.