Внутреннее устройство ядра Linux 2.4

Построение образа ядра Linux


В данном разделе рассматриваются этапы сборки ядра Linux и обсуждается результат работы каждого из этапов. Процесс сборки в значительной степени зависит от аппаратной платформы, поэтому особое внимание будет уделено построению ядра Linux для платформы x86.

Когда пользователь дает команду 'make zImage' или 'make bzImage', результат -- загрузочный образ ядра, записывается как arch/i386/boot/zImage или arch/i386/boot/bzImage соответственно. Вот что происходит в процессе сборки:

  • Исходные файлы на C и ассемблере компилируются в перемещаемый [relocatable] объектный код в формате ELF (файлы с расширением .o), при этом некоторые файлы, с помощью утилиты ar(1), дополнительно группируются в архивы (с раширением .a)
  • Созданные на предыдущем шаге, файлы .o и .a объединяются утилитой ld(1) в статически скомпонованный исполняемый файл vmlinux в 32-разрядном формате ELF 80386 с включенной символической информацией.
  • Далее, посредством nm vmlinux, создается файл System.map, при этом все не относящиеся к делу символы отбрасываются.
  • Переход в каталог arch/i386/boot.
  • Текст asm-файла bootsect.S перерабатывается с или без ключа -D__BIG_KERNEL__, в зависимости от конечной цели bzImage или zImage, в bbootsect.s или bootsect.s соответственно.
  • bbootsect.s ассемблируется и конвертируется в файл формата 'raw binary' с именем bbootsect

    (bootsect.s ассемблируется в файл bootsect в случае сборки zImage).

  • Содержимое установщика setup.S

    (setup.S подключает video.S) преобразуется в bsetup.s для bzImage (setup.s для zImage). Как и в случае с кодом bootsector, различия заключаются в использовании ключа -D__BIG_KERNEL__, при сборке bzImage. Результирующий файл конвертируется в формат 'raw binary' с именем bsetup.

  • Переход в каталог arch/i386/boot/compressed. Файл /usr/src/linux/vmlinux переводится в файл формата 'raw binary' с именем $tmppiggy и из него удаляются ELF-секции .note и .comment.
  • gzip -9 < $tmppiggy > $tmppiggy.gz
  • Связывание $tmppiggy.gz в перемещаемый ELF-формат (ld -r) piggy.o.

  • Компиляция процедур сжатия данных head.S и misc.c (файлы находятся в каталоге arch/i386/boot/compressed) в объектный ELF формат head.o и misc.o.


  • Объектные файлы head.o, misc.o и piggy.o объединяются в bvmlinux ( или vmlinux при сборке zImage, не путайте этот файл с /usr/src/linux/vmlinux!). Обратите внимание на различие: -Ttext 0x1000, используется для vmlinux, а -Ttext 0x100000 -- для bvmlinux, т.е. bzImage загружается по более высоким адресам памяти.


  • Преобразование bvmlinux в файл формата 'raw binary' с именем bvmlinux.out, в процессе удаляются ELF секции .note и .comment.


  • Возврат в каталог arch/i386/boot и, с помощью программы tools/build, bbootsect, bsetup и compressed/bvmlinux.out

    объединяются в bzImage (справедливо и для zImage, только в именах файлов отсутствует начальный символ 'b'). В конец bootsector записываются такие важные переменные, как setup_sects и root_dev.


  • Размер загрузочного сектора (bootsector) всегда равен 512 байт. Размер установщика (setup) должен быть не менее чем 4 сектора, и ограничивается сверху размером около 12K - по правилу:

    512 + setup_sects * 512 + место_для_стека_bootsector/setup <= 0x4000 байт

    Откуда взялось это ограничение станет понятным дальше.

    На сегодняшний день верхний предел размера bzImage составляет примерно 2.5M, в случае загрузки через LILO, и 0xFFFF параграфов (0xFFFF0 = 1048560 байт) для загрузки raw-образа, например с дискеты или CD-ROM (El-Torito emulation mode).

    Следует помнить, что tools/build выполняет проверку размеров загрузочного сектора, образа ядра и нижней границы установщика (setup), но не проверяет *верхнюю* границу установщика (setup). Следовательно очень легко собрать "битое" ядро, добавив несколько больший размер ".space" в конец setup.S.


    Содержание раздела