<!--
     The FreeBSD Documentation Project

     $FreeBSD$
-->

<chapter id="kernelopts">
  <title>A&ntilde;adir nuevas opciones de configuraci&oacute;n al kernel</title>
  
  <para><emphasis>Contribuci&acute;n de &a.joerg;</emphasis></para>
  
  <note>
    <para>Antes de leer esta secci&oacute;n se debe estar familiarizado con
        la secci&oacute;n sobre <link linkend="kernelconfig">configuraci&oacute;n 
        del kernel</link>.</para>
  </note>
  
  <sect1>
    <title>Ante todo &iquest;Qu&eacute; es una <emphasis>opci&oacute;n del 
      kernel</emphasis>?</title>
    
    <para>El uso de opciones del kernel se describe b&aacute;sicamente en la secci&oacute;n
      <link linkend="kernelconfig-options">configuraci&oacute;n del kernel</link>.
      Tambi&eacute;n hay una discusi&oacute;n sobre opciones &ldquo;estilo historico&rdquo; y
      &ldquo;estilo moderno&rdquo;.   El objetivo final es que en alg&uacute;n momento
      todas las opciones soportadas por el kernel se hayan convertido al estilo
      moderno, as&iacute; para la gente que hizo un <command>make depend</command> exitoso
      en su directorio de compilaci&oacute;n del kernel luego de correr &man.config.8;,
      el proceso de build automaticamente seleccionar&aacute; las opciones modificadas y
      solo recompilara los archivos donde se usan.  El paso de eliminar el viejo
      directorio de compilaci&oacute;n cada vez que se corre &man.config.8; como a&uacute;n se
      hace podr&aacute; entonces ser eliminado nuevamente.</para>

    <para>B&aacute;sicamente una opci&oacute;n del kernel no es m&aacute;s que la definici&oacute;n de una
      macro del preprocesador C para el proceso de compilaci&oacute;n del kernel. Para
      hacer la compilaci&oacute;n verdaderamente opcional, la parte correspondiente del
      c&oacute;digo fuente del kernel (o archivo <filename>.h</filename> del kernel) debe estar
      escrita con el concepto de opci&oacute;n en mente, por ejemplo el default para la opci&oacute;n
      debe haber sido hecho modificable. Esto se hace generalmente con algo como:</para>

	<programlisting>
#ifndef THIS_OPTION
#define THIS_OPTION (valor_por_default)
#endif /* THIS_OPTION */</programlisting>
	
    <para>De esta manera, un administrador seleccionando otro valor para la opci&oacute;n
      en su archivo de configuraci&oacute;n dejar&aacute; sin efecto el default, y lo reemplazar&aacute;
      con su nuevo valor. Como es claro, el nuevo valor ser&aacute; sustituido en el c&oacute;digo
      fuente durante la ejecuci&oacute;n del preprocesador, por lo que debe ser una
      expresi&oacute;n C v&aacute;lida en el contexto en el que habr&iacute;a sido usado el default.
    </para>
	
    <para>Tambi&eacute;n es posible crear opciones sin valor que simplemente activen o
      desactiven una parte del c&oacute;digo rodeandola con</para>
	
    <programlisting>
#ifdef THAT_OPTION

[c&oacute;digo fuente espec&iacute;fico]

#endif</programlisting>
	
    <para>Con solo mencionar <literal>THAT_OPTION</literal> en el archivo de
      configuraci&oacute;n (con o sin valor) activar&aacute; la parte del c&oacute;digo correspondiente.</para>
	
    <para>Quien est&eacute; familiarizado con el lenguaje C se dar&aacute; cuenta de que todo
      podr&iacute;a ser tratado como una &ldquo;opci&oacute;n de configuraci&oacute;n&rdquo; si hay
      por lo menos un <literal>#ifdef</literal> referenciandolo...
      De todos modos, es poco probable que mucha gente ponga</para>
	
    <programlisting>
options		notyet,notdef</programlisting>
	
    <para>en su archivo de configuraci&oacute;n, y luego se pregunten por que la kernel
      compilation les da errores.  <!-- smiley -->:-)</para>
	
    <para>Como es claro, usar nombres arbitrarios para las opciones hace que sea
      muy dif&iacute;cil rastrear su uso por todo el &aacute;rbol de c&oacute;digo fuente. Esa es la
      raz&oacute;n que impulsa el esquema de opciones <emphasis>estilo-moderno</emphasis>,
      donde cada opci&oacute;n va en un archivo <filename>.h</filename> separado en el
      directorio de compilaci&oacute;n del kernel, el cual por convenci&oacute;n se llamar&aacute;
      <filename>opt_<replaceable>foo</replaceable>.h</filename>.  De esta forma
      las dependencias usuales del Makefile pueden aplicarse, y el <command>make
      </command> puede determinar que se necesita recompilar cuando una opci&oacute;n fue
      cambiada.</para>
	
    <para>El mecanismo de opciones estilo antiguo tiene a&uacute;n una ventaja para
      opciones locales o tal vez experimentales que tendr&aacute;n por anticipado poco
      tiempo de vida: ya que es facil agregar un nuevo <literal>#ifdef</literal>
      al c&oacute;digo fuente del kernel, esto ya lo ha convertido en una opci&oacute;n de
      configuraci&oacute;n. En este caso el administrador que use tal opci&oacute;n es responsable
      de conocer sus implicaciones ( y tal vez forzar la recompilaci&oacute;n de partes
      del kernel a mano). Una vez que la tansici&oacute;n de todas las opciones soportadas
      haya sido hecha, &man.config.8; advertir&aacute; cuando aparezca una opci&oacute;n no
      soportada en el archivo de configuraci&oacute;n, pero sin embargo la incluir&aacute; en
      el Makefile del kernel.</para>
  </sect1>
  
  <sect1>
    <title>Y ahora ¿Qu&eacute; debo hacer para eso?</title>
    
    <para>Primero, edite <filename>sys/conf/options</filename> (o
      <filename>sys/i386/conf/options.<replaceable>&lt;arq&gt;</replaceable></filename>,
      Ej: <filename>sys/i386/conf/options.i386</filename>), y seleccione un archivo
      <filename>opt_<replaceable>foo</replaceable>.h</filename> donde
      su nueva opci&oacute;n cabr&iacute;a mejor.</para>
	
    <para>Si ya hay algo que se acerque al proposito de la nueva opci&oacute;n, elijalo.
      Por ejemplo, las opciones que modifican la conducta general del subsistema
      SCSI pueden ir dentro de <filename>opt_scsi.h</filename>. Por default,
      con solo mencionar una opci&oacute;n en el archivo de opciones apropiado,
      digamos <literal>FOO</literal>, implica que su valor ir&aacute; dentro del
      archivo correspondiente <filename>opt_foo.h</filename>. Esto puede ser
      reemplazado en el lado derecho de una regla especificando otro nombre de
      archivo.</para>
	
    <para>Si no hay ning&uacute;n
      <filename>opt_<replaceable>foo</replaceable>.h</filename> ya
      disponible para la nueva opci&oacute;n, invente un nuevo nombre. H&aacute;galo
      significativo, y comente la nueva secci&oacute;n en el archivo
      <filename>options[<replaceable>.&lt;arq&gt;</replaceable>]</filename>.
      &man.config.8; automaticamente tomar&aacute; el cambio, y crear&aacute; el archivo
      la pr&oacute;xima vez que se corra. La mayor&iacute;a de las opciones deber&iacute;an ir en
      un archivo <filename>.h</filename> individual.</para>
	
    <para>Meter demasiadas opciones en un solo archivo
      <filename>opt_<replaceable>foo</replaceable>.h</filename> causar&aacute; que
      se tengan que recompilar demasiados archivos del kernel cuando se cambie
      una de las opciones en el archivo de configuraci&oacute;n.</para>
	
    <para>Por &uacute;ltimo, averigüe que archivos del kernel dependen de la nueva
      opci&oacute;n. A menos que usted haya inventado recientemente su opci&oacute;n, y
      a&uacute;n no existe en ning&uacute;n lado <screen>&prompt.user;
      <userinput>find /usr/src/sys -name
	  type f | xargs fgrep NEW_OPTION</userinput></screen> le ser&aacute; de
      ayuda para encontrarlos. Edite todos esos archivos y agregue <programlisting>
	#include "opt_foo.h"</programlisting> <emphasis>al comienzo</emphasis>,
      antes de todos los <literal>#include &lt;xxx.h&gt;</literal>. Este
      orden es m&aacute;s importante en tanto las opciones podr&iacute;an reemplazar los
      defaults de los archivos <filename>.h</filename> regulares, si los defaults
      son de la forma <programlisting> #ifndef NEW_OPTION #define NEW_OPTION (something)
	#endif</programlisting> en el <filename>.h</filename> regular.</para>
	
    <para>Agregar una opci&oacute;n que reemplaza algo en un archivo header del sistema
      (un archivo ubicado en <filename>/usr/include/sys/</filename>) es
      casi siempre un error.
      <filename>opt_<replaceable>foo</replaceable>.h</filename> no puede ser
      incluido dentro de estos archivos dado que esto da&ntilde;ar&iacute;a al header
      muy seriamente, pero si no se incluye entonces otros lugares que lo
      incluyen podr&iacute;an tener valores inconsistentes para la opci&oacute;n. S&iacute;, hay
      precedentes de esto actualmente, pero eso no los hace m&aacute;s correctos.</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:
-->

