Библиотека сайта 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 does not match actual kernelИ вывод klogd или ksymoops в случае некоторых сбоев в работе ядра не будет соответствовать действительности.
Каждый раз, когда вы компилируете новое ядро, адреса символов изменяются и в процессе компиляции ядра создается новый файл System.map. Если вы имеете на своей машине несколько разных ядер, должен быть создан свой файл System.map для каждого из них с именем System.map-release соответственно.
Примечание: К.Касперски советует: "Файл System.map (обычно располагающийся в каталоге /boot) включает в себя символьную информацию о глобальных переменных и функциях, экспортируемых ядром, и широко используется руткитами, которые прячут от глаз администратора враждебные файлы, процессы и сетевые соединения. И хотя достаточно многие руткиты могут находить необходимые им функции и без System.map'a, его удаление существенно уменьшает вероятность успешного проведения атаки. В "мирных целях" System.map нужен разве что отладчикам, да некоторым низкоуровневым программам. На всякий случай, чтобы потом не перекомпилировать ядро (а System.map создается именно при перекомпиляции ядра), скопируй его в надежное место (например, на внешний носитель) или просто переименуй во что-то менее "напряженное".
Назад | Оглавление | Вперед |