<!--
     The FreeBSD Russian Documentation Project

     $FreeBSD: doc/ru_RU.KOI8-R/books/handbook/kernelopts/chapter.sgml,v 1.2 2001/03/11 16:45:02 phantom Exp $
     $FreeBSDru: frdp/doc/ru_RU.KOI8-R/books/handbook/kernelopts/chapter.sgml,v 1.2 2000/11/10 11:55:24 phantom Exp $
-->

<chapter id="kernelopts">
  <title>Добавление новых параметров конфигурации ядра</title>

  <para><emphasis>Предоставил &a.joerg;</emphasis></para>

  <note>
    <para>Перед тем, как читать этот раздел, вы должны усвоить материал
      раздела о <link linkend="kernelconfig">конфигурации ядра</link>.</para>
  </note>

  <sect1>
    <title>Что же такое <emphasis>параметр ядра</emphasis>, в конце
      концов?</title>

    <para>Использование параметров ядра в основном описано в разделе о <link
      linkend="kernelconfig-options">конфигурации ядра</link>.	Там же
      имеется описание <quote>устаревших</quote> и параметров <quote>в новом
      стиле</quote>.  Конечной целью является постепенный перевод всех
      поддерживаемых параметров ядра к новому стилю, так чтобы для тех, кто
      корректно выполняют команду <command>make depend</command> в каталоге
      компиляции ядра после запуска &man.config.8;, процесс построения
      автоматически принимал модифицированные параметры и
      перекомпилировал только те файлы, которые необходимы.  Удаление старого
      каталога компиляции при каждом перезапуске &man.config.8;, как это
      еще происходит сейчас, затем может быть убрано.</para>

    <para>В своей основе параметр ядра является не более чем определение
      макроса препроцессора C для процесса компиляции ядра.  Чтобы сделать
      построение полностью настраиваемым через опции процессом,
      соответствующая часть исходных текстов ядра (или файла
      <filename>.h</filename> ядра) должна быть написана с упором на
      концепцию параметров, то есть чтобы значения, используемые по
      умолчанию, могли быть переопределены параметрами конфигурации.  Это
      обычно делается примерно так:</para>

    <programlisting>
#ifndef THIS_OPTION
#define THIS_OPTION (некоторое значение по умолчанию)
#endif /* THIS_OPTION */
    </programlisting>

    <para>Этим способом администратор, задающий другое значение для параметра
      в своем конфигурационном файле, избегает использования значения по
      умолчанию и заменяет его новым значением.  Более того, новое значение
      будет подставлено в исходный код во время работы препроцессора, так что
      это должно быть правильное выражение языка C в контексте использования
      значения по умолчанию.</para>

    <para>Также возможно создание параметров, которые не принимают
      определенного значения, а просто включают или выключают некоторую часть
      кода, обрамляя его в</para>

    <programlisting>
#ifdef THAT_OPTION

[здесь ваш код]

#endif
    </programlisting>

    <para>Простое упоминание <literal>THAT_OPTION</literal> в
      конфигурационном файле (со значением или без него) приведет к включению
      соответствующего кода.</para>

    <para>Те, кто знаком с языком C, могут сказать, что все может считаться
      как <quote>config option</quote>, там где есть по крайней мере одна
      строчка <literal>#ifdef</literal>...  Однако вряд ли многие будут
      писать</para>

    <programlisting>
options 	notyet,notdef
    </programlisting>

    <para>в своих конфигурационных файлах и потом удивляться, почему
      компиляция ядра не проходит.  <!-- smiley -->:-)</para>

    <para>Более точно, использование уникальных имен для параметров делает
      очень трудным отслеживание их использования в дереве исходных текстов
      ядра.  В использовании схемы параметров в <emphasis>новом
      стиле</emphasis> имеется рациональное зерно, когда каждый параметр
      помещается в отдельный файл <filename>.h</filename> в каталоге
      компиляции ядра, который по соглашению называется
      <filename>opt_<replaceable>foo</replaceable>.h</filename>.  Таким
      образом, могут быть применены обычные зависимости в Makefile, и утилита
      <command>make</command> может определить, что нужно перекомпилировать
      при изменении определенного параметра.</para>

    <para>Параметры при использовании механизма в старом стиле имеют одно
      преимущество для локальных изменений или для экспериментальных
      параметров, которые имеют короткий срок жизни: так как весьма легко
      добавить новую строку <literal>#ifdef</literal> к исходному коду ядра,
      то это уже превращается в параметр конфигурации ядра.  В таком случае
      администратор, использующий параметры таким образом, несет
      ответственность за знание влияния этого параметра (и может быть, за
      принудительную перекомпиляцию вручную частей ядра).  Как только перевод
      всех поддерживаемых опций будет сделан, программа &man.config.8; будет
      выдавать предупреждение о не поддерживаемой опции, появившейся в
      конфигурационном файле, однако она будет включать ее в файл Makefile
      ядра.</para>
  </sect1>

  <sect1>
    <title>И что я должен для этого сделать?</title>

    <para>Во-первых, отредактируйте файл
      <filename>sys/conf/options</filename> (или
      <filename>sys/<replaceable>&lt;arch&gt;</replaceable>/conf/options.<replaceable>&lt;arch&gt;</replaceable></filename>,
      например <filename>sys/i386/conf/options.i386</filename>), и выберите
      файл <filename>opt_<replaceable>foo</replaceable>.h</filename>,
      в котором лучше всего поместить вашу новую опцию.</para>

    <para>Если имеется что-то, уже похожее на предназначение новой опции,
      выберите это.  Например, опции, изменяющие общее поведение подсистемы
      SCSI, могут быть помещены в
      <filename>opt_scsi.h</filename>.	По умолчанию простое упоминание опции
      в соответствующем файле опций, скажем, <literal>FOO</literal>, приводит
      к тому, что ее значение помещается в соответствующий файл
      <filename>opt_foo.h</filename>.  Это может быть переопределено в
      правой части правила указанием другого имени файла.</para>

    <para>Если файла
      <filename>opt_<replaceable>foo</replaceable>.h</filename> для
      предполагаемой новой опции еще нет, придумайте новое имя.  Сделайте его
      значимым и прокомментируйте новый раздел в файле
      <filename>options[<replaceable>.&lt;arch&gt;</replaceable>]</filename>.
      Утилита &man.config.8; автоматически воспримет изменения и создаст
      этот файл при следующем своем запуске.  Большинство опций должно
      оказаться в заголовочном файле..</para>

    <para>Размещение слишком большого количества опций в одном файле
      <filename>opt_<replaceable>foo</replaceable>.h</filename> приведет к
      перестроению слишком большого количества файлов ядра при изменении
      одной из опций в конфигурационном файле.</para>

    <para>Наконец, определите, какие файлы ядра зависят от новой опции.  Если
      только вы не только что придумали вашу опцию и она еще нигде не
      упоминается, то команда
      <screen>
&prompt.user; <userinput>find /usr/src/sys -type f | xargs fgrep NEW_OPTION</userinput>
      </screen>
      вам поможет ее найти.  Сделайте это и отредактируйте все эти файлы, а
      также добавьте <programlisting>#include "opt_foo.h"</programlisting>
      <emphasis>вверху</emphasis> до всех строк
      <literal>#include &lt;xxx.h&gt;</literal>.  Эта последовательность
      очень важна, так как опции могут переопределять значения по умолчанию
      из обычных включаемых файлов, если эти значения по умолчанию даются в
      форме <programlisting> #ifndef NEW_OPTION #define NEW_OPTION (что-то)
      #endif</programlisting> в обычном заголовке.</para>

    <para>Добавление опции, которая переопределяет что-то в системном
      заголовочном файле (то есть файле, находящемся в каталоге
      <filename>/usr/include/sys/</filename>), практически всегда ошибочно.
      <filename>opt_<replaceable>foo</replaceable>.h</filename> не может быть
      включен в те файлы, потому что это изменит заголовки более серьезно,
      но если он не включен, то в местах его включения может получиться
      рассогласованность значений для этой опции.  Да, такие прецеденты имеют
      место и сейчас, но это их не оправдывает.</para>
  </sect1>
</chapter>

<!--
     Local Variables:
     mode: sgml
     sgml-declaration: "../chapter.decl"
     sgml-indent-data: t
     sgml-omittag: nil
     sgml-always-quote-attributes: t
     sgml-parent-document: ("../book.sgml" "part" "chapter")
     End:
-->