hackers.sgml 1.15 hardware.sgml 1.16 misc.sgml 1.15 network.sgml 1.22 preface.sgml 1.31 commercial.sgml 1.4 x.sgml 1.7 PR: 11001, 11002, 11025, 11026, 11027, 11042, 11043 Submitted by: Andrey Zakhvatov <andy@icc.surw.chel.su>
595 lines
28 KiB
Text
595 lines
28 KiB
Text
<!-- $Id: hackers.sgml,v 1.5 1999-04-13 20:00:29 dt Exp $ -->
|
||
<!-- The FreeBSD Russian Documentation Project -->
|
||
|
||
<sect>
|
||
<heading>
|
||
Только для серьёзных FreeBSD хакеров<label id="hackers">
|
||
</heading>
|
||
|
||
<sect1>
|
||
<heading>
|
||
Что такое SNAP и RELEASE?
|
||
</heading>
|
||
|
||
<p>В <url url="http://www.freebsd.org/cgi/cvsweb.cgi"
|
||
name="дереве CVS"> сейчас находятся три активно/полуактивно
|
||
развивающихся ветки FreeBSD:
|
||
|
||
<itemize>
|
||
<item><bf/RELENG_2_2/ AKA <bf/2.2-stable/ AKA <bf/"ветвь 2.2"/
|
||
<item><bf/RELENG_3/ AKA <bf/3.x-stable/ AKA <bf/"ветвь 3.0"/
|
||
<item><bf/HEAD/ AKA <bf/-current/ AKA <bf/4.0-current/
|
||
</itemize>
|
||
|
||
<p><bf/HEAD/ - это не реальный тег ветки, как другие два, а просто
|
||
символьная константа для обозначения <em/"текущего, не ветвящегося,
|
||
находящегося в разработке дерева"/, то есть <bf/-current/.
|
||
|
||
<p>На данный момент <bf/-current/ является находящимся в разработке
|
||
деревом 4.0, ветка <bf/3.0-stable/, <bf/RELENG_3/, отделилась от
|
||
<bf/-current/ в январе 1999.
|
||
|
||
<p>Ветвь <bf/2.2-stable/, <bf/RELENG_2_2/, отделилась от -current
|
||
в ноябре 1996.
|
||
|
||
<p>Ветвь <bf/2.1-stable/, <bf/RELENG_2_1_0/, отделилась от -current
|
||
в сентябре 1994. Развитие этой ветви полностью прекращено.
|
||
|
||
<sect1>
|
||
<heading>Как самим сделать релиз?<label id="custrel"></heading>
|
||
|
||
<p>Чтобы сделать релиз, вам нужно иметь три вещи: Во-первых, вам нужно
|
||
работать с ядром, включающим драйвер <htmlurl
|
||
url="http://www.freebsd.org/cgi/man.cgi?vn" name="vn">. Добавьте его
|
||
в файл конфигурации ядра и откомпилируйте новое ядро:
|
||
|
||
<verb>
|
||
pseudo-device vn #Vnode driver (turns a file into a device)
|
||
</verb>
|
||
|
||
<p>Во-вторых, вам нужно иметь на диске полное дерево CVS. Чтобы
|
||
добиться этого, вы можете использовать <url
|
||
url="../../handbook/synching.html#CVSUP" name="CVSUP">, указав в файле
|
||
supfile в качестве имени релиза cvs и удалив все поля с тегами и датами:
|
||
|
||
<verb>
|
||
*default prefix=/home/ncvs
|
||
*default base=/a
|
||
*default host=cvsup.FreeBSD.org
|
||
*default release=cvs
|
||
*default delete compress use-rel-suffix
|
||
|
||
## Main Source Tree
|
||
src-all
|
||
src-eBones
|
||
src-secure
|
||
|
||
# Other stuff
|
||
ports-all
|
||
www
|
||
doc-all
|
||
</verb>
|
||
|
||
<p>После этого запустите <tt/cvsup -g supfile/ для выкачки всех
|
||
нужных исходных текстов на ваш компьютер...
|
||
|
||
<p>Наконец, вам нужно свободное место для построения системы.
|
||
Допустим, что свободное место есть в каталоге
|
||
<tt>/some/big/filesystem</tt> и, как в примере выше, вы поместили
|
||
дерево CVS в каталог <tt>/home/ncvs</tt>:
|
||
|
||
<verb>
|
||
setenv CVSROOT /home/ncvs # or export CVSROOT=/home/ncvs
|
||
cd /usr/src/release
|
||
make release BUILDNAME=3.0-MY-SNAP CHROOTDIR=/some/big/filesystem/release
|
||
</verb>
|
||
|
||
<p>Полный релиз будет строиться в каталоге
|
||
<tt>/some/big/filesystem/release</tt> и по окончании этого процесса
|
||
дистрибутив, готовый к помещению на FTP-сервер, будет находиться в
|
||
каталоге <tt>/some/big/filesystem/release/R/ftp</tt>. Если вы захотите
|
||
построить SNAP другой ветки, не -current, то можете указать
|
||
<tt/RELEASETAG=SOMETAG/ в командной строке make release выше, например,
|
||
при указании <tt/RELEASETAG=RELENG_2_2/, будет строиться самый свежий
|
||
снэпшот ветки 2.2-STABLE.
|
||
|
||
<sect1>
|
||
<heading>Как создать инсталляционные диски?</heading>
|
||
|
||
<p>Весь процесс создания инсталляционных дисков и дистрибутивов
|
||
исходных текстов и бинарников автоматизирован в файле
|
||
<tt>/usr/src/release/Makefile</tt>. Информации, в нём содержащейся,
|
||
должно быть достаточно, чтобы начать. Однако, должны вас предупредить,
|
||
что этот процесс включает в себя выполнение ``make world'' и поэтому
|
||
занимает много времени и дискового пространства.
|
||
|
||
<sect1>
|
||
<heading>
|
||
По команде ``make world'' были переустановлены все программы.
|
||
</heading>
|
||
|
||
<p>Да, так и должно быть; как говорит название этой команды, ``make
|
||
world'' выполняет построение всех системных файлов с нуля, так
|
||
что в итоге можете быть уверены, что получите чистую рабочую
|
||
систему (вот почему это занимает столько времени).
|
||
|
||
<p>Если в момент запуска команд ``<tt/make world/'' или ``<tt/make
|
||
install/'' определена переменная окружения <tt/DESTDIR/, то вновь
|
||
создаваемые файлы будут помещены в дерево каталогов. идентичное
|
||
существующему, с корнем, располагающимся в
|
||
<tt>${DESTDIR}</tt>. Однако некоторые случайные
|
||
комбинации модификаций совместно используемых библиотек и версий
|
||
компилируемых программ при исполнении команды ``<tt/make world/'',
|
||
может этому помешать.
|
||
|
||
<sect1>
|
||
<heading>
|
||
При загрузке системы выдаётся сообщение ``(bus speed defaulted)''.
|
||
</heading>
|
||
|
||
<p>Адаптеры SCSI Adaptec 1542 позволяют программно изменять скорость
|
||
доступа к шине. Предыдущие версии драйвера 1542 пытались определить
|
||
максимально возможную скорость работы и установить это значение. Мы
|
||
обнаружили, что у некоторых пользователей это приводило к нарушению
|
||
работоспособности системы, поэтому эта возможность сейчас вынесена
|
||
в параметр конфигурации ядра ``<tt/TUNE_1542/''. Использование
|
||
этой опции на тех системах, где она работает, может привести к
|
||
ускорению доступа к дискам, а там, где это не работает, может привести
|
||
к потере данных.
|
||
|
||
<sect1>
|
||
<heading>
|
||
Можно ли работать с current при ограниченном доступе в Internet?
|
||
<label id="ctm">
|
||
</heading>
|
||
|
||
<p>Да, это можно делать <tt/без/ скачивания полного дерева исходных
|
||
текстов с помощью <url url="../../handbook/synching.html#CTM"
|
||
name="системы CTM">.
|
||
|
||
<sect1>
|
||
<heading>Как вы разделяете дистрибутив на файлы по 240К?</heading>
|
||
|
||
<p>Команда split в современных BSD-системах имеет опцию ``<tt/-b/'',
|
||
позволяющую разрезать файлы на части с точностью до байта.
|
||
|
||
<p>Вот пример из файла <tt>/usr/src/Makefile</tt>.
|
||
|
||
<verb>
|
||
bin-tarball:
|
||
(cd ${DISTDIR}; \
|
||
tar cf - . \
|
||
gzip --no-name -9 -c | \
|
||
split -b 240640 - \
|
||
${RELEASEDIR}/tarballs/bindist/bin_tgz.)
|
||
</verb>
|
||
|
||
<sect1>
|
||
<heading>
|
||
Я написал некоторое добавление к ядру, кому его послать?
|
||
</heading>
|
||
|
||
<p>Обратитесь к соответствующему <url url="../../handbook/contrib.html"
|
||
name="разделу"> Руководства, в котором описано, как это сделать.
|
||
|
||
<p>И спасибо вам за ваши усилия!
|
||
|
||
<sect1>
|
||
<heading>
|
||
Как распознаются и инициализируются адаптеры ISA Plug N Play?
|
||
</heading>
|
||
|
||
<p>От: <url url="mailto:uhclem@nemesis.lonestar.org"
|
||
name="Фрэнка Дурды IV"> (Frank Durda IV)
|
||
|
||
<p>Если рассматривать на самом низком уровне, то существует несколько
|
||
портов ввода/вывода, в которые должны выводить информацию все адаптеры
|
||
PnP, когда компьютер пытается выполнить запрос о наличии установленных
|
||
адаптеров. Так что, когда запускается процедура определения адаптеров
|
||
PnP, она выполняет запрос о наличии каких-либо адаптеров PnP, а все
|
||
такие адаптеры выдают свой номер модели при чтении того же порта
|
||
ввода/вывода, поэтому процедура определения получит ответ на свой
|
||
запрос, состоящий из логически наложенных номеров моделей,
|
||
интерпретируемый как ``да''. В этом ответе по крайней мере один бит
|
||
будет установлен в единицу. Затем код определения адаптеров может
|
||
``выключать'' адаптеры с ID (назначаемыми Microsoft/Intel), меньшими,
|
||
чем X. Потом следует попытка определить, остались ли ещё адаптеры,
|
||
отвечающие на запрос. Если ответ ``<tt/0/'', то адаптеров с
|
||
ID, большими чем X, нет. После этого делается попытка определить
|
||
наличие адаптеров с номерами, меньшими чем ``X''. Если они есть,
|
||
то становится известно, что есть адаптеры с номерами, меньшими чем X.
|
||
Тогда происходит запрос адаптерам, большим чем X-(limit-4), на
|
||
выключение. Запрос повторяется. Применив этот метод полудвоичного
|
||
поиска границ расположения ID достаточное количество раз, код
|
||
идентификации найдёт все адаптеры PnP, установленные в данной машине
|
||
за число итераций, гораздо меньшее, чем может занять перебор 2^64
|
||
возможных вариантов ID.
|
||
|
||
<p>ID представляет собой два 32-разрядные числа (всего их 2ˆ64)
|
||
+ 8 бит контрольной суммы. Первые 32 бита являются идентификатором
|
||
производителя. Они никогда не сообщаются, однако часто бывает, что
|
||
различные типы адаптеров от одного и того же производителя имеют
|
||
различные 32-битные значения идентификатора производителя.
|
||
Необходимость в 32 разрядах только для задания производителя адаптера
|
||
выглядит несколько излишним.
|
||
|
||
<p>Оставшиеся 32 бита являются серийным номером, ethernet-адресом,
|
||
чем-либо, делающим этот адаптер уникальным. Производитель не должен
|
||
выпускать других адаптеров, имеющих то же самое значение этих битов,
|
||
если, конечно, у них не разные идентификаторы производителя. Таким
|
||
образом, вы можете иметь несколько адаптеров одинакового типа, но с
|
||
различными 64-разрядными номерами.
|
||
|
||
<p>Группы по 32 бита не богут быть нулевыми. Это позволяет при
|
||
логическом объединении OR их номеров получать ненулевое значение во
|
||
время начального поиска адаптеров.
|
||
|
||
<p>Как только система определила ID всех адаптеров, она активизирует
|
||
каждый адаптер, по одному за раз (через те же порты ввода/вывода), и
|
||
определяет, какие ресурсы требуются данному адаптеру, какие возможные
|
||
прерывания доступны итд. Сканирование и сбор информации происходит
|
||
по всем адаптерам.
|
||
|
||
<p>Эта информация соотносится с содержащейся в файлах ECU на диске
|
||
или в MLB BIOS. Поддержка PnP из ECU и BIOS для аппаратуры на
|
||
MLB обычно имеет синтетический характер, и периферия не выполняет
|
||
полностью поцедуру настоящего PnP. Однако, используя BIOS и
|
||
информацию из ECU, процедура инициализации может обнаружить устройства
|
||
PnP, которые не могут быть найдены другим способом.
|
||
|
||
<p>Затем устройства PnP опрашиваются ещё раз для назначения им портов
|
||
ввода/вывода, DMA, IRQ и адресов отображаемой памяти. Теперь
|
||
устройства должны иметь именно такие настройки и они должны оставаться
|
||
такими до следующей перезагрузки, хотя нигде не сказано, что вы не
|
||
можете их менять, когда захотите.
|
||
|
||
<p>Здесь сделано много упрощений, однако общую идею вы должны уловить.
|
||
|
||
<p>Microsoft использовала для PnP некоторые порты статуса первого
|
||
принтера, по их логике, не существует адаптеров, использующих эти
|
||
адреса для ввода/вывода. Я обнаружил один такой адаптер принтера от
|
||
IBM, который декодирует запись в порт статуса в момент начального
|
||
опроса устройств PnP, на что MS ответил ``хулиган''. Так что они
|
||
выполняют запись в порт статуса принтера для установки адресов,
|
||
плюс используют этот адрес + <tt/0x800/, и ещё один порт ввода/вывода,
|
||
который может располагаться где угодно в диапазоне между <tt/0x200/ и
|
||
<tt/0x3ff/, для чтения.
|
||
|
||
<sect1>
|
||
<heading>Поддерживает ли FreeBSD платформы, отличные от x86?</heading>
|
||
|
||
<p>Интерес к работе над многоплатформенной поддержкой во FreeBSD
|
||
проявили несколько групп разработчиков, и одна из попыток переноса,
|
||
FreeBSD/AXP (ALPHA), оказавшейся достаточно удачной, в настоящее
|
||
время доступна в виде релиза 3.0 SNAP по адресу <url
|
||
url="ftp://ftp.freebsd.org/pub/FreeBSD/alpha/"
|
||
name="ftp://ftp.freebsd.org/pub/FreeBSD/alpha">. Эта реализация
|
||
для ALPHA сейчас поддерживаёт всё увеличивающееся число машин ALPHA,
|
||
в частности, модели AlphaStation, AXPpci, PC164, Miata и Multia.
|
||
Нельзя сказать, что это настоящий релиз, он и не будет полным,
|
||
пока в него не будут включены все утилиты для инсталляции и не
|
||
будет сделан дистрибутивный CDROM, включающий достаточное количество
|
||
рабочих портов и пакаджей. FreeBSD/AXP сейчас находится в стадии
|
||
BETA. Чтобы быть в курсе событий, происходящих с этим портом,
|
||
подпишитесь на соответствующий
|
||
<tt><freebsd-alpha@FreeBSD.ORG></tt><ref id="mailing"
|
||
name="список рассылки">.
|
||
|
||
Также был проявлен интерес к переносу FreeBSD на платформу SPARC,
|
||
если вы хотите подключиться к этому проекту, подпишитесь на
|
||
соответствующий <tt><freebsd-sparc@FreeBSD.ORG></tt>
|
||
<ref id="mailing" name="список рассылки">. Для обсуждение общих
|
||
вопросов, касающихся новых аппаратных платформ, предназначен <ref
|
||
id="mailing" name="список рассылки">
|
||
<tt><freebsd-platforms@FreeBSD.ORG></tt>.
|
||
|
||
<sect1>
|
||
<heading>
|
||
Мне нужно старшее число для написанного мною драйвера устройства.
|
||
</heading>
|
||
|
||
<p>Всё зависит от того, планируете вы сделать этот драйвер
|
||
общедоступным или нет. Если это так, то, пожалуйста, пошлите нам
|
||
копию исходных текстов драйвера вместе с соответствующими
|
||
модификациями в файле <tt>files.i386</tt>, пример описания устройства
|
||
в файле конфигурации ядра и соответствующий код
|
||
<htmlurl url="http://www.freebsd.org/cgi/man.cgi?MAKEDEV"
|
||
name="MAKEDEV"> для создания специальных файлов устройств, которые
|
||
использует ваше устройство. Если это не так. или это невозможно
|
||
из-за лицензионных ограничений, то для старшего числа символьного
|
||
устройства и старшего числа блочного устройства для этих целей были
|
||
зарезервированы значения 32 и 8 соответственно; используйте их. В
|
||
любом случае. мы будем рады услышать о вашем драйвере в списке
|
||
рассылки <tt><freebsd-hackers@FreeBSD.ORG></tt>.
|
||
|
||
<sect1>
|
||
<heading>Альтернативный метод размещения каталогов</heading>
|
||
|
||
<p>В ответ на вопрос о других методах размещения каталогов могу
|
||
сказать, что используемая в настоящее схема не претерпела изменений
|
||
с 1983 года. Эти соглашения были предназначены для оригинальной
|
||
файловой системы FFS, я никогда их не пересматривал. Эта схема
|
||
прекрасно работает, позволяя избежать переполнения групп дорожек.
|
||
Как некоторые из вас замечали, она работает плохо при поиске.
|
||
Большинство файловых систем создаются из архивов, которые были
|
||
созданы с глубиной первого поиска (aka ftw). Это приводит к тому, что
|
||
их каталоги размещаются на нескольких группах дорожек, создавая
|
||
наихудший случай для последующего поиска глубиной один. Если бы
|
||
было известно общее количество каталогов, которые должны быть созданы,
|
||
быходом было бы создание (общее количество / количество групп дорожек)
|
||
на дорожку группу перед переходом. Обычно это число определяется чисто
|
||
эвристически. Даже при использовании маленького фиксированное числа,
|
||
скажем 10, значительно улучшает ситуацию. Чтобы различать операции
|
||
восстановления от обычных операций (где текущий алгоритм подходит),
|
||
вы можете использовать объединение в кластеры объёмом до 10, если они
|
||
делаются в окне, равным 10 секундам. Во всяком случае, я думаю, что
|
||
это требует некоторых экспериментов.</p>
|
||
|
||
<p>Кирк МакКузик (Kirk McKusick), Сентябрь 1998</p>
|
||
|
||
<sect1>
|
||
<heading>Что делать при аварийном остановах системы</heading>
|
||
|
||
<p>
|
||
<em>[Этот раздел был вырезан из письма, написанного <url
|
||
url="mailto:wpaul@FreeBSD.ORG" name="Биллом Полом"> (Bill Paul)
|
||
в список рассылки <ref id="mailing" name="список рассылки">
|
||
freebsd-current <url url="mailto:des@FreeBSD.ORG"
|
||
name="Дэгом-Элингом Коиданом Смёгравом"> (Dag-Erling Coïdan
|
||
Smørgrav), который исправил несколько опечаток и добавил
|
||
комментарии в квадратных скобках]</em>
|
||
|
||
<p>
|
||
<verb>
|
||
From: Bill Paul <wpaul@skynet.ctr.columbia.edu>
|
||
Subject: Re: the fs fun never stops
|
||
To: ben@rosengart.com
|
||
Date: Sun, 20 Sep 1998 15:22:50 -0400 (EDT)
|
||
Cc: current@FreeBSD.ORG
|
||
</verb>
|
||
|
||
<p>
|
||
<em>[<ben@rosengart.com> отправил письмо, содержащее следующее
|
||
аварийное сообщение системы]</em>
|
||
<verb>
|
||
> Fatal trap 12: page fault while in kernel mode
|
||
> fault virtual address = 0x40
|
||
> fault code = supervisor read, page not present
|
||
> instruction pointer = 0x8:0xf014a7e5
|
||
^^^^^^^^^^
|
||
> stack pointer = 0x10:0xf4ed6f24
|
||
> frame pointer = 0x10:0xf4ed6f28
|
||
> code segment = base 0x0, limit 0xfffff, type 0x1b
|
||
> = DPL 0, pres 1, def32 1, gran 1
|
||
> processor eflags = interrupt enabled, resume, IOPL = 0
|
||
> current process = 80 (mount)
|
||
> interrupt mask =
|
||
> trap number = 12
|
||
> panic: page fault
|
||
</verb>
|
||
|
||
<p>[Если] вы увидите такое сообщение, просто его воспроизвести и
|
||
послать нам не достаточно. Указатель инструкций, выделенный мною,
|
||
важен, к сожалению, его значение зависит от конфигурации ядра.
|
||
Другими словами, его значение меняется в зависимости от конкретного
|
||
ядра, которое вы используете. Если вы используете ядро GENERIC
|
||
одного из снэпшотов, то кто-то ещё может отследить функцию, вызвавшую
|
||
ошибку, но если вы работаете со специально отконфигурированным ядром,
|
||
то только <em/вы/ можете сказать нам, где случилась ошибка.
|
||
|
||
<p>Вот что вы должны сделать:
|
||
|
||
<itemize>
|
||
<item>Запишите значение указателя инструкций. Заметьте, что
|
||
часть <tt/0x8:/ в этом случае не важна: нам нужна часть
|
||
<tt/0xf0xxxxxx/.
|
||
|
||
<item>Когда система перезагрузится, сделайте следующее:
|
||
<verb>
|
||
% nm /kernel.that.caused.the.panic | grep f0xxxxxx
|
||
</verb>
|
||
где <tt/f0xxxxxx/ - это значение указателя инструкций. Однако
|
||
неприятность заключается в том, что вы не получите точного
|
||
соответствия, так как в таблице имен ядра для точек входа в функции
|
||
даны адреса на начало функций, а указатель инструкций будет указывать
|
||
куда-то внутрь её тела. Если вы не получили точного соответствия,
|
||
опустите последнюю цифру в значении указателя инструкций и попробуйте
|
||
снова, то есть:
|
||
<verb>
|
||
% nm /kernel.that.caused.the.panic | grep f0xxxxx
|
||
</verb>
|
||
Если и это не привело ни к каким результатам, отрежьте следующую
|
||
цифру. Повторяйте, пока не получите хоть что-то. Результатом будет
|
||
список функций, которые, возможно, привели к аварийному останову.
|
||
Этот механизм обнаружения ошибочного места довольно неточен, но это
|
||
всё же лучше чем ничего.
|
||
</itemize>
|
||
|
||
<p>Зачастую люди приводят подобные аварийные сообщения, на редко кто
|
||
утруждается привести соотвествие указателя инструкций с функцией в
|
||
таблице символов ядра.
|
||
|
||
<p>Лучшим способом выяснить причину, вызвавшую аварийный останов,
|
||
является создание аварийного дампа системы, а затем использование
|
||
<tt/gdb(1)/ для трассировки вызовов. Конечно, это зависит
|
||
от корректности работы <tt/gdb(1)/ с -current, что я гарантировать не
|
||
могу (помнится, кто-то говорил, что новый ELF <tt/gdb(1)/ некорректно
|
||
работает с аварийными дампами ядра: необходимо проверить это
|
||
до выхода 3.0, иначе не избежать краски стыда на наших лицах
|
||
после выпуска CD).
|
||
|
||
<p>Во всяком случае, обычно я использую такой способ:
|
||
|
||
<itemize>
|
||
<item>Отредактируйте конфигурационный файл ядра, добавив строку
|
||
'options DDB', если вам зачем-то понадобился встроенный отладчик.
|
||
(Я использую его в основном для указания точек останова, если
|
||
подозреваю возникновение бесконечных циклов.)
|
||
<item>Выполните <tt/config -g KERNELCONFIG/ для создания каталога
|
||
построения ядра.
|
||
<item><tt>cd /sys/compile/KERNELCONFIG; make</tt>
|
||
<item>Дождитесь окончания компиляции ядра.
|
||
<item><tt/cp kernel kernel.debug/
|
||
<item><tt/strip -d kernel/
|
||
<item><tt/mv /kernel /kernel.orig/
|
||
<item><tt>cp kernel /</tt>
|
||
<item>reboot
|
||
</itemize>
|
||
|
||
<p><em>[Замечание: Так как теперь ядра FreeBSD 3.x по умолчанию
|
||
имеют формат Elf, вы должны использовать команду <tt/strip -g/
|
||
вместо <tt/strip -d/]. Если по какой-то причине ваше ядро всё ещё
|
||
имеет формат a.out, используйте команду <tt/strip -aout -d/.]</em>
|
||
|
||
<p>Заметьте, что ВАМ <em/НЕ/ НУЖНО ЗАГРУЖАТЬ ЯДРО С ОТЛАДОЧНОЙ
|
||
ИНФОРМАЦИЕЙ. Ядро, откомпилированное с ключом <tt/-g/, может
|
||
занимать порядка 10МБ. Вам не нужно загружать этот огромный образ:
|
||
он вам пригодится позже для <tt/gdb(1)/ (а <tt/gdb(1)/ требует
|
||
таблицу имён). Вместо этого просто сохраните полный образ и создайте
|
||
ещё один, удалив отладочную информацию командой <tt/strip -d/. Именно
|
||
этот образ вам и нужен для загрузки.
|
||
|
||
<p>Чтобы включить сброс аварийного дампа, вам нужно отредактировать
|
||
файла <tt>/etc/rc.conf</tt>, чтобы <tt/dumpdev/ указывало на раздел
|
||
подкачки. В этом случае скрипты <tt/rc(8)/ будут вызывать команду
|
||
<tt/dumpon(8)/ для включения создания аварийных дампов. Вы можете
|
||
запустить команду <tt/dumpon(8)/ вручную. После аварийной остановки
|
||
аварийный дамп может быть получен с помощью программы
|
||
<tt/savecore(8)/; если значение переменной <tt/dumpdev/ было
|
||
установлено в <tt>/etc/rc.conf</tt>, скрипты <tt/rc(8)/ запустят
|
||
<tt/savecore(8)/ автоматически и поместят аварийный дамп в каталог
|
||
<tt>/var/crash</tt>.
|
||
|
||
<p>ЗАМЕЧАНИЕ: аварийные дампы FreeBSD обычно имеют размер, равный
|
||
физическому объёму оперативной памяти вашей машины. Так что если
|
||
у вас 64МБ ОЗУ, вы получите дамп размером 64МБ. Поэтому вы должны
|
||
удостовериться, что в каталоге <tt>/var/crash</tt> достаточно места
|
||
для хранения дампа. Либо вы можете вручную запустить <tt/savecore(8)/
|
||
и создать аварийный дамп в другом каталоге, где достаточно места.
|
||
Размер аварийного дампа можно уменьшить, указав в конфигурации
|
||
ядра <tt/options MAXMEM=(размер)/ подходящее значение для объёма
|
||
памяти, которое будет использоваться ядром. Например, если у вас
|
||
128 МБ ОЗУ, вы можете ограничить использование памяти ядром 16
|
||
мегабайтами, так что размер аварийного дампа будет равен 16МБ, а
|
||
не 128.
|
||
|
||
<p>Как только вы получили аварийный дамп, вы можете выполнить
|
||
трассировку вызовов с помощью <tt/gdb(1)/ таким образом:
|
||
|
||
<p>
|
||
<verb>
|
||
% gdb -k /sys/compile/KERNELCONFIG/kernel.debug /var/crash/vmcore.0
|
||
(gdb) where
|
||
</verb>
|
||
|
||
<p>Заметьте, что при этом может быть выведено несколько экранов
|
||
информации; в идеале вы должны использовать <tt/script(1)/ для их
|
||
перехвата. При использовании необработанного образа ядра со всей
|
||
отладочной информацией может быть найдена конкретная строка исходного
|
||
текста ядра, при достижении которой случилась аварийная остановка.
|
||
Для выяснения последовательности событий, приведших к аварийному
|
||
останову, обычно читается трассировка стека снизу вверх. Вы можете
|
||
также использовать <tt/gdb(1)/ для вывода значений различных переменных
|
||
или структур, чтобы выяснить состояние системы во время аварии.
|
||
|
||
<p>Теперь, если вы в самом деле душевнобольной и у вас есть второй
|
||
компьютер, то можете настроить <tt/gdb(1)/ для удалённой отладки, так,
|
||
что сможете использовать <tt/gdb(1)/ на одном компьютере, чтобы
|
||
отладить ядро на другом, включая использование точек останова,
|
||
пошагового прохода по коду ядра, всё как с обычной прикладной
|
||
программой. Я пока с этим не игрался, так как не часто имею
|
||
возможность поставить две машины одну напротив другой для отладки.
|
||
|
||
<p><em>[Билл (Bill) добавил: "Я забыл обратить ваше внимание
|
||
на одну вещь: если у вас включена поддержка DDB и ядро переходит
|
||
в режим отладки, вы можете намеренно вызвать аварийный останов
|
||
(и создание аварийного дампа), набрав 'panic' в командной строке
|
||
ddb. Этот процесс может снова вызвать отладчик. В этом случае
|
||
наберите 'continue' и процесс будет завершён созданием аварийного
|
||
дампа." -ed]</em>
|
||
|
||
<sect1>
|
||
<heading>Перестала работать функция dlsym() для ELF!</heading>
|
||
|
||
<p>По умолчанию при работе с форматом ELF символы, определённые в
|
||
выполнимом файле, не доступны динамическому загрузчику. Поэтому
|
||
при вызове функции <tt>dlsym()</tt>, которая осуществляет поиск по
|
||
дескриптору, полученному после вызова <tt>dlopen(NULL, flags)</tt>,
|
||
желаемый результат достигнут не будет.
|
||
|
||
<p>Если вы хотите осуществить поиск в выполнимом файле процесса с
|
||
помощью функции <tt>dlsym()</tt>, вам нужно компоновать выполнимый
|
||
файл с опцией <tt>-export-dynamic</tt> <htmlurl
|
||
url="http://www.freebsd.org/cgi/man.cgi?ld" name="компоновщика ELF">.
|
||
|
||
<sect1>
|
||
<heading>Увеличение и уменьшение адресного пространства ядра</heading>
|
||
|
||
<p>По умолчанию размер адресного пространства ядра равен 256 МБ во
|
||
FreeBSD 3.x и 1 ГБ во FreeBSD 4.x. Если вы используете FreeBSD
|
||
в качестве сервера с интенсивной сетевой нагрузкой (скажем,
|
||
большой FTP или HTTP сервер), вы можете обнаружить, что 256 МБ
|
||
недостаточно.
|
||
|
||
<p>Каким же образом можно увеличить адресное пространство? Здесь
|
||
есть два момента. Во-первых, вам нужно указать ядру выделить
|
||
большее количество адресного пространства для самого ядра. Во-вторых,
|
||
так как ядро загружается в верхнюю часть адресного пространства, вам
|
||
нужно уменьшить адрес загрузки так, чтобы он не вышел за верхнюю
|
||
границу.
|
||
|
||
<p>Первая проблема решается увеличением значения константы
|
||
<tt/NKPDE/ в файле <tt>src/sys/i386/include/pmap.h</tt>. В случае 1
|
||
ГБ адресного пространства он должен выглядеть примерно так:
|
||
|
||
<verb>
|
||
#ifndef NKPDE
|
||
#ifdef SMP
|
||
#define NKPDE 254 /* addressable number of page tables/pde's */
|
||
#else
|
||
#define NKPDE 255 /* addressable number of page tables/pde's */
|
||
#endif /* SMP */
|
||
#endif
|
||
</verb>
|
||
|
||
<p>Для вычисления значения <tt/NKPDE/ разделите желаемый объём
|
||
адресного пространства (в мегабайтах) на четыре и вычтите из
|
||
получившегося числа единичку в случае однопроцессорной машины и
|
||
двоечку в случае многопроцессорного ядра.
|
||
|
||
<p>Для достижения второй цели вам нужно правильный адрес для загрузки
|
||
ядра: просто отнимите размер адресного пространства (в байтах) от
|
||
0x100100000; результат будет равным 0xc0100000 для адресного
|
||
пространства в 1 ГБ. Установите значение константы <tt/LOAD_ADDRESS/
|
||
в файле <tt>src/sys/i386/conf/Makefile.i386</tt> в это значение; затем
|
||
установите значение счётчика в начале списка секций в то же самое
|
||
значение, как это сделано здесь:
|
||
|
||
<verb>
|
||
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
|
||
OUTPUT_ARCH(i386)
|
||
ENTRY(btext)
|
||
SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/obj/elf/home/src/tmp/usr/i386-unknown-freebsdelf/lib);
|
||
SECTIONS
|
||
{
|
||
/* Read-only sections, merged into text segment: */
|
||
. = 0xc0100000 + SIZEOF_HEADERS;
|
||
.interp : { *(.interp) }
|
||
</verb>
|
||
|
||
<p>После этого переконфигурируйте и перестройте ядро. Вы можете
|
||
столкнуться с проблемами при работе утилит <tt/ps(1)/, <tt/top(1)/
|
||
и подобных им; решить их может <tt/make world/ (или ручная
|
||
перекомпиляция <tt/libkvm/, <tt/ps/ и <tt/top/ после копирования
|
||
исправленного <tt/pmap.h/ в <tt>/usr/include/vm/)</tt>.
|
||
|
||
<p>ЗАМЕЧАНИЕ: Размер адресного пространства ядра должен быть
|
||
кратен четырём мегабайтам.
|
||
|
||
<p>[<url url="mailto:dg@freebsd.org" name="Дэвид Гринмэн">
|
||
(David Greenman) добавил: <em> Я думаю, что размер адресного
|
||
пространства ядра должен быть степенью двойки, но я в этом не уверен.
|
||
Для работы с верхними адресами памяти использовался код старого
|
||
загрузчика, и я ожидаю по крайней мере точность в 256 МБ.]</em>
|
||
|
||
</sect>
|