<!--
     The FreeBSD Documentation Project

     $FreeBSD$
-->

<chapter id="kernelopts">
  <chapterinfo>
    <authorgroup>
      <author>
	<firstname>J&ouml;rg</firstname>
	<surname>Wunsch</surname>
	<contrib>Contribuido por </contrib>
      </author>
    </authorgroup>
  </chapterinfo>

  <title>A&ntilde;adiendo Opciones a la Configuraci&oacute;n de un Nuevo Kernel</title>
  
  <note>
    <para>Es importante que antes de leer este documento, usted este
      familiarizado con la secci&oacute;n de <link
	linkend="kernelconfig">configuraci&oacute; del kernel</link>.</para>
  </note>
  
  <sect1>
    <title>&iquest;Qu&eacute; son las <emphasis>Opciones del Kernel</emphasis>?</title>
    
    <para>B&aacute;sicamente el uso de las opciones del kernel se
      encuentran descritas en la secci&oacute;n de <link
      linkend="kernelconfig-options">configuraci&oacute;n del kernel</link>.
      Tambi&eacute;n existe una explicaci&oacute;n de opciones 
      <quote>hist&oacute;ricas</quote> y de <quote>nuevo-estilo</quote>.  La
      meta final es que eventualmente todas las opciones soportadas por el
      kernel sean del nuevo-estilo, de tal forma que para las personas que
      acertadamente ejecutan <command>make depend</command> en el directorio
      de compilaci&oacute;n de su kernel, despu&eacute;s de ejecutar 
      &man.config.8;, el proceso de compilaci&oacute;n detectar&aacute;
      autom&aacute;ticamente las opciones modificadas, y s&oacute;lo 
      recompilar&aacute; los ficheros donde sea necesario.  Eliminando el
      anterior directorio de compilaci&oacute;n en cada ocasi&oacute;n que 
      se ejecute &man.config.8; como es llevado a cabo ahora.</para>

    <para>B&aacute;sicamente, una opci&oacute;n del kernel no es otra cosa
      que la definici&oacute;n de un macro del preprocesador C para el
      proceso de compilaci&oacute;n del kernel.  Para efecto de hacer que la
      compilaci&oacute;n sea realmente opcional, la parte que corresponde a 
      la fuente del kernel (o bien el fichero kernel<filename>.h</filename>), 
      debe ser escrita teniendo en mente, el uso de
      las opciones del kernel, por ejemplo, las opciones por omisi&oacute;n
      pueden modificarse con la opci&oacute;n config.  Esto normalmente se
      lleva a cabo con algo como esto:</para>

	<programlisting>#ifndef ESTA_OPCION
#define ESTA_OPCION (algun_valor_por_default)
#endif /* ESTA_OPCION */</programlisting>

    <para>De esta forma cuando un administrador indica otro valor en su
      fichero de configuraci&oacute;n, deja sin efecto el valor que se
      tiene originalmente por default, y lo substituye con este nuevo
      valor.  Claramente el nuevo valor ser&aacute; utilizado como
      substituto en el c&oacute;digo fuente, cuando el preprocesador se
      ejecute, por lo que debe de tratarse de una expresi&oacute;n 
      v&aacute;lida para el lenguaje C, sin importar el contexto en el que
      se haya estado usando el valor por default.</para>

    <para>Tambi&eacute;n es posible crear opciones de menor valor, que
      simplemente habilitan o deshabilitan una parte particular del
      c&oacute;digo, al encerrarlo en &eacute;l</para>

    <programlisting>#ifdef ESTA_OPCION

[su c&oacute;digo aqui]

#endif</programlisting>

    <para>Simplemente al incluir <literal>ESTA_OPCION</literal> en su 
      fichero de configuraci&oacute;n (con o sin valor alguno), activar&aacute;
      la parte del c&oacute;digo que haya ingresado.</para>

    <para>Para la gente que este familiarizada con el lenguaje C, inmediatamente
      podr&aacute; darse cuenta de que todo pudiera ser tratado como una
      <quote>opci&oacute;n de configuraci&oacute;n</quote>, donde cuando menos
      se tiene una simple referencia del tipo <literal>#ifdef</literal>...  
      Por otro lado, es poco probable que alguien especifique</para> 

    <programlisting>options		aunno,nodefinida</programlisting>

    <para>en su fichero de configuraci&oacute;n, y que posteriormente
      se pregunten por que fallo la compilaci&oacute;n del kernel.</para>

    <para>Es claro que, el uso de nombres arbitrarios para las opciones, 
      hacen muy dif&iacute;cil el poder rastrear su uso en el c&oacute;digo
      del kernel.  Lo anterior es el razonamiento detr&aacute;s del esquema
      de opciones de <emphasis>nuevo-estilo</emphasis>, donde cada opci&oacute;n
      se localiza en un fichero <filename>.h</filename> diferente dentro del
      directorio de compilaci&oacute;n del kernel, los cuales por
      convicci&oacute;n son llamados 
      <filename>opt_</replaceable>foo</replaceable>.h</filename>.  De esta
      manera se pueden crear las dependencias dispuestas por Makefile, y el
      comando <command>make</command> puede determinar que debe ser
      recompilado, cuando una opci&oacute;n ha cambiado.</para>

    <para>Aun con esto los mecanismos del estilo-viejo, tienen una ventaja
      para las opciones locales o quiz&aacute;s para las opciones de
      experimentaci&oacute;n, que cuentan con un periodo de vida corto:
      en virtud de que es f&aacute;cil a&ntilde;adir  un nuevo 
      <literal>#ifdef</literal> al c&oacute;digo fuente del kernel, lo cual
      ya lo ha hecho una opci&oacute;n de configuraci&oacute;n del kernel.  En
      este caso, al utilizar esta opci&oacute;n, el administrador, es
      responsable por completo, al tener conocimiento de las implicaciones
      que tiene usarla (y probablemente el forzar la recompilaci&oacute;n de
      ciertas partes del kernel).  Una vez que la transici&oacute;n de 
      todas las opciones soportadas por el kernel ha finalizado, &man.config.8;
      advertir&aacute; cuando una opci&oacute;n no soportada aparezca en el
      fichero de configuraci&oacute;n, y no proceder&aacute; a incluirlo
      en el fichero Makefile del kernel.</para>
  </sect1>
  
  <sect1>
    <title>Ahora, &iquest;Qu&eacute; Debo Hacer?</title>
    
    <para>Lo primero es, editar el fichero <filename>sys/conf/options</filename>
      (o bien <filename>sys/<replaceable>&lt;arch&gt;</replaceable>/conf/options.
      <replaceable>&lt;arch&gt;</replaceable></filename>, por ejemplo; 
      <filename>/sys/i386/conf/options.i386</filename>), y seleccionar un
      fichero <filename>opt_<replaceable>foo</replaceable>.h</filename> que
      mejor describa la nueva opci&oacute;n, para su inclusi&oacute;n.</para>

    <para>Si ya existiese alguno, que se acerce al prop&oacute;sito de la
      nueva opci&oacute;n, debe elegir ese.  Por ejemplo, opciones que
      modifiquen el comportamiento global del subsistema SCSI, pueden
      incluirse en <filename>opt_scsi.h</filename>.  Por default, con el simple
      hecho de mencionar una opci&oacute;n en el fichero apropiado, digamos 
      <literal>FOO</literal>, implica que el valor correspondiente a esta
      opci&oacute;n se localiza en el fichero correspondiente 
      <filename>opt_foo.h</filename>.  Por otro lado, esto puede modificarse
      al especificar el nombre de otro fichero.</para>

    <para>Si el fichero 
      <filename>opt_<replaceable>foo</replaceable>.h</filename> para la
      nueva opci&oacute;n no existiera, invente un nuevo nombre.  Creelo de
      manera que sea intuitivo, con significado, y comente la nueva 
      secci&oacute;n en el fichero
      <filename>options[<replaceable>.&lt;arch&gt;</replaceable>]</filename>.
      En la ejecuci&oacute;n de &man.config.8;, este autom&aacute;gicamente
      reconocer&aacute; los cambios, y crear&aacute; ese fichero, la
      pr&oacute;xima vez que se ejecute.  La mayor&iacute;a de las opciones
      deber&aacute;n incluirse como encabezados por si mismos..</para>

    <para>El hecho de incluir muchas opciones, dentro de un solo fichero
      <filename>opt_<replaceable>foo</replaceable>.h</filename>, 
      tendr&aacute; como resultado la creaci&oacute;n de un buen numero de
      ficheros del kernel, durante la compilaci&oacute;n, cuando s&oacute;lo
      se haya realizado un cambio en alguna de las opciones del fichero de
      configuraci&oacute;n del kernel, por esta
      raz&oacute;n es conveniente conservar cada opci&oacute;n en su
      propio fichero <filename>opt_</filename>.</para>

    <para>Finalmente, averigue las dependencias que existen para la
      nueva opci&oacute;n.  A menos que la nueva opci&oacute;n sea de
      nueva creaci&oacute;n, y no exista en ninguna parte, la siguiente
      alternativa es su amiga, para efecto de encontrar dependencias:</para>

      <screen>&prompt.user; 
      <userinput>find /usr/src/sys -type f | xargs fgrep NUEVA_OPCION</userinput>
      </screen>

    <para>El comando anterior dar&aacute; como resultado un listado de 
      ficheros que tienen dependecia, dirijase a todos esos ficheros y
      a&ntilde;ada lo siguiente, en la parte <emphasis>superior</emphasis>
      (como encabezado), antes de todo lo que se refiere a 
      <literal>#include &lt;xxx.h&gt;</literal>.</para>

      <programlisting>#include "opt_foo.h"</programlisting>

    <para>El seguir este orden es de suma importancia, en virtud de que las 
      opciones pueden modificar el comportamiento, por omisi&oacute;n, de los
      ficheros normales del tipo <quote>#include</quote>
      (N de T: librer&iacute;s de encabezado), si
      estos son del tipo:</para>

      <programlisting> #ifndef NUEVA_OPCION #define NUEVA_OPCION (algo)
	#endif</programlisting>

    <para>El a&ntilde;adir una opci&oacute;n que substituye alg&uacute;n
      encabezado, en ficheros del sistema (por ejemplo; un fichero que se
      localiza en <filename>/usr/include/sys/</filename>) da como resultado
      casi siempre un error.  El fichero <filename>opt_<replaceable>foo
      </replaceable>.h</filename> no puede ser incluido en esos ficheros, 
      en virtud de que generaran un conflicto m&aacute;s serio, con sus
      propios encabezados, pero si no son incluidos, al momento de que se
      deseen utilizar, se puede obtener un valor inconsistente para esta
      opci&oacute;n.  Si, existen antecedentes de esto en este momento,
      pero eso no lo hace m&aacute;s correcto.</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:
-->

