Проект R
Руководство разработчика
×

6.1. Linux OS: kernel

Ядро Linux версии 2.6.xx собирается для разработанных и разрабатываемых встраиваемых решений. Описание приводит последовательность установки и ответов на вопросы: что делать, если что-то пойдет не так.
Что такое Linux? Linux - это клон операционной системы Unix, написанный с нуля Линусом Торвальдсом при содействии сплоченной команды хакеров по всей сети, направленный на обеспечение соответствия спецификациям POSIX и Single UNIX. Linux обладает всеми функциями и соотвествует полноценной Unix, включая: реальную многозадачность, виртуальную память, разделяемые библиотеки, загрузку по требованию, совместное копирование исполняемых файлов при записи, надлежащее управление памятью и многоуровневую сеть, включая IPv4 и IPv6. Linux распространяется под лицензией GNU General Public License. Изначально Linux был разработан для 32-разрядных ПК на базе x86 (прим.: 386 или выше), на сегодня Linux также работает на Compaq Alpha AXP, Sun SPARC, UltraSPARC, Motorola 68000, PowerPC, PowerPC64, ARM, Hitachi SuperH, Cell, IBM S/390, MIPS, HP PA-Архитектуры RISC, Intel IA-64, DEC VAX, AMD x86-64, AXIS CRIS, Xtensa, AVR32 и Renesas M32R.
Linux легко переносим на большинство 32- или 64-разрядных архитектур общего назначения, если у них есть модуль управления выгружаемой памятью (прим.: PMMU) и порт компилятора GNU C (прим.: gcc, часть коллекции компиляторов GNU, GCC). Linux также был портирован на архитектуры без PMMU но с ограниченной функциоальностью.
Linux позволяет запускать ядро как приложение в пользовательском пространстве - это называется UserMode Linux (прим.:UML)
 
Локация и струткура архива:
Архив с ядром для загрузки доступен на сервере: ссылка. Структура архива соотвествует ветки дерева разработки ядра версии 2.6
 
Подкаталоги документация:
  • подкаталог Documentation/ содержит файлы README с например, инструкциями по установке для некоторых драйверов, относящиеся к конкретному ядру. Список того, что содержится в каждом файле в документации/00-INDEX;
  • подкаталог Documentation/DocBook/ содержит несколько руководств для разработчиков ядра и пользователей. Для корректного оботбражения необходимо установить пакеты с просмоторщиками, слеующими командами "make psdocs", "make pdfdocs", "make htmldoc" или "make mandocs"
     
    Установка исходного кода ядра:
  • шаг 1: перенос архива ядра в каталог с разрешененим действий распаковки;
  • шаг 2: распаковка, "xx" необходимо заменить номером версии последнего ядра:
gzip -cd linux-2.6.xx.tar.gz | tar xvf -
 или
bzip2 -dc linux-2.6.xx.tar.bz2 | tar xvf -
Комментарий: облсть /usr/src/linux! содержит (прим.: обычно неполный) набор заголовков ядра, которые используются файлами заголовков библиотеки. Они должны соответствовать библиотеке. Работа с ядром не должна влиять на данный раздел не при каких обстоятельствах.
  •   шаг 3: обновим версию ядра 2.6.xx с помощью исправлений. Исправления распространяются в традиционном формате gzip и более новом формате bzip2. Чтобы получить все новые файлы исправлений, необходимо войти в каталог верхнего уровня исходного кода ядра (прим.: linux-2.6.xx) и выполнить:
gzip -cd ../patch-2.6.xx.gz | patch -p1
или
bzip2 -dc ../patch-2.6.xx.bz2 | patch -p1
Комментарий: при обновлении, следите за указываемой в командах xx (прим.: версии ядра), которая должна превышать версию текущего исходного дерева _in_order_. После удаления файлов резервных копий (прим.: xxx~ или xxx.orig) необходимо убедиться, что нет неудачных исправлений (xxx# или xxx.rej).
Обновления необходимы для подгрузки исправлений, важно знать, что исправления для ядер 2.6.x и исправления для ядер 2.6.x.y (прим.: разработчики называют это стабильные ядра) не являются инкрементными, а вместо этого применяются непосредственно к базовому ядру 2.6.x.  Дополнительная информация в Documentation/applying-patches.txt.
Данный процесс можно автоматизировать, через скрипт patch-kernel, позволяя определять текущую версию ядра и применять все найденные исправления:
linux/scripts/patch-kernel linux
Команда позволяет подтягивать исправления из текущего каталога, но в качестве второго аргумента может быть указан альтернативный каталог.
Если обновления между выпусками происходит с использованием пакета исправлений из стабильной серии, напрример, patch-2.6.xx.y, обратите внимание, что это "точечные релизы" (прим.: стабильных ядер) не являющиеся инкрементными, должны применяться к базовому дереву 2.6.xx. Например, если ядро версии 2.6.12, a патч исправлений 2.6.12.3, необходимо применить патчи 2.6.12.1 и 2.6.12.2. Аналогично для перехода версий между ядрами, например, перейти с 2.6.12.2 на 2.6.12.3, необходимо отменить исправления 2.6.12.2:
patch -R
_before_ затем применить патч 2.6.12.3. Дополнительная информация содержится в Documentation/applying-patches.txt. После проведённых процедур, необходимо убедится, что нет устаревших файлов и зависимостей, лежащих в окружении:
cd linux
make mrproper
Если все шаги выполнены успешно - код ядра установлен верно
 
Требование к программному обеспечению:
Для компиляции и запуска ядер 2.6.xx требуется обновление версии различных пакетов программного обеспечения. Нельзя увлекаться обновлениями пакетов, старые версии пакетов могут привести к зависимым ошибкам, которые очень трудно отследить.
 
Каталог BUILD для ядра:
При компиляции ядра все выходные файлы по умолчанию будут храниться вместе с исходным кодом ядра. Если необходимо хранить файлы в выбранном месте включая .confi, необходимо применить опцию "make O=output/dir":
kernel source code:  /usr/src/linux-2.6.N
build directory:   /home/name/build/kernel
Конфгурация сборки ядра выполняется клмандами:
cd /usr/src/linux-2.6.N
make O=/home/name/build/kernel menuconfig
make O=/home/name/build/kernel
sudo make O=/home/name/build/kernel modules_install install
Комментарий: если используется опция 'O=output/dir', то она должна быть использована для всех вызовов команды make.
 
Конфигурирование ядра:
Данный шаг обязателен не зависимо от важности проводимых обновлений.  В каждом выпуске добавляются новые параметры конфигурации. Процесс переноса существующей конфигурации в новую версию с минимальными затратами запускается командой - "make oldconfig".
  • командами отвечающими за конфигурацию выступает набор указаный в таблице 6.2
     
Таблица 6.2 – команды отвечающие за конфигурацию ядра
Команда
Описание
Примечание
make config
текстовый интерфейс
-
make menuconfig
графичсекое меню, радиолисты и диалоги на основе текста
-
make xconfig
инструмент конфигурирования на основе X windows (Qt)
-
make gconfig
инструмент настройки на основе X windows (Gtk)
-
make oldconfig
обновляет существующий файл ./.config с запросом новых значениях конфигурации
-
make silentoldconfig
запрашивает с предложением о включении опций Как и выше, но позволяет избежать загромождения экрана вопросами, на которые уже есть ответы
-
make defconfig
обновляет зависимости сверяя config текущий, новой версии ядра и настроенной, персонализированной опции, параметра. Создаёт конфигурационный файл, который использует настройки по умолчанию, основанные на архитектуре текущей системы. Позволяет собрать конфигурацию, используя значения по умолчанию командами в зависимости от архитектуры:
         arch/$ARCH/defconfi
или
         arch/$ARCH/configs/${PLATFORM}_defconfig
-
make ${PLATFORM}_defconfig
Позволяет собрать конфигурацию, используя значения по умолчанию для конкретной платформы, команда
         arch/$ARCH/configs/${PLATFORM}_defconfig
используйте команду "make help", чтобы получить список всех доступных платформ для архитектуры на которую устанавливается Linux
-
make allyesconfig
сборка компактной конфигурации ядра с включением критчисеки важных параметров и исправлений
подтверждение выбора 'y'
make allnoconfig
Сорка конфигурации позваляющая включать в ядро тлько существенно важные модули
подвтерждение выбора 'n'
make allmodconfig
позволяет отметить модули как подгружаемые, а не встроеные в ядро
подтверждение выбора 'm'
make randconfig
сборка конфигурации ядра для тестирования, произволный выбор значений,позволяет проверить сборку и запуск ядра
-
Комментарий: подробная информацию об использовании инструментов конфигурации ядра Linux содержится вдокументах Documentation/kbuild/kconfig.txt. Примечания по сборке конфигурации командой "make config":
  • наличие ненужных драйверов увеличивает размер ядра и может привести к проблемам, например, поиск нарушение области видимости раверов, свзяок с контроллерами при поиске не поддерживаемой платы;
  • компиляция ядра с параметром "Тип процессора" выше 386 приведет к тому, что ядро не будет работать на 386-ом;
  • ядро со скомпилированной математической эмуляцией все равно будет использовать сопроцессор, если он есть.  Ядро будет немного больше, но будет работать на разных машинах независимо от того есть ли в них математический сопроцессор или нет;
  • конфигурация "взлома ядра" обычно приводят к тому, что ядро становится менее стабильным за счет настройки некоторых процедур на активные перенастроить "плохой" код, чтобы найти проблемы ядра (прим.: kmalloc()).  При сборке ядра стоит ответить 'n' на вопросы для модулей "разработка", "экспериментальные" или "отладочные" функции.
 
Компилирование ядра:
  • установите или проверьте версию gcc, необходима не менее 3.2;
  • выполнить команду "make" для создания сжатого образа ядра. Если установлен lilo можно выполнить "make install";
  • если какие-либо части ядра конфигурировались как модули необходимо выполнить команду "make modules_install";
  • вывод компиляции/сборки ядра:
Комментарий: чтобы видеть компиляцию, компоновку или другие процессы в момент их выполнения, необходимо спользовать режим сборки "verbose". Включить режим можно установив в комаду "make" аргумент "V=1", make V=1 all. Аогумент "V=2", позволит увидеть причины по которым может потребоваться пересобрать ядро
  • при компилировании ядра, позаботьтесь, чтобы под рукой было резервное ядро с резервной копией модулей, соответствующих этому ядру.  Если новое и текущее ядро одинаковой версии, необходимо сделать резервную копию каталога модулей, прежде чем выполнить команду "make modules_install". В качестве альтернативы, перед компиляцией ядра, можно включить параметр конфигурации ядра "LOCALVERSION", чтобы добавить уникальный суффикс к обычной версии ядра. Включается параметр LOCALVERSION в меню "Общая настройка".
  • перед загрузкой нового ядра, нужно скопировать образ ядра, например, .../linux/arch/i386/boot/bzImage. Образ необходимо разместить рядом с загрузочным ядром.
  • файл образа ядра обычно находится в /vmlinuz, /boot/vmlinuz, /bzImage или /boot/bzImage.  Чтобы использовать новое ядро, необходимо сохранить копию старого образа и скопировать новый образ поверх старого.  Затем, запустить LILO повторно или если просто запустить LILO. Если этого не сделать, не получиться загрузить новый образ ядра. Переустановка LILO обычно сводится к запуску /sbin/lilo. Для указания сслыки на старый образ ядра (прим.: на случай если новая версия ядра не запустится) необходимо отредактировать /etc/lilo.conf, например, /vmlinux.old на случай. После проведённых действий, необхожимо перезапустить службу;
    Комментарий: изменить установки по умолчанию - видеорежим, размер ramdisk и подобное в образе ядра, необходимо использовать программу 'rdev' (прим.: или альтернативные опции загрузки LILO, когда это необходимо). Нет необходимости перекомпилировать ядро для смены установок по умолчанию.
  • перезагрузите систему с новым ядром - готово.
 
Если возникла ошибка:
  • возникшую ошибку, информации по которой нет в данном руководстве или не удалось найти в сообществе разработчиков, можно отправить письмом на адрес - torvalds@linux-foundation.org. Поскольку адрес принадлежи главному разработчику Linux в каждом сообщении об ошибках *обязательно* необходимо указать версия ядра, характеристику системмы на которую устанавливается ядро и как длого сохраняется проблема. Если в результате ошибки появляется сообщение (прим.: дамп) типа:
    unable to handle kernel paging request at address C0000010
    Oops: 0002
    EIP:   0010:XXXXXXXX
    eax: xxxxxxxx   ebx: xxxxxxxx   ecx: xxxxxxxx   edx: xxxxxxxx
    esi: xxxxxxxx   edi: xxxxxxxx   ebp: xxxxxxxx
    ds: xxxx  es: xxxx  fs: xxxx  gs: xxxx
    Pid: xx, process nr: xx
    xx xx xx xx xx xx xx xx xx xx
обязательно небходимо отправить на указыанный почтовый адрес. Текст сообщения, который предшествует дампу, необходимо включить в письмо, поскольку говорит о том, почему произошла ошибка в приведенном примере ошибка связана с плохо устанавленным указателем ядра. Более подробная информация о том, как читать дамп содержится в Documentation/oops-tracing.txt;
  • при компиляции ядра с парметром CONFIG_KALLSYMS и возникновении ошибки, изучить дамп можно при помощи программы "ksymoops". Утилиту можно загрузить с сайта https://mirrors.edge.kernel.org/pub/linux/utils/kernel/ksymoops/;
  • в дампах есть параметр EIP, значение параметра зависит от конкретной настройки ядра и позволяет самостоятельно определить какая фуекция выдаёт ошибку. Чтобы найти какя функция срабытывает не корректно, выпишите значение из строки EIP после системного префикса - "0010:", откройте список имён функций ядра. Открыть список необходимо следующим образом: найти системный двоичный файл, связанный с ядром, в котором проявился симптом - 'linux/vmlinux', извлечь список имен командой:
nm vmlinux | sort | less
после открытия списка функций ядра можно сопоставить EIP дампа. Список функций ядра отсортирован в поряке возрастания;
Комментарий: команда 'grep' применённая к полученному списку может выдать не корректный результат из-за несовпадения полного имени в списках функций и дампа (прим.: встречается редко). При составлении отчёта об ошибках, который прикладывается к письму, обобщающий в себе выше рассмотренные пункты стоит включить "контекст" об ошибках
  •  для работы с ошибками и устранением можно воспользоваться debugger gdb, запустив отладчик на ядре. Перед запуском необходимо скомпилировать ядро с флагом -g, отредактировать arch/i386/Makefile, затем выполнить команду:
    make clean
    включить праметр CONFIG_PROC_FS (прим.: через команду "make config"). После указанных действий необходимо перезагрузить систему. После перезагрузки выполнить команду:
    gdb vmlinux /proc/kcore
    после выполнения команды можно использовать набор команд gdb. Команда для поиска функции в которой произошел сбой системы:
    l *0xXXXXXXXX
    сиволы XXX необходимо заменить на значения EIP из дампа