Наши партнеры

UnixForum






Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

Исследуем процесс загрузки Linux

(C) В.А.Костромин, 2007
(версия файла от 6.08.2007 г.)


Назад Оглавление Вперед

Этап 3: Загрузчик 2 этапа операционной системы

3.3. Файл System.map

Снова заглянем в каталог /boot и на сей раз поинтересуемся находящимся там файлом System.map-suff, где suff - некий суффикс, содержащий номер соответствующего ядра и, возможно, указание на версию дистрибутива. Например, в дистибутиве ASP Linux 11 этот файл называется System.map-2.6.14-1.1653.1asp. Обычно в том же каталоге имеется символическая ссылка, позволяющая обращаться к этому файлу просто как к System.map. Это имя мы и будем ниже использовать.

Информации о назначении этого файла в сети на удивление мало. Единственная содержательная статья - это заметка [16]. Во всех других найденных поисковиком ссылках просто утверждается, что этот файл нужно переносить в загрузочный каталог вместе со вновь скомпилированным ядром. Кроме заметки [16] упоминание файла System.map можно найти в man-страничках к утилитам klogd и ps.

3.3.1. Что такое "Таблица символов ядра"?

Файл System.map содержит таблицу символов ядра. Символ - это имя переменной или название функции. Поскольку ядро - это сложная программа, она содержит множество глобальных символов. Программисты, естественно, дают переменным и функциям "человеческие" имена, вроде "ascii_buffer" или "BytesRead()". Но компьютер имена в таком виде использовать не может, ему нужны адреса соответствующих переменных и функций примерно такого вида: c0343f20. Поскольку основная часть ядра написана на C, проблемы это не составляет, компилятор/линкер позволяет программистам использовать имена символов, преобразуя их в адреса для компьютера. И все счастливы.

Однако имеются ситуации, когда нам нужно знать адреса символов (или определить название символа по его адресу). Для этого и создается таблица символов ядра. В ней перечислены все символы ядра и даны их соответствующие адреса. Вот несколько строк из таблицы символов ядра версии 2.6.14, установленного в системе ASP Linux 11. Эти строки позволят вам составить представление об этой таблице, а в своей системе вы можете просмотреть ее, заглянув в файл /boot/System.map.

Листинг 5. Несколько первых строк из таблицы символов ядра

00000400 A __kernel_vsyscall
00000410 A SYSENTER_RETURN_OFFSET
00000420 A __kernel_sigreturn
00000440 A __kernel_rt_sigreturn
00100000 A phys_startup_32
c0100000 A _text
c0100000 T startup_32
c01000c6 t checkCPUtype
c0100147 t is486
c010014e t is386
c0100199 t L6
c010019b t check_x87
c01001c2 t setup_idt
c01001df t rp_sidt
c01001ec t ignore_int
c0100220 T _stext
c0100220 t rest_init
c0100220 T stext
c010023b t do_pre_smp_initcalls
c0100240 t run_init_process
c0100269 t init

Вы можете, например, видеть, что переменная с именем L6 расположена в ядре по адресу c0100199.

3.3.2. Когда и кем используется таблица символов ядра?

Таблица символов ядра используется демоном протоколирования ядра klogd и некоторыми утилитами, предназначенными для управление процессами: top, ps и др. Демон klogd использует эту таблицу для протоколирования событий, связанных с различными сбоями в работе ядра. Например, в тех случаях, когда ядро пытается разименовывать некорректную ссылку, происходит сбой, который сопровождается выдачей сообщения "Oops". При этом ядро в большинстве случаев не "ударяется в панику", а продолжает оставаться в работоспособном состоянии. Пользователю выдается информация, которая может быть полезна для последующего устранения проблемы. Эта информация включает в себя содержимое всех регистров ЦПУ, содержимое стека ядра и содержимое указателя на выполняемую инструкцию (EIP - instruction pointer), которое выглядит примерно следующим образом:
   EIP: 0010:[<00000000>]
   Call Trace: [<c010b860>]

Как видите, информация, выдаваемая в строках EIP и Call Trace, для человека не очень информативна. Чтобы сделать ее более понятной для программиста, klogd преобразует адрес вызова (Call Trace) в символическое имя и передает эту информацию демону системного протоколиррования syslogd. Для преобразования адресов в имена как раз и используется таблица символов ядра.

3.3.3. Где находится таблица символов ядра?

Таблица символов ядра хранится в виде обычного файла на долговременном носителе. В принципе этот файл может находиться где угодно, важно только, чтобы те программы, которые его используют, знали где его искать. Man-страница к демону klogd утверждает, что местоположение этой таблицы можно задать, используя опцию -k в командной строке запуска демона. Если же эта опция не задана, то демон будет искать таблицу символов ядра в следующих файлах:
/boot/System.map
/System.map
/usr/src/linux/System.map

Как говорится в статье [16], хотя man-страница к klogd и утверждает, что таблица символов ядра может находиться в файле /usr/src/linux/System.map, это не прослеживается в исходных кодах демона klogd. В той же статье утверждается, что демон klogd ищет в упомянутых каталогах не только файл System.map, но и файл System.map-release, где -release - номер версии текущего ядра. Причем, если обнаруживается файл System.map для ядра другой версии, поиск продолжается.

Утилита ps ищет таблицу символов ядра в следующих файлах:

$PS_SYSMAP
$PS_SYSTEM_MAP
/proc/*wchan
/boot/System.map-'uname -r'
/boot/System.map
/lib/modules/'uname -r'/System.map
/usr/src/linux/System.map

Как видим, самое естественное место для таблицы символов ядра - файл /boot/System.map. Здесь ее найдут все программы, которые в ней нуждаются.

Впрочем, из приведенного материала следует, что на интересующий нас процесс загрузки системы этот файл влияния не оказывает. Однако удалять его совсем не следует. Если вы запустите ядро без файла System.map (или с некорректным файлом), вы будете каждый раз при запуске ps получать сообщение вида:
System.map does not match actual kernel
И вывод klogd или ksymoops в случае некоторых сбоев в работе ядра не будет соответствовать действительности.

Каждый раз, когда вы компилируете новое ядро, адреса символов изменяются и в процессе компиляции ядра создается новый файл System.map. Если вы имеете на своей машине несколько разных ядер, должен быть создан свой файл System.map для каждого из них с именем System.map-release соответственно.


Примечание: К.Касперски советует: "Файл System.map (обычно располагающийся в каталоге /boot) включает в себя символьную информацию о глобальных переменных и функциях, экспортируемых ядром, и широко используется руткитами, которые прячут от глаз администратора враждебные файлы, процессы и сетевые соединения. И хотя достаточно многие руткиты могут находить необходимые им функции и без System.map'a, его удаление существенно уменьшает вероятность успешного проведения атаки. В "мирных целях" System.map нужен разве что отладчикам, да некоторым низкоуровневым программам. На всякий случай, чтобы потом не перекомпилировать ядро (а System.map создается именно при перекомпиляции ядра), скопируй его в надежное место (например, на внешний носитель) или просто переименуй во что-то менее "напряженное".


Назад Оглавление Вперед