Delete old kernel* chapters.
This commit is contained in:
parent
07951ab095
commit
ca1745d9e6
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/head/; revision=33274
2 changed files with 0 additions and 841 deletions
|
@ -1,625 +0,0 @@
|
||||||
<!--
|
|
||||||
The FreeBSD Documentation Project
|
|
||||||
|
|
||||||
The FreeBSD Spanish Documentation Project
|
|
||||||
|
|
||||||
%SOURCE% en_US.ISO8859-1/books/handbook/kerneldebug/chapter.sgml
|
|
||||||
%SRCID% 0.0
|
|
||||||
|
|
||||||
|
|
||||||
$FreeBSD$
|
|
||||||
$FreeBSDes: doc/es_ES.ISO8859-1/books/handbook/kerneldebug/chapter.sgml,v 1.2 2004/10/08 22:14:26 jesusr Exp $
|
|
||||||
-->
|
|
||||||
|
|
||||||
<chapter id="kerneldebug">
|
|
||||||
<title>Depurando el Kernel</title>
|
|
||||||
|
|
||||||
<para><emphasis>Contribución de &a.paul; y &a.joerg;</emphasis></para>
|
|
||||||
|
|
||||||
<sect1>
|
|
||||||
<title>Depuración de un Kernel Crash Dump con <command>kgdb</command></title>
|
|
||||||
|
|
||||||
<para>Aquí se dan instrucciones para hacer funcionar la depuración del
|
|
||||||
kernel sobre un crash dump. En ellos se asume que usted tiene suficiente
|
|
||||||
espacio de swap para un crash dump. Si usted tiene varias particiones
|
|
||||||
de swap y la primera es demasiado pequeña para albergar un dump, puede
|
|
||||||
configurar su kernel para que use un dispositivo alternativo (en la línea
|
|
||||||
<literal>config kernel</literal>=, o puede especificar una alternativa
|
|
||||||
usando el comando &man.dumpon.8;. La mejor manera de usar &man.dumpon.8;
|
|
||||||
es asignar la variable <literal>dumpdev</literal> en
|
|
||||||
<filename>/etc/rc.conf</filename>. Generalmente usted va a querer
|
|
||||||
especificar uno de los dispositivos de swap especificados en
|
|
||||||
<filename>/etc/fstab</filename>. Actualmente no se soportan dumps a
|
|
||||||
dispositivos que no sean de swap, como por ejemplo una unidad de cinta.
|
|
||||||
Configure su kernel usando <command>config -g</command>. Vea <link
|
|
||||||
linkend="kernelconfig">Configuración del Kernel</link> para más detalles
|
|
||||||
sobre la configuración del kernel FreeBSD.</para>
|
|
||||||
|
|
||||||
<para>Use el comando &man.dumpon.8; para decirle al kernel donde hacer
|
|
||||||
el dump (Tenga en cuenta que esto debera hacerse luego de configurar
|
|
||||||
la partición como dispositivo de swap usando &man.swapon.8;). Esto se
|
|
||||||
hace normalmente usando los archivos <filename>/etc/rc.conf</filename>
|
|
||||||
y <filename>/etc/rc</filename>. Como alternativa se puede fijar el
|
|
||||||
dispositivo usando la cláusula <literal>dump</literal> en la línea
|
|
||||||
<literal>config</literal> de su archivo de configuración del kernel.
|
|
||||||
Esta práctica esta en desuso y sólo debería ser usada para obtener
|
|
||||||
un dump de un kernel que falla durante el inicio.</para>
|
|
||||||
|
|
||||||
<note>
|
|
||||||
<para>En adelante, el término <command>kgdb</command> se referirá al
|
|
||||||
<command>gdb</command> corriendo en “kernel debug mode”.
|
|
||||||
Esto puede lograrse ya sea iniciando al <command>gdb</command> con
|
|
||||||
la opción <option>-k</option>, o enlazandolo y arrancandolo con el
|
|
||||||
nombre <command>kgdb</command>. Esto no se hace por default, y
|
|
||||||
la idea está basicamente en desuso ya que a la gente de GNU no le
|
|
||||||
gusta que sus herramientas se comporten distinto cuando se las llama
|
|
||||||
por otro nombre. Esta posibilidad podrá perfectamente ser descontinuada
|
|
||||||
en futuras versiones.</para>
|
|
||||||
</note>
|
|
||||||
|
|
||||||
<para>Una vez que el kernel ha sido compilado haga una copia, digamos
|
|
||||||
<filename>kernel.debug</filename>, y luego corra <command>strip
|
|
||||||
-g</command> sobre el original. Instale el original normalmente. Usted
|
|
||||||
tambien podría instalar el kernel sin hacer el <command>strip</command>,
|
|
||||||
pero los tiempos de busqueda de algunos programas en la tabla de
|
|
||||||
símbolos aumentarán sensiblemente, y dado que el kernel se carga completo
|
|
||||||
en memoria durante el inicio y no puede intercambiarse a disco luego,
|
|
||||||
se desperdiciarán varios megabytes de memoria.</para>
|
|
||||||
|
|
||||||
<para>Si usted esta probando un nuevo kernel, por ejemplo tipeando el
|
|
||||||
nombre del nuevo kernel en el prompt de inicio, pero necesita arrancar
|
|
||||||
otro para tener su sistema funcionando de nuevo, arranquelo solo en modo
|
|
||||||
monousuario usando la opción <option>-s</option> en el prompt de inicio
|
|
||||||
, y luego siga los siguientes pasos:</para>
|
|
||||||
|
|
||||||
<screen>&prompt.root; <userinput>fsck -p</userinput>
|
|
||||||
&prompt.root; <userinput>mount -a -t ufs</userinput> # asi su file system para /var/crash se puede escribir
|
|
||||||
&prompt.root; <userinput>savecore -N /kernel.panicked /var/crash</userinput>
|
|
||||||
&prompt.root; <userinput>exit</userinput> # ...a modo multiusuario</screen>
|
|
||||||
|
|
||||||
<para>Esto instruye a &man.savecore.8; que use otro kernel para la
|
|
||||||
extracción de nombres de símbolo. De otro modo usaria el kernel en uso
|
|
||||||
y probablemente no haga nada ya que los símbolos del kernel y los del
|
|
||||||
dump son diferentes.</para>
|
|
||||||
|
|
||||||
<para>Ahora, luego de un crash dump, vaya a
|
|
||||||
<filename>/sys/compile/WHATEVER</filename> y corra
|
|
||||||
<command>kgdb</command>. desde <command>kgdb</command> haga:
|
|
||||||
|
|
||||||
<screen><userinput>symbol-file kernel.debug</userinput>
|
|
||||||
<userinput>exec-file /var/crash/kernel.0</userinput>
|
|
||||||
<userinput>core-file /var/crash/vmcore.0</userinput></screen>
|
|
||||||
|
|
||||||
y voila, ya puede depurar el crash dump usando las fuentes
|
|
||||||
del kernel como lo hace con cualquier otro programa.</para>
|
|
||||||
|
|
||||||
<para>A continuación se muestra el log de una sesión de
|
|
||||||
<command>kgdb</command> que ilustra el procedimiento. Las líneas
|
|
||||||
fueron numeradas para referencia, y las largas fueron cortadas para
|
|
||||||
mejorar la legibilidad. Mas alla de esto es el registro de un error real
|
|
||||||
tomado durante el desarrollo del driver pcvt de consola.</para>
|
|
||||||
|
|
||||||
<screen> 1:Script started on Fri Dec 30 23:15:22 1994
|
|
||||||
2:&prompt.root; <userinput>cd /sys/compile/URIAH</userinput>
|
|
||||||
3:&prompt.root; <userinput>kgdb kernel /var/crash/vmcore.1</userinput>
|
|
||||||
4:Reading symbol data from /usr/src/sys/compile/URIAH/kernel
|
|
||||||
...done.
|
|
||||||
5:IdlePTD 1f3000
|
|
||||||
6:panic: because you said to!
|
|
||||||
7:current pcb at 1e3f70
|
|
||||||
8:Reading in symbols for ../../i386/i386/machdep.c...done.
|
|
||||||
9:<prompt>(kgdb)</prompt> <userinput>where</userinput>
|
|
||||||
10:#0 boot (arghowto=256) (../../i386/i386/machdep.c line 767)
|
|
||||||
11:#1 0xf0115159 in panic ()
|
|
||||||
12:#2 0xf01955bd in diediedie () (../../i386/i386/machdep.c line 698)
|
|
||||||
13:#3 0xf010185e in db_fncall ()
|
|
||||||
14:#4 0xf0101586 in db_command (-266509132, -266509516, -267381073)
|
|
||||||
15:#5 0xf0101711 in db_command_loop ()
|
|
||||||
16:#6 0xf01040a0 in db_trap ()
|
|
||||||
17:#7 0xf0192976 in kdb_trap (12, 0, -272630436, -266743723)
|
|
||||||
18:#8 0xf019d2eb in trap_fatal (...)
|
|
||||||
19:#9 0xf019ce60 in trap_pfault (...)
|
|
||||||
20:#10 0xf019cb2f in trap (...)
|
|
||||||
21:#11 0xf01932a1 in exception:calltrap ()
|
|
||||||
22:#12 0xf0191503 in cnopen (...)
|
|
||||||
23:#13 0xf0132c34 in spec_open ()
|
|
||||||
24:#14 0xf012d014 in vn_open ()
|
|
||||||
25:#15 0xf012a183 in open ()
|
|
||||||
26:#16 0xf019d4eb in syscall (...)
|
|
||||||
27:<prompt>(kgdb)</prompt> <userinput>up 10</userinput>
|
|
||||||
28:Reading in symbols for ../../i386/i386/trap.c...done.
|
|
||||||
29:#10 0xf019cb2f in trap (frame={tf_es = -260440048, tf_ds = 16, tf_\
|
|
||||||
30:edi = 3072, tf_esi = -266445372, tf_ebp = -272630356, tf_isp = -27\
|
|
||||||
31:2630396, tf_ebx = -266427884, tf_edx = 12, tf_ecx = -266427884, tf\
|
|
||||||
32:_eax = 64772224, tf_trapno = 12, tf_err = -272695296, tf_eip = -26\
|
|
||||||
33:6672343, tf_cs = -266469368, tf_eflags = 66066, tf_esp = 3072, tf_\
|
|
||||||
34:ss = -266427884}) (../../i386/i386/trap.c line 283)
|
|
||||||
35:283 (void) trap_pfault(&frame, FALSE);
|
|
||||||
36:<prompt>(kgdb)</prompt> <userinput>frame frame->tf_ebp frame->tf_eip</userinput>
|
|
||||||
37:Reading in symbols for ../../i386/isa/pcvt/pcvt_drv.c...done.
|
|
||||||
38:#0 0xf01ae729 in pcopen (dev=3072, flag=3, mode=8192, p=(struct p\
|
|
||||||
39:roc *) 0xf07c0c00) (../../i386/isa/pcvt/pcvt_drv.c line 403)
|
|
||||||
40:403 return ((*linesw[tp->t_line].l_open)(dev, tp));
|
|
||||||
41:<prompt>(kgdb)</prompt> <userinput>list</userinput>
|
|
||||||
42:398
|
|
||||||
43:399 tp->t_state |= TS_CARR_ON;
|
|
||||||
44:400 tp->t_cflag |= CLOCAL; /* cannot be a modem (:-) */
|
|
||||||
45:401
|
|
||||||
46:402 #if PCVT_NETBSD || (PCVT_FREEBSD >= 200)
|
|
||||||
47:403 return ((*linesw[tp->t_line].l_open)(dev, tp));
|
|
||||||
48:404 #else
|
|
||||||
49:405 return ((*linesw[tp->t_line].l_open)(dev, tp, flag));
|
|
||||||
50:406 #endif /* PCVT_NETBSD || (PCVT_FREEBSD >= 200) */
|
|
||||||
51:407 }
|
|
||||||
52:<prompt>(kgdb)</prompt> <userinput>print tp</userinput>
|
|
||||||
53:Reading in symbols for ../../i386/i386/cons.c...done.
|
|
||||||
54:$1 = (struct tty *) 0x1bae
|
|
||||||
55:<prompt>(kgdb)</prompt> <userinput>print tp->t_line</userinput>
|
|
||||||
56:$2 = 1767990816
|
|
||||||
57:<prompt>(kgdb)</prompt> <userinput>up</userinput>
|
|
||||||
58:#1 0xf0191503 in cnopen (dev=0x00000000, flag=3, mode=8192, p=(st\
|
|
||||||
59:ruct proc *) 0xf07c0c00) (../../i386/i386/cons.c line 126)
|
|
||||||
60: return ((*cdevsw[major(dev)].d_open)(dev, flag, mode, p));
|
|
||||||
61:<prompt>(kgdb)</prompt> <userinput>up</userinput>
|
|
||||||
62:#2 0xf0132c34 in spec_open ()
|
|
||||||
63:<prompt>(kgdb)</prompt> <userinput>up</userinput>
|
|
||||||
64:#3 0xf012d014 in vn_open ()
|
|
||||||
65:<prompt>(kgdb)</prompt> <userinput>up</userinput>
|
|
||||||
66:#4 0xf012a183 in open ()
|
|
||||||
67:<prompt>(kgdb)</prompt> <userinput>up</userinput>
|
|
||||||
68:#5 0xf019d4eb in syscall (frame={tf_es = 39, tf_ds = 39, tf_edi =\
|
|
||||||
69: 2158592, tf_esi = 0, tf_ebp = -272638436, tf_isp = -272629788, tf\
|
|
||||||
70:_ebx = 7086, tf_edx = 1, tf_ecx = 0, tf_eax = 5, tf_trapno = 582, \
|
|
||||||
71:tf_err = 582, tf_eip = 75749, tf_cs = 31, tf_eflags = 582, tf_esp \
|
|
||||||
72:= -272638456, tf_ss = 39}) (../../i386/i386/trap.c line 673)
|
|
||||||
73:673 error = (*callp->sy_call)(p, args, rval);
|
|
||||||
74:<prompt>(kgdb)</prompt> <userinput>up</userinput>
|
|
||||||
75:Initial frame selected; you cannot go up.
|
|
||||||
76:<prompt>(kgdb)</prompt> <userinput>quit</userinput>
|
|
||||||
77:&prompt.root; <userinput>exit</userinput>
|
|
||||||
78:exit
|
|
||||||
79:
|
|
||||||
80:Script done on Fri Dec 30 23:18:04 1994</screen>
|
|
||||||
<para>Comentarios al listado anterior:</para>
|
|
||||||
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry>
|
|
||||||
<term>línea 6:</term>
|
|
||||||
|
|
||||||
<listitem>
|
|
||||||
<para>Este es un dump tomado desde el DDB (vea abajo), a partir del
|
|
||||||
comentario del panic “because you said to!”, y un
|
|
||||||
listado de la pila bastante largo; la razón incial para entrar al
|
|
||||||
DDB fue un trap de falta de pagina.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>línea 20:</term>
|
|
||||||
|
|
||||||
<listitem>
|
|
||||||
<para>Esta es la ubicación de la función <function>trap()</function>
|
|
||||||
en el listado de la pila.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>línea 36:</term>
|
|
||||||
|
|
||||||
<listitem>
|
|
||||||
<para>Se fuerza el uso de un nuevo marco de pila; esto ya no es
|
|
||||||
necesario ahora. Actualmente se supone que los marcos de pila apuntan a
|
|
||||||
las ubicaciones correctas, aun en caso de un trap. (No tengo un
|
|
||||||
dump más nuevo a mano <g>, mi kernel no ha hecho un panic
|
|
||||||
desde hace bastante tiempo.) Mirando al código en la línea 403
|
|
||||||
del código fuente, hay una alta probabilidad de que la referencia
|
|
||||||
al puntero “tp” sea erronea, o el acceso al arreglo
|
|
||||||
estuviera fuera de sus límites.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>línea 52:</term>
|
|
||||||
|
|
||||||
<listitem>
|
|
||||||
<para>El puntero se ve sospechoso, pero contiene una dirección
|
|
||||||
válida.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>línea 56:</term>
|
|
||||||
|
|
||||||
<listitem>
|
|
||||||
<para>De todos modos, obviamente apunta a basura, asi que encontramos
|
|
||||||
nuestro error! (Para los que no esten familiarizados con esa pieza
|
|
||||||
de código en particular: <literal>tp->t_line</literal> hace
|
|
||||||
referencia a la disciplina de línea de este dispositivo de consola,
|
|
||||||
el cual debe ser un entero por demás pequeño)</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
</variablelist>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1>
|
|
||||||
<title>Depurando un crash dump con DDD</title>
|
|
||||||
|
|
||||||
<para>Tambien es posible examinar un crash dump del kernel con un debugger
|
|
||||||
gráfico como <command>ddd</command>. Agregue la opción <option>-k
|
|
||||||
</option> a la línea de comando del <command>ddd</command> que usaría
|
|
||||||
normalmente. Por ejemplo;</para>
|
|
||||||
|
|
||||||
<screen>&prompt.root; <userinput>ddd -k /var/crash/kernel.0 /var/crash/vmcore.0</userinput></screen>
|
|
||||||
|
|
||||||
<para>De esta manera usted debería poder analizar el crash dump usando
|
|
||||||
la interfaz gráfica del <command>ddd</command>.</para>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1>
|
|
||||||
<title>Analisis Post-mortem de un Dump</title>
|
|
||||||
|
|
||||||
<para>Que sucede si un kernel hace un dump de su memoria que usted
|
|
||||||
no esperaba, y por lo tanto no estaba compilado usando <command>
|
|
||||||
config -g</command>? No todo esta perdido aquí. Do not panic!</para>
|
|
||||||
|
|
||||||
<note>
|
|
||||||
<para>N.del T.: El autor hace un juego con la palabra panic! que
|
|
||||||
prefiero dejar sin traducir.</para>
|
|
||||||
</note>
|
|
||||||
|
|
||||||
<para>Por supuesto, aun necesita habilitar los crash dumps. Vea más arriba
|
|
||||||
las opciones que debe especificar para esto.</para>
|
|
||||||
|
|
||||||
<para>Vaya a su directorio de configuración del kernel
|
|
||||||
(<filename>/usr/src/sys/<replaceable>arq</replaceable>/conf</filename>)
|
|
||||||
y edite su archivo de configuración. Quite las marcas de comentario
|
|
||||||
(o agregue, si no existe) la siguiente línea</para>
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols</programlisting>
|
|
||||||
|
|
||||||
<para>Recompile el kernel. Algunos otros archivos seran recompilados,
|
|
||||||
por ejemplo <filename>trap.o</filename>, a causa del cambio de la fecha
|
|
||||||
del archivo Makefile. Con un poco de suerte, la opción <option>-g
|
|
||||||
</option> no cambiará nada del código generado, al final usted tendra
|
|
||||||
un kernel con el mismo código que tiene problemas ahora pero con ciertos
|
|
||||||
símbolos para depuración. Por lo menos usted debería verificar el tamaño
|
|
||||||
anterior y el nuevo con el comando &man.size.1;. Si hay diferencia
|
|
||||||
probablemente sea el momento de darse por vencido.</para>
|
|
||||||
|
|
||||||
<para>Ahora puede examinar el dump como se describió anteriormente. Los
|
|
||||||
símbolos pueden estar incompletos para algunas partes, como se puede ver
|
|
||||||
en el listado de pila del ejemplo anterior donde algunas funciones
|
|
||||||
se muestran sin numeros de línea ni listas de argumentos. Si necesita
|
|
||||||
más símbolos borre los archivos objeto apropiados y repita la sesión de
|
|
||||||
<command>kgdb</command> hasta que haya averiguado lo suficiente.</para>
|
|
||||||
|
|
||||||
<para>No se garantiza que todo esto funcione, pero irá bastante bien la
|
|
||||||
en mayoría de los casos.</para>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1>
|
|
||||||
<title>Depuración En-línea del Kernel Usando DDB</title>
|
|
||||||
|
|
||||||
<para>Si bien el <command>kgdb</command> provee un muy alto nivel de
|
|
||||||
interfaz de usuario como depurador post-mortem, hay cosas que no puede
|
|
||||||
hacer. Siendo las más importantes poder marcar puntos de interrupción
|
|
||||||
y ejecutar código del kernel paso a paso.</para>
|
|
||||||
|
|
||||||
<para>Si usted necesita hacer una depuración a bajo nivel de su kernel hay
|
|
||||||
disponible un debugger en-línea llamado DDB. Permite poner puntos de
|
|
||||||
interrupción, ejecutar paso a paso las funciones del kernel, examinar y
|
|
||||||
cambiar variables, etc. Sin embargo, no puede acceder al código fuente
|
|
||||||
del kernel y sólo tiene acceso a los símbolos globales y estáticos, no
|
|
||||||
a toda la información de depuración como el <command>kgdb</command>.</para>
|
|
||||||
|
|
||||||
<para>Para configurar su kernel para que incluya el DDB, agregue la opción
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
options DDB</programlisting>
|
|
||||||
|
|
||||||
a su archivo de configuración, y recompile (vea <link
|
|
||||||
linkend="kernelconfig">Configuración del Kernel</link> para más
|
|
||||||
detalles sobre como configurar el kernel de FreeBSD.)</para>
|
|
||||||
|
|
||||||
<note>
|
|
||||||
<para>Notese que si usted tiene una versión vieja del boot block,
|
|
||||||
sus símbolos de debugger podrían no ser cargados. Actualize su
|
|
||||||
boot block; los mas recientes cargan los símbolos del DDB
|
|
||||||
automágicamente.</para>
|
|
||||||
</note>
|
|
||||||
|
|
||||||
<para>Una vez que su kernel con DDB esta corriendo, hay varias maneras
|
|
||||||
de entrar al DDB. La primera y más temprana es tipear la opción
|
|
||||||
<option>-d</option> directamente en el prompt de inicio. El kernel
|
|
||||||
se iniciará en modo de depuración e ingresará al DDB antes de cualquier
|
|
||||||
detección de dispositivos. De aquí en adelante usted podrá
|
|
||||||
depurar hasta las funciones probe/attach de los dispositivos.</para>
|
|
||||||
|
|
||||||
<para>El segundo escenario es una combinación de teclas, generalmente
|
|
||||||
Ctrl-Alt-Esc. En el caso de las syscons, esto puede modificarse,
|
|
||||||
algunos mapas de teclado distribuidos lo hacen, por lo que hay que
|
|
||||||
prestar atención. Hay disponible una opción para consolas en puertos
|
|
||||||
serie que permite el uso de la señal BREAK en la línea para entrar al
|
|
||||||
DDB (<literal>options BREAK_TO_DEBUGGER</literal> en el archivo de
|
|
||||||
configuración del kernel). Esto no es el default ya que hay un montón
|
|
||||||
de adaptadores serie dando vueltas que generan condiciones BREAK
|
|
||||||
sin necesidad, por ejemplo cuando se desenchufa el cable.</para>
|
|
||||||
|
|
||||||
<para>La tercera forma es que un panic salte al DDB si el kernel está
|
|
||||||
configurado para usarlo. Por este motivo, no es recomendable configurar
|
|
||||||
un kernel con DDB para una máquina funcionando sin atención.</para>
|
|
||||||
|
|
||||||
<para>Los comandos del DDB se asemejan remotamente a algunos de los
|
|
||||||
del <command>gdb</command>. Lo primero que usted probablemente
|
|
||||||
necesite hacer es poner un punto de interrupción:</para>
|
|
||||||
|
|
||||||
<screen><userinput>b nombre-de-función</userinput>
|
|
||||||
<userinput>b dirección</userinput></screen>
|
|
||||||
|
|
||||||
<para>Por default los números se toman en hexadecimal, pero para
|
|
||||||
distinguirlos de los nombres de símbolo los números hexadecimales
|
|
||||||
que empiezan con las letras <literal>a-f</literal> se deben preceder
|
|
||||||
con <literal>0x</literal> (para los demás números esto es opcional).
|
|
||||||
Tambien se admiten expresiones sencillas, por ejemplo:
|
|
||||||
<literal>nombre-de-función + 0x103</literal>.</para>
|
|
||||||
|
|
||||||
<para>Para que el kernel interrumpido continue ejecutandose, solo
|
|
||||||
tipee:</para>
|
|
||||||
|
|
||||||
<screen><userinput>c</userinput></screen>
|
|
||||||
|
|
||||||
<para>Para ver un listado de la pila, use:</para>
|
|
||||||
|
|
||||||
<screen><userinput>trace</userinput></screen>
|
|
||||||
|
|
||||||
<note>
|
|
||||||
<para>Notese que cuando se entra al DDB con una combinación de teclas
|
|
||||||
el kernel está atendiendo una interrupción, por lo que el listado
|
|
||||||
de la pila podría no serle de mucha utilidad.</para>
|
|
||||||
</note>
|
|
||||||
|
|
||||||
<para>Si quiere quitar un punto de interrupción, use</para>
|
|
||||||
|
|
||||||
|
|
||||||
<screen><userinput>del</userinput>
|
|
||||||
<userinput>del expresión-dirección-de-memoria</userinput></screen>
|
|
||||||
|
|
||||||
<para>La primera forma se aceptará inmediatamente despues de llegar
|
|
||||||
a un punto de interrupción, y borra el punto actual. La segunda
|
|
||||||
puede quitar cualquier punto de interrupción, pero se debe
|
|
||||||
especificar la dirección exacta; esta se puede obtener de:</para>
|
|
||||||
|
|
||||||
<screen><userinput>show b</userinput></screen>
|
|
||||||
|
|
||||||
<para>Para ejecutar el kernel paso a paso, intente:</para>
|
|
||||||
|
|
||||||
<screen><userinput>s</userinput></screen>
|
|
||||||
|
|
||||||
<para>Esto entrará dentro de las funciones, pero puede hacer
|
|
||||||
que DDB las siga hasta llegar a la instrucción de retorno
|
|
||||||
correspondiente usando:</para>
|
|
||||||
|
|
||||||
<screen><userinput>n</userinput></screen>
|
|
||||||
|
|
||||||
<note>
|
|
||||||
<para>Esto es distinto de la instrucción <command>next</command>
|
|
||||||
del <command>gdb</command>; es más parecido a la instrucción
|
|
||||||
<command>finish</command>.</para>
|
|
||||||
</note>
|
|
||||||
|
|
||||||
<para>Para examinar los datos en la memoria use (por ejemplo):
|
|
||||||
|
|
||||||
<screen><userinput>x/wx 0xf0133fe0,40</userinput>
|
|
||||||
<userinput>x/hd db_symtab_space</userinput>
|
|
||||||
<userinput>x/bc termbuf,10</userinput>
|
|
||||||
<userinput>x/s stringbuf</userinput></screen>
|
|
||||||
|
|
||||||
para acceder a palabras/medias palabras/bytes, y para mostrar
|
|
||||||
en hexadecimal/decimal/caracteres/strings. El número luego de la coma
|
|
||||||
es la cantidad de objetos. Para mostrar los siguientes 0x10
|
|
||||||
items, simplemente use:</para>
|
|
||||||
|
|
||||||
<screen><userinput>x ,10</userinput></screen>
|
|
||||||
|
|
||||||
<para>Del mismo modo, use
|
|
||||||
|
|
||||||
<screen><userinput>x/ia foofunc,10</userinput></screen>
|
|
||||||
|
|
||||||
para desensamblar las primeras 0x10 instrucciones de
|
|
||||||
<function>foofunc</function>, y mostrarlas junto con su
|
|
||||||
desplazamiento desde el comienzo de <function>foofunc</function>.</para>
|
|
||||||
|
|
||||||
<para>Para modificar memoria, use el comando write:</para>
|
|
||||||
|
|
||||||
<screen><userinput>w/b termbuf 0xa 0xb 0</userinput>
|
|
||||||
<userinput>w/w 0xf0010030 0 0</userinput></screen>
|
|
||||||
|
|
||||||
<para>El modificador
|
|
||||||
(<literal>b</literal>/<literal>h</literal>/<literal>w</literal>)
|
|
||||||
especifica el tamaño de los datos a ser escritos, la primera expresión
|
|
||||||
a continuación es la dirección donde escribir y el resto es interpretado
|
|
||||||
como datos para escribir en las direcciones de memoria sucesivas.</para>
|
|
||||||
|
|
||||||
<para>Si quiere conocer el valor actual de los registros del
|
|
||||||
procesador, use:</para>
|
|
||||||
|
|
||||||
<screen><userinput>show reg</userinput></screen>
|
|
||||||
|
|
||||||
<para>O, puede mostrar un solo registro usando:
|
|
||||||
|
|
||||||
<screen><userinput>p $eax</userinput></screen>
|
|
||||||
|
|
||||||
y modificarlo haciendo:</para>
|
|
||||||
|
|
||||||
<screen><userinput>set $eax new-value</userinput></screen>
|
|
||||||
|
|
||||||
<para>Si usted quisiera llamar alguna función del kernel desde
|
|
||||||
el DDB, solo debe decir:</para>
|
|
||||||
|
|
||||||
<screen><userinput>call func(arg1, arg2, ...)</userinput></screen>
|
|
||||||
|
|
||||||
<para>El valor devuelto será impreso en la pantalla.</para>
|
|
||||||
|
|
||||||
<para>Para un resumen de los procesos corriendo al estilo &man.ps.1;
|
|
||||||
use:</para>
|
|
||||||
|
|
||||||
<screen><userinput>ps</userinput></screen>
|
|
||||||
|
|
||||||
<para>Usted ya ha examinado la causa de que su kernel falle, y quiere
|
|
||||||
reiniciar su equipo. Recuerde que, dependiendo de lo severo de las
|
|
||||||
fallas que ocurrieron, algunas partes del kernel podrían no funcionar
|
|
||||||
como se espera. Siga una de las siguientes acciones para apagar y
|
|
||||||
reiniciar su equipo:</para>
|
|
||||||
|
|
||||||
<screen><userinput>call diediedie()</userinput></screen>
|
|
||||||
|
|
||||||
<para>Esto causará que su kernel haga un crash dump y reinicie, asi
|
|
||||||
luego podrá analizar el dump a un nivel más alto con el kgdb. Este
|
|
||||||
comando suele tener que acompañarse por otra instrucción <command>
|
|
||||||
continue</command>. Para hacer esto hay un alias:
|
|
||||||
<command>panic</command>.</para>
|
|
||||||
|
|
||||||
<screen><userinput>call boot(0)</userinput></screen>
|
|
||||||
|
|
||||||
<para>La cual podría ser una buena manera de apagar ordenadamente el
|
|
||||||
sistema, hacer un <function>sync()</function> de todos los discos,
|
|
||||||
y finalmente reiniciar. En tanto las interfaces de disco y de
|
|
||||||
filesystem del kernel no esten dañadas, esta podría ser una buena
|
|
||||||
manera de hacer un apagado bastante prolijo.</para>
|
|
||||||
|
|
||||||
<screen><userinput>call cpu_reset()</userinput></screen>
|
|
||||||
|
|
||||||
<para>Es la ultima salida de los desastres y es practicamente lo
|
|
||||||
mismo que presionar el Gran Boton Rojo.</para>
|
|
||||||
|
|
||||||
<para>Si usted necesita un breve sumario de los comandos, tipee:</para>
|
|
||||||
|
|
||||||
<screen><userinput>help</userinput></screen>
|
|
||||||
|
|
||||||
<para>De todos modos, es altamente recomendable tener una copia impresa
|
|
||||||
de la página &man.ddb.4; del manual a mano antes de la sesión de
|
|
||||||
depuración. Recuerde que es bastante difícil leer el manual en línea
|
|
||||||
mientras se está ejecutando el kernel paso a paso.</para>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1>
|
|
||||||
<title>Depuración En-Línea Usando El GDB remoto</title>
|
|
||||||
|
|
||||||
<para>Esta característica ha sido soportada desde FreeBSD 2.2, y ya está
|
|
||||||
en verdad muy bien pulida.</para>
|
|
||||||
|
|
||||||
<para>El GDB ha soportado <emphasis>depuración remota</emphasis> desde
|
|
||||||
hace mucho tiempo. Esto se hace usando un protocolo muy simple a
|
|
||||||
traves de una línea serie. A diferencia de los otros metodos descriptos
|
|
||||||
anteriormente, hacen falta dos máquinas para hacer esto. Una va a
|
|
||||||
proveer el entorno de depuración, incluyendo todos los archivos fuente,
|
|
||||||
y una copia del ejecutable del kernel con todos los símbolos y la otra
|
|
||||||
será la máquina a depurar que simplemente corre una copia de exactamente
|
|
||||||
el mismo kernel (pero sin los símbolos de depuración).</para>
|
|
||||||
|
|
||||||
<para>Usted debería configurar el kernel en cuestión con <command>config
|
|
||||||
-g</command>, incluir <option>DDB</option> en la configuración, y
|
|
||||||
compilarla como siempre. Esto arrojará un ejecutable enorme, debido a la
|
|
||||||
información de depuración. Copie este kernel a la máquina a depurar,
|
|
||||||
quitele los simbolos con <command>strip -x</command>, e inicielo usando
|
|
||||||
la opción <option>-d</option> en el prompt de inicio. Conecte el primer
|
|
||||||
puerto serie de la máquina a cualquier puerto serie de la máquina que
|
|
||||||
correrá el debugger. Ahora en la máquina que corre el debugger, vaya al
|
|
||||||
directorio de compilación del kernel a depurar, y arranque el gdb:</para>
|
|
||||||
|
|
||||||
<screen>&prompt.user; <userinput>gdb -k kernel</userinput>
|
|
||||||
GDB is free software and you are welcome to distribute copies of it
|
|
||||||
under certain conditions; type "show copying" to see the conditions.
|
|
||||||
There is absolutely no warranty for GDB; type "show warranty" for details.
|
|
||||||
GDB 4.16 (i386-unknown-freebsd),
|
|
||||||
Copyright 1996 Free Software Foundation, Inc...
|
|
||||||
<prompt>(kgdb)</prompt> </screen>
|
|
||||||
|
|
||||||
<para>Inicie la sesión de depuración remota haciendo
|
|
||||||
(asumiendo que se usa el primer puerto serie):</para>
|
|
||||||
|
|
||||||
<screen><prompt>(kgdb)</prompt> <userinput>target remote /dev/cuaa0</userinput></screen>
|
|
||||||
|
|
||||||
<para>Ahora en la máquina a depurar (que entró al DDB justo antes de
|
|
||||||
empezar a detectar los dispositivos), tipee:</para>
|
|
||||||
|
|
||||||
<screen>Debugger("Boot flags requested debugger")
|
|
||||||
Stopped at Debugger+0x35: movb $0, edata+0x51bc
|
|
||||||
<prompt>db></prompt> <userinput>gdb</userinput></screen>
|
|
||||||
|
|
||||||
<para>El DDB responderá diciendo:</para>
|
|
||||||
|
|
||||||
<screen>Next trap will enter GDB remote protocol mode</screen>
|
|
||||||
|
|
||||||
<para>Cada vez que tipee <command>gdb</command>, el modo se alternará
|
|
||||||
entre el GDB remoto y el DDB local. Para forzar un siguiente trap
|
|
||||||
inmediatamente, simplemente tipee <command>s</command> (avanza un paso).
|
|
||||||
la máquina del debugger ahora ganará control sobre el kernel a depurar:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<screen>Remote debugging using /dev/cuaa0
|
|
||||||
Debugger (msg=0xf01b0383 "Boot flags requested debugger")
|
|
||||||
at ../../i386/i386/db_interface.c:257
|
|
||||||
<prompt>(kgdb)</prompt></screen>
|
|
||||||
|
|
||||||
<para>Esta sesión puede usarse casi como cualquier otra sesión de GDB,
|
|
||||||
incluyendo acceso completo al código fuente, ejecutarlo en modo-gud
|
|
||||||
dentro de una ventana de Emacs (lo cual brinda la posibilidad de
|
|
||||||
mostrar automáticamente el código fuente en otra ventana de Emacs)
|
|
||||||
etc.</para>
|
|
||||||
|
|
||||||
<para>El GDB remoto tambien puede usarse para depurar LKMs. Primero
|
|
||||||
compile el LKM con los simbolos de depuración:</para>
|
|
||||||
|
|
||||||
<screen>&prompt.root; <userinput>cd /usr/src/lkm/linux</userinput>
|
|
||||||
&prompt.root; <userinput>make clean; make COPTS=-g</userinput></screen>
|
|
||||||
|
|
||||||
<para>Luego instale esta versión del módulo en la máquina a depurar,
|
|
||||||
carguelo y use <command>modstat</command> para averiguar donde fue
|
|
||||||
cargado:</para>
|
|
||||||
|
|
||||||
<screen>&prompt.root; <userinput>linux</userinput>
|
|
||||||
&prompt.root; <userinput>modstat</userinput>
|
|
||||||
Type Id Off Loadaddr Size Info Rev Module Name
|
|
||||||
EXEC 0 4 f5109000 001c f510f010 1 linux_mod</screen>
|
|
||||||
|
|
||||||
<para>Tome la dirección de carga (loadaddr) del módulo y sumele
|
|
||||||
0x20 (probablemente para contar el encabezado a.out). Esta es la
|
|
||||||
dirección donde el código del módulo fue reubicado. Use el comando
|
|
||||||
<command>add-symbol-file</command> en el GDB para informarle al
|
|
||||||
debugger acerca del módulo:</para>
|
|
||||||
|
|
||||||
<screen><prompt>(kgdb)</prompt> <userinput>add-symbol-file /usr/src/lkm/linux/linux_mod.o 0xf5109020</userinput>
|
|
||||||
add symbol table from file "/usr/src/lkm/linux/linux_mod.o" at
|
|
||||||
text_addr = 0xf5109020? (y or n) <userinput>y</userinput>
|
|
||||||
<prompt>(kgdb)</prompt></screen>
|
|
||||||
|
|
||||||
<para>Ahora tiene acceso a todos los símbolos en el LKM.</para>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1>
|
|
||||||
<title>Depurando Un Driver de Consola</title>
|
|
||||||
|
|
||||||
<para>Dado que el DDB necesita un driver de consola sobre el que correr,
|
|
||||||
las cosas son mas complicadas si lo que falla es el propio driver de
|
|
||||||
consola. Usted podría entonces recordar el uso de una consola en puerto serie
|
|
||||||
(ya sea con un sector de inicio modificado, o especificando <option>-h
|
|
||||||
</option> en el prompt <prompt>Boot:</prompt>) y colgar una terminal
|
|
||||||
estándar en su primer puerto serie. El DDB funciona en cualquier
|
|
||||||
driver de consola configurado, por supuesto tambien en una consola de
|
|
||||||
puerto serie.</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:
|
|
||||||
-->
|
|
||||||
|
|
|
@ -1,216 +0,0 @@
|
||||||
<!--
|
|
||||||
The FreeBSD Documentation Project
|
|
||||||
|
|
||||||
The FreeBSD Spanish Documentation Project
|
|
||||||
|
|
||||||
%SOURCE% en_US.ISO8859-1/books/handbook/kernelopts/chapter.sgml
|
|
||||||
%SRCID% 0.0
|
|
||||||
|
|
||||||
|
|
||||||
$FreeBSD$
|
|
||||||
$FreeBSDes: doc/es_ES.ISO8859-1/books/handbook/kernelopts/chapter.sgml,v 1.2 2004/10/08 22:14:26 jesusr Exp $
|
|
||||||
-->
|
|
||||||
|
|
||||||
<chapter id="kernelopts">
|
|
||||||
<chapterinfo>
|
|
||||||
<authorgroup>
|
|
||||||
<author>
|
|
||||||
<firstname>Jörg</firstname>
|
|
||||||
<surname>Wunsch</surname>
|
|
||||||
<contrib>Contribuido por </contrib>
|
|
||||||
</author>
|
|
||||||
</authorgroup>
|
|
||||||
</chapterinfo>
|
|
||||||
|
|
||||||
<title>Añadiendo Opciones a la Configuración de un Nuevo Kernel</title>
|
|
||||||
|
|
||||||
<note>
|
|
||||||
<para>Es importante que antes de leer este documento, usted este
|
|
||||||
familiarizado con la sección de <link
|
|
||||||
linkend="kernelconfig">configuració del kernel</link>.</para>
|
|
||||||
</note>
|
|
||||||
|
|
||||||
<sect1>
|
|
||||||
<title>¿Qué son las <emphasis>Opciones del Kernel</emphasis>?</title>
|
|
||||||
|
|
||||||
<para>Básicamente el uso de las opciones del kernel se
|
|
||||||
encuentran descritas en la sección de <link
|
|
||||||
linkend="kernelconfig-options">configuración del kernel</link>.
|
|
||||||
También existe una explicación de opciones
|
|
||||||
<quote>histó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ón de su kernel, después de ejecutar
|
|
||||||
&man.config.8;, el proceso de compilación detectará
|
|
||||||
automáticamente las opciones modificadas, y sólo
|
|
||||||
recompilará los ficheros donde sea necesario. Eliminando el
|
|
||||||
anterior directorio de compilación en cada ocasión que
|
|
||||||
se ejecute &man.config.8; como es llevado a cabo ahora.</para>
|
|
||||||
|
|
||||||
<para>Básicamente, una opción del kernel no es otra cosa
|
|
||||||
que la definición de un macro del preprocesador C para el
|
|
||||||
proceso de compilación del kernel. Para efecto de hacer que la
|
|
||||||
compilació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ón
|
|
||||||
pueden modificarse con la opció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ón, deja sin efecto el valor que se
|
|
||||||
tiene originalmente por default, y lo substituye con este nuevo
|
|
||||||
valor. Claramente el nuevo valor será utilizado como
|
|
||||||
substituto en el código fuente, cuando el preprocesador se
|
|
||||||
ejecute, por lo que debe de tratarse de una expresión
|
|
||||||
válida para el lenguaje C, sin importar el contexto en el que
|
|
||||||
se haya estado usando el valor por default.</para>
|
|
||||||
|
|
||||||
<para>También es posible crear opciones de menor valor, que
|
|
||||||
simplemente habilitan o deshabilitan una parte particular del
|
|
||||||
código, al encerrarlo en él</para>
|
|
||||||
|
|
||||||
<programlisting>#ifdef ESTA_OPCION
|
|
||||||
|
|
||||||
[su código aqui]
|
|
||||||
|
|
||||||
#endif</programlisting>
|
|
||||||
|
|
||||||
<para>Simplemente al incluir <literal>ESTA_OPCION</literal> en su
|
|
||||||
fichero de configuración (con o sin valor alguno), activará
|
|
||||||
la parte del código que haya ingresado.</para>
|
|
||||||
|
|
||||||
<para>Para la gente que este familiarizada con el lenguaje C, inmediatamente
|
|
||||||
podrá darse cuenta de que todo pudiera ser tratado como una
|
|
||||||
<quote>opción de configuració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ón, y que posteriormente
|
|
||||||
se pregunten por que fallo la compilación del kernel.</para>
|
|
||||||
|
|
||||||
<para>Es claro que, el uso de nombres arbitrarios para las opciones,
|
|
||||||
hacen muy difícil el poder rastrear su uso en el código
|
|
||||||
del kernel. Lo anterior es el razonamiento detrás del esquema
|
|
||||||
de opciones de <emphasis>nuevo-estilo</emphasis>, donde cada opción
|
|
||||||
se localiza en un fichero <filename>.h</filename> diferente dentro del
|
|
||||||
directorio de compilación del kernel, los cuales por
|
|
||||||
convicció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ón ha cambiado.</para>
|
|
||||||
|
|
||||||
<para>Aun con esto los mecanismos del estilo-viejo, tienen una ventaja
|
|
||||||
para las opciones locales o quizás para las opciones de
|
|
||||||
experimentación, que cuentan con un periodo de vida corto:
|
|
||||||
en virtud de que es fácil añadir un nuevo
|
|
||||||
<literal>#ifdef</literal> al código fuente del kernel, lo cual
|
|
||||||
ya lo ha hecho una opción de configuración del kernel. En
|
|
||||||
este caso, al utilizar esta opción, el administrador, es
|
|
||||||
responsable por completo, al tener conocimiento de las implicaciones
|
|
||||||
que tiene usarla (y probablemente el forzar la recompilación de
|
|
||||||
ciertas partes del kernel). Una vez que la transición de
|
|
||||||
todas las opciones soportadas por el kernel ha finalizado, &man.config.8;
|
|
||||||
advertirá cuando una opción no soportada aparezca en el
|
|
||||||
fichero de configuración, y no procederá a incluirlo
|
|
||||||
en el fichero Makefile del kernel.</para>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1>
|
|
||||||
<title>Ahora, ¿Qué Debo Hacer?</title>
|
|
||||||
|
|
||||||
<para>Lo primero es, editar el fichero <filename>sys/conf/options</filename>
|
|
||||||
(o bien <filename>sys/<replaceable><arch></replaceable>/conf/options.
|
|
||||||
<replaceable><arch></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ón, para su inclusión.</para>
|
|
||||||
|
|
||||||
<para>Si ya existiese alguno, que se acerce al propósito de la
|
|
||||||
nueva opció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ón en el fichero apropiado, digamos
|
|
||||||
<literal>FOO</literal>, implica que el valor correspondiente a esta
|
|
||||||
opció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ón no existiera, invente un nuevo nombre. Creelo de
|
|
||||||
manera que sea intuitivo, con significado, y comente la nueva
|
|
||||||
sección en el fichero
|
|
||||||
<filename>options[<replaceable>.<arch></replaceable>]</filename>.
|
|
||||||
En la ejecución de &man.config.8;, este automágicamente
|
|
||||||
reconocerá los cambios, y creará ese fichero, la
|
|
||||||
próxima vez que se ejecute. La mayoría de las opciones
|
|
||||||
deberá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á como resultado la creación de un buen numero de
|
|
||||||
ficheros del kernel, durante la compilación, cuando sólo
|
|
||||||
se haya realizado un cambio en alguna de las opciones del fichero de
|
|
||||||
configuración del kernel, por esta
|
|
||||||
razón es conveniente conservar cada opción en su
|
|
||||||
propio fichero <filename>opt_</filename>.</para>
|
|
||||||
|
|
||||||
<para>Finalmente, averigue las dependencias que existen para la
|
|
||||||
nueva opción. A menos que la nueva opción sea de
|
|
||||||
nueva creació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á como resultado un listado de
|
|
||||||
ficheros que tienen dependecia, dirijase a todos esos ficheros y
|
|
||||||
añada lo siguiente, en la parte <emphasis>superior</emphasis>
|
|
||||||
(como encabezado), antes de todo lo que se refiere a
|
|
||||||
<literal>#include <xxx.h></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ón, de los
|
|
||||||
ficheros normales del tipo <quote>#include</quote>
|
|
||||||
(N de T: librerís de encabezado), si
|
|
||||||
estos son del tipo:</para>
|
|
||||||
|
|
||||||
<programlisting> #ifndef NUEVA_OPCION #define NUEVA_OPCION (algo)
|
|
||||||
#endif</programlisting>
|
|
||||||
|
|
||||||
<para>El añadir una opción que substituye algú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á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ón. Si, existen antecedentes de esto en este momento,
|
|
||||||
pero eso no lo hace má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:
|
|
||||||
-->
|
|
||||||
|
|
Loading…
Reference in a new issue