Include sections:
- Directory policies - Kernel panics - dlsym() - Kernel address space
This commit is contained in:
parent
78515fb620
commit
e9ed3cf4c8
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/head/; revision=4583
3 changed files with 1104 additions and 21 deletions
|
@ -1,4 +1,4 @@
|
|||
<!-- $Id: hackers.sgml,v 1.5 1999-01-29 19:31:06 jesusr Exp $ -->
|
||||
<!-- $Id: hackers.sgml,v 1.6 1999-03-29 18:46:28 jesusr Exp $ -->
|
||||
<!-- The FreeBSD Documentation Spanish Project -->
|
||||
<sect>
|
||||
<heading>Sólo para hackers serios de FreeBSD<label id="hackers">
|
||||
|
@ -168,13 +168,87 @@
|
|||
<p>Y gracias por pensar en nosotros!
|
||||
|
||||
<sect1>
|
||||
<heading>Soportará FreeBSD otras arquitecturas?</heading>
|
||||
<heading>Cómo se detectan e inicializan las tarjetas ISA y PnP?</heading>
|
||||
|
||||
<p>Diferentes grupos de trabajo nos han expresado su interés en
|
||||
trabajar en el soporte multi-artquitectura para FreeBSD y algunas
|
||||
personas están actualmente trabajando en portar FreeBSD a ALPHA,
|
||||
con la cooperación de DEC. Para discusiones generales sobre
|
||||
nuevas arquietecturas, usa la lista <tt><platforms@FreeBSD.ORG></tt>
|
||||
<p>Brevemente, hay unos cuantos puertos de entrada/salida a los que
|
||||
todas las tarjetas PnP responden cuando el ordenador pregunta si hay
|
||||
alguien ahí. Así, cuando comienza la rutina de prueba
|
||||
de PnP, pregunta si hay alguna tarjeta PnP presente y todas las
|
||||
tarjetas responden con su número de modelo a una lectura I/O
|
||||
del mismo puerto. Así el código de prueba puede conocer
|
||||
el ID de cada tarjeta (asignado por Microsoft/Intel).
|
||||
|
||||
<p>Los ID's son dos campos de 32 bits (2ˆ64) + 8 bits de
|
||||
checksum. Los primeros 32 bits son el identificador del fabricante.
|
||||
No se ha dicho publicamente, pero parece estar asumido que diferentes
|
||||
tipos de tarjeta del mismo fabricante pueden tener diferentes id's de
|
||||
fabricante. La idea de necesitar 32 bits sólo para los
|
||||
fabricantes parece un poco excesiva.
|
||||
|
||||
<p>La parte baja de 32 bits son un número de serie,
|
||||
dirección ethernet, algo que haga a la tarjeta única. El
|
||||
fabricante no debe producir nunca una segunda tarjeta que tenga los
|
||||
mismos 32 bits de la parte baja, aunque los 32 bits de la parte alta sean
|
||||
diferentes. Así puedes tener múltiples tarjetas del mismo
|
||||
tipo en la misma máquina y los 64 bits serán únicos
|
||||
para cada tarjeta.
|
||||
|
||||
<p>Los grupos de 32 bits nunca pueden ser todos cero. Esto permite
|
||||
mostrar todos los bits no-cero durante la búsqueda binaria
|
||||
inicial.
|
||||
|
||||
<p>Una vez el sistema ha identificado todos los ID's de las tarjetas
|
||||
presentes, reactivaráa cada tarjeta, una tras otra (a
|
||||
través de los mismos puertos I/O), y encontrará los
|
||||
recursos que cada tarjeta necesita, que opciones de interrupción
|
||||
están disponibles, etc. Se realiza un escaneo sobre todas y cada
|
||||
una de las tarjetas presentes para conocer esta información.
|
||||
|
||||
<p>Esta información se combina con la información de los
|
||||
ficheros ECU del disco y con las BIOS MLB. El soporte PnP de ECU y las
|
||||
BIOS para hardware en el MLB usualmente es sintético, y los
|
||||
periféricos no hacen PnP genuino. De todas maneras, examinando
|
||||
la información de la BIOS más la información
|
||||
ECU, la rutina de prueba puede causar que los dispositivos que no son
|
||||
PnP puedan evitar a esos dispositivos que el código de prueba
|
||||
no puede volver a posicionar.
|
||||
|
||||
<p>Así, los dispositivos PnP son visitados una vez más
|
||||
y se les asigna su I/O, DMA, IRQ, direcciones del mapa de memoria. Los
|
||||
dispositivos aparecerán en esas direcciones y permanecerán
|
||||
en ellas hasta que se vuelva a reinicializar la máquina.
|
||||
|
||||
<p>Todo el proceso se ha simplificado mucho, pero espero que hayas podido
|
||||
hacerte una idea del proceso.
|
||||
|
||||
<sect1>
|
||||
<heading>Soportar FreeBSD arquitecturas diferentes a x86?</heading>
|
||||
|
||||
<p>Diferentes grupos de personas han expresado su interés en
|
||||
trabajar en un port multi-arquitectura de FreeBSD y FreeBSD/AXP
|
||||
(ALPHA) es un ejemplo de ese esfuerzo realizado, ahora disponible en
|
||||
forma de 3.0 SNAPshot release en <url
|
||||
url="ftp://ftp.freebsd.org/pub/FreeBSD/alpha/"
|
||||
name="ftp://ftp.freebsd.org/pub/FreeBSD/alpha">. El port de ALPHA
|
||||
funciona actualmente en diferentes tipos de máquinas ALPHA,
|
||||
entre ellas, AlphaStation, AXPpci, PC164, Miata y Multia. Este port
|
||||
todavía no se considera una release completa y no lo será
|
||||
hasta que exista una colección completa de herramientas de
|
||||
instalación y una distribución completa en cdrom para
|
||||
instalació, incluyendo un número razonable de ports y
|
||||
packages funcionales. FreeBSD/AXP debe considerarse software de
|
||||
calidad BETA en estos momentos. Para más información del
|
||||
proyecto, subscríbete a la
|
||||
<tt><freebsd-alpha@FreeBSD.ORG></tt><ref id="mailing"
|
||||
name="lista de correo">.
|
||||
|
||||
También se ha expresado interés en un port de FreeBSD para
|
||||
arquitectura SPARC. Subscríbete a
|
||||
<tt><freebsd-sparc@FreeBSD.ORG></tt> <ref id="mailing"
|
||||
name="la lista"> si estás interesado en participar en el proyecto.
|
||||
Para discusiones generales en nuevas arquitecturas, participa en
|
||||
<ref id="mailing" name="la lista">
|
||||
<tt><freebsd-platforms@FreeBSD.ORG></tt>.
|
||||
|
||||
<sect1>
|
||||
<heading>Necesito un numero de dispositivo para un driver propio</heading>
|
||||
|
@ -188,6 +262,293 @@
|
|||
crear cualquier fichero especial que use tu dispositivo. Puedes enviar
|
||||
todo lo necesario a <tt><freebsd-hackers@FreeBSD.ORG></tt>.
|
||||
|
||||
<sect1>
|
||||
<heading>Alternativas a la política de directorios</heading>
|
||||
|
||||
<p>En respuesta a esta pregunta de políticas alternativas
|
||||
para los directorios, el esquema que está actualmente en uso
|
||||
no ha cambiado desde que lo escribí en 1983. Escribí esa
|
||||
política para el sistema de ficheros rápido original, y
|
||||
nunca se ha revisado. Trabaja bién manteniendo los grupos de
|
||||
cilindros. Como muchos de vosotros habreis notado, el rendimiento es
|
||||
muy pobre con "find". Muchos sistemas de ficheros son creados desde
|
||||
archivos que fueron creados por una primera búsqueda en
|
||||
profundidad (también conocido como ftw). Estos directorios
|
||||
terminan esparcidos a través de los grupos de cilindros. Si
|
||||
conociesemos el número total de directorios a crear, la
|
||||
solución sería crear (total / fs_ncg) por grupo de
|
||||
cilindros antes de moverlos. Obviamente, tendriamos que crear
|
||||
algún tipo de heurística para adivinar este número.
|
||||
Usando un número pequeño fijo (como puede ser
|
||||
10) haría de orden de magnitud. Para diferencial restores de
|
||||
operaciones normales (cuando el algoritmo actual es probablemente
|
||||
más sensible), podrís usar el clustering hasta 10 si
|
||||
fueran todos hechos dentro de una ventana de diez segundos. De cualquier
|
||||
manera, mi conclusión es que este es un área para la
|
||||
experimentación.</p>
|
||||
|
||||
<p>Kirk McKusick, Septiembre 1998</p>
|
||||
|
||||
<sect1>
|
||||
<heading>Obtener todo lo posible de un "kernel panic"</heading>
|
||||
|
||||
<p>
|
||||
<em>[Esta sección fue extraida de un mensaje escrito por <url
|
||||
url="mailto:wpaul@FreeBSD.ORG" name="Bill Paul"> en la
|
||||
<ref id="mailing" name="lista"> freebsd-current por <url
|
||||
url="mailto:des@FreeBSD.ORG" name="Dag-Erling Coïdan
|
||||
Smørgrav">, quién a fijado algunos errores y
|
||||
añadido algunos comentarios entre corchetes]</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> envió el siguiente panic]</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>[Cuando] ves un mensaje como este, no es suficiente con solo
|
||||
reproducirlo y enviarlo. El valor del puntero de instrucciones que
|
||||
he marcado arriba es importante; desafortunadamente, depende de la
|
||||
configuración. En otras palabras, el valor varía
|
||||
dependiendo de la imáden de kernel exacta que se use. Si
|
||||
estás usando el kernel GENERIC de uno de los snapshots, entonces
|
||||
es posible que alguien pueda seguir la función
|
||||
problemática, pero si estás usando un kernel
|
||||
personalizado, entonces solo <em>tú</em> puedes decirnos donde
|
||||
ha ocurrido el fallo.
|
||||
|
||||
<p>Tendrías que hacer lo siguiente:
|
||||
|
||||
<itemize>
|
||||
<item>Anotar el valor del puntero de la instrucción. Ten en
|
||||
cuenta la parte <tt/0x8:/ al inicio no es significante en este caso:
|
||||
es la parte <tt/0xf0xxxxxx/ la que queremos.
|
||||
<item>Cuando el sistema rearranca, haz lo siguiente:
|
||||
<verb>
|
||||
% nm /kernel.that.caused.the.panic | grep f0xxxxxx
|
||||
</verb>
|
||||
donde <tt/f0xxxxxx/ es el valor del puntero de la instrucción.
|
||||
El problema es que no obtendrás una búsqueda exacta ya
|
||||
que los símbolos en la tabla de símbolos del kernel
|
||||
son para los puntos de entrada de las funciones y la dirección
|
||||
del puntero de la instrucción estará en algún
|
||||
lugar dentro de una función, no al principio. Si no obtienes
|
||||
un resultado exacto, omite el último dígito del valor
|
||||
del puntero de la instrucción e intentalo otra vez, por
|
||||
ejemplo:
|
||||
<verb>
|
||||
% nm /kernel.that.caused.the.panic | grep f0xxxxx
|
||||
</verb>
|
||||
Si esto no da ningún resultado, elimina otro dígito.
|
||||
Repite la operación hasta que obtengas algún tipo de
|
||||
salida. El resultado será una lista de posibles funciones
|
||||
que causan el panic. Este no es un sistema muy exacto de
|
||||
búsqueda de errores, pero es mejor que nada.
|
||||
</itemize>
|
||||
|
||||
<p>Veo gente que constantemente envía mensajes de panics como
|
||||
este, pero raramente veo que alguien se tome el tiempo de buscar
|
||||
la coincidencia entre el puntero de instrucción y una
|
||||
función en la tabla de símbolos del kernel.
|
||||
|
||||
<p>La mejor manera de hacer el seguimiento de la causa de un panic es
|
||||
capturar un "crash dump", usando <tt/gdb(1)/ para hacer una traza del
|
||||
"crash dump". Por supuesto, esto depende de que <tt/gdb(1)/ funcione
|
||||
correctamente en -current, lo que no puedo garantizar (recuerdo que
|
||||
alguien ha comentado que el nuevo <tt/gdb(1)/ en formato ELF no
|
||||
manejaba bién los "dumps" de un crash del kernel; alguién
|
||||
debería mirar esto antes de que la 3.0 salga del estado beta).
|
||||
|
||||
<p>En cualquier caso, el método que normalmente uso es este:
|
||||
|
||||
<itemize>
|
||||
<item>Crear un fichero de configuración de kernel, opcionalmente
|
||||
añadiendo 'options DDB' si piensas que necesitas el debugger
|
||||
del kernel por algún motivo. (Uso esto principalmente para
|
||||
configurar puntos de salida si sospecho que existe alguna
|
||||
condición que crea un loop infinito).
|
||||
<item>Usar <tt/config -g KERNELCONFIG/ para crear el directorio
|
||||
de configuración del kernel.
|
||||
<item><tt>cd /sys/compile/KERNELCONFIG; make</tt>
|
||||
<item>Esperar a que el kernel termine de compilar.
|
||||
<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>[Nota: ahora que los kernels de FreeBSD 3.x son ELF por defecto
|
||||
debes usar <tt/strip -g/ en lugar de <tt/strip -d/. Si por algún
|
||||
motivo tu kernel es aún a.out, usa <tt/strip -aout -d/.]</em>
|
||||
|
||||
<p>Ten en cuenta que TU <em/NO/ QUIERES ARRANCAR CON UN KERNEL QUE TIENE
|
||||
TODOS LOS SIMBOLOS DE DEBUG EN EL. Un kernel compilado con <tt/-g/
|
||||
puede llegar facilmente a los 10MB de tamaño. No tienes que
|
||||
arrancar esta imán masiva, solo lo necesitas para poder usar
|
||||
después <tt/gdb(1)/ (<tt/gdb(1)/ quiere la tabla de
|
||||
símbolos). Al contrario, quieres mantener una copia de la
|
||||
imágen completa y crear una segunda imágen con los
|
||||
símbolos de debug desactivados usando <tt/strip -d/. Es esta
|
||||
segunda imágen la que quieres arrancar.
|
||||
|
||||
<p>Para asegurarte de capturar un "crash dump", necesitas editar el
|
||||
fichero <tt>/etc/rc.conf</tt> y apuntar <tt/dumpdev/ a tu
|
||||
partición de swap. Esto hará que el script <tt/rc(8)/ use
|
||||
el comando <tt/dumpon(8)/ para activar los "crash dumps". También
|
||||
puedes ejecutar manualmente <tt/dumpon(8)/. Después de un panic,
|
||||
el "crash dump" puede ser recuperado usando <tt/savecore(8)/; si
|
||||
<tt/dumpdev/ está en <tt>/etc/rc.conf</tt>, el script
|
||||
<tt/rc(8)/ ejecutará <tt/savecore(8)/ automaticamente y
|
||||
pondrá el "crash dump" en <tt>/var/crash</tt>.
|
||||
|
||||
<p>NOTA: los "crash dumps" de FreeBSD suelen tener el mismo
|
||||
tamaño que la cantidad total de memoria física del
|
||||
sistema. Esto significa que si tienes 64MB de RAM, obtendrás
|
||||
un "crash dump" de 64MB. Debido a esto, tienes que asegurarte de tener
|
||||
suficiente espacio libre en <tt>/var/crash</tt>. Alternativamente puedes
|
||||
ejecutar <tt/savecore(8)/ manualmente y hacer la recuparación en
|
||||
otro directorio donde tengas más espacio libre. Es posible
|
||||
limitar el tamaño del "crash dump" usando <tt/options MAXMEM=(foo)/
|
||||
para indicar la cantidad de memoria que el kernel puede ocupar. Por
|
||||
ejemplo, si tienes 128MB de RAM, puedes limitar el uso de memoria del
|
||||
kernel a 16MB para que el "crash dump" sea de 16MB y no de 128MB.
|
||||
|
||||
<p>Una vez hayas recuperado el "crash dump", puedes obtener una traza
|
||||
del stack con <tt/gdb(1)/ de la manera siguiente:
|
||||
|
||||
<p>
|
||||
<verb>
|
||||
% gdb -k /sys/compile/KERNELCONFIG/kernel.debug /var/crash/vmcore.0
|
||||
(gdb) where
|
||||
</verb>
|
||||
|
||||
<p>Es posible que aparezcan muchas líneas de información:
|
||||
es una buena idea usar el comando <tt/script(1)/ para capturarlas
|
||||
todas. Usando la imágen del kernel con todos los símbolos
|
||||
de debug deberí mostrar la línea exacta de código
|
||||
fuente del kernel donde ha ocurrido el panic. Normalmente, tienes que
|
||||
leer la traza del stack de abajo hacia arriba para poder conocer la
|
||||
secuencia exacta de eventos que han provocado el crash. También
|
||||
puedes usar <tt/gdb(1)/ para mostrar los contenidos de las diferentes
|
||||
variables o estructuras para examinar el estado del sistema en el
|
||||
momento del crash.
|
||||
|
||||
<p>Ahora, si eres realmente curioso y tienes un segundo ordenador,
|
||||
puedes configurar <tt/gdb(1)/ para hacer un debug remoto de manera
|
||||
que puedes usar <tt/gdb(1)/ en un sistema para revisar el kernel
|
||||
de otro sistema, de la misma manera que lo harías en la
|
||||
máquina local.
|
||||
|
||||
<p><em>[Bill añade: "Olvidé mencionar una cosa: si tienes
|
||||
DDB activado, puedes forzar un panic (y un crash dump) tecleando
|
||||
"panic" en el prompt del ddb. Es posible que el debugger se pare
|
||||
durante la fase del panic. Si esto ocurre, teclea "continue" y el
|
||||
crash dump finalizará"]</em>
|
||||
|
||||
<sect1>
|
||||
<heading>dlsym() no funciona con ejecutables ELF!</heading>
|
||||
|
||||
<p>Las herramientas ELF no hacen por defecto que los símbolos
|
||||
definidos en un ejecutable sean visibles por el linker dinámico.
|
||||
Consecuentemente, <tt/dlsym()/ buscará en datos obtenidos desde
|
||||
llamadas a <tt>dlopen(NULL, flags)</tt>, lo que provoca que no se
|
||||
encuentren esos símbolos.
|
||||
|
||||
<p>Si quieres buscar, usando <tt/dlsym()/ símbolos presentes
|
||||
en el ejecutable principal de un proceso, necesitas linkar el
|
||||
ejecutable usando la opción <tt>-export-dynamic</tt> en el
|
||||
<htmlurl url="http://www.freebsd.org/cgi/man.cgi?ld"
|
||||
name="linkador ELF">.
|
||||
|
||||
<sect1>
|
||||
<heading>Incrementando o reduciendo el espacio de direcciones del
|
||||
kernel</heading>
|
||||
|
||||
<p>Por defecto, el espacio de direcciones del kernel es de 256MB en
|
||||
FreeBSD 3.x y 1GB en FreeBSD 4.x. Si gestionas un servidor de red
|
||||
muy cargado (por ejemplo, servidores FTP o HTTP con mucho
|
||||
tráfico), es posible que encuentres que 256MB no es
|
||||
suficiente.
|
||||
|
||||
<p>Así que... como incremento el espacio de direcciones?. Hay
|
||||
dos aspectos a tener en cuenta. Primero, necesitas indicarle al kernel
|
||||
que reserve una parte mayor del espacio de direcciones para él
|
||||
mismo. Segundo, ya que el kernel se carga al inicio del espacio de
|
||||
direcciones, necesitas disminuir la dirección de carga.
|
||||
|
||||
<p>El primer aspecto lo solucionamos incrementando el valor de
|
||||
<tt/NKPDE/ en <tt>src/sys/i386/include/pmap.h</tt>. Este es una entrada
|
||||
de ejemplo para 1GB de espacio de direcciones:
|
||||
|
||||
<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>Para encontrar el valor correcto de <tt/NKPDE/, divide el espacio de
|
||||
direcciones deseado (en megabytes) por cuatro, después resta uno
|
||||
por UP y dos por SMP.
|
||||
|
||||
<p>Para solucionar el segundo aspecto, necesitas calcular la
|
||||
dirección correcta de carga: simplemente resta el tamaño
|
||||
del espacio de direcciones (en bytes) de 0x100100000; el resultado
|
||||
es 0xc0100000 para 1GB de espacio de direcciones. Ajusta
|
||||
<tt/LOAD_ADDRESS/ en <tt>src/sys/i386/conf/Makefile.i386</tt> a ese
|
||||
valor; a continuación pon el contador al inicio de la
|
||||
sección al mismo valor, como sigue:
|
||||
|
||||
<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>Reconfigura y compial el kernel. Probablemente tengas problemas con
|
||||
<tt/top(1)/, <tt/ps(1)/ y programas así; haciendo un
|
||||
<tt/make world/ deberín solucionarse esos problemas (o una
|
||||
recompilación manual de <tt/libkvm/, <tt/ps/ y <tt/top/
|
||||
después de copiar el <tt/pmap.h/ parcheado a
|
||||
<tt>/usr/include/vm/</tt>.
|
||||
|
||||
<p>NOTA: el tamaño del espacio de direcciones debe ser un
|
||||
múltiplo de cuatro megabytes.
|
||||
|
||||
<p><em>[<url url="mailto:dg@freebsd.org" name="David Greenman">
|
||||
añade:</em> Pienso que el espacio de direcciones del kernel
|
||||
necesita ser una potenica de 2, pero no estoy totalmente seguro.
|
||||
|
||||
</sect>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!-- $Id: hackers.sgml,v 1.5 1999-01-29 19:31:06 jesusr Exp $ -->
|
||||
<!-- $Id: hackers.sgml,v 1.6 1999-03-29 18:46:28 jesusr Exp $ -->
|
||||
<!-- The FreeBSD Documentation Spanish Project -->
|
||||
<sect>
|
||||
<heading>Sólo para hackers serios de FreeBSD<label id="hackers">
|
||||
|
@ -168,13 +168,87 @@
|
|||
<p>Y gracias por pensar en nosotros!
|
||||
|
||||
<sect1>
|
||||
<heading>Soportará FreeBSD otras arquitecturas?</heading>
|
||||
<heading>Cómo se detectan e inicializan las tarjetas ISA y PnP?</heading>
|
||||
|
||||
<p>Diferentes grupos de trabajo nos han expresado su interés en
|
||||
trabajar en el soporte multi-artquitectura para FreeBSD y algunas
|
||||
personas están actualmente trabajando en portar FreeBSD a ALPHA,
|
||||
con la cooperación de DEC. Para discusiones generales sobre
|
||||
nuevas arquietecturas, usa la lista <tt><platforms@FreeBSD.ORG></tt>
|
||||
<p>Brevemente, hay unos cuantos puertos de entrada/salida a los que
|
||||
todas las tarjetas PnP responden cuando el ordenador pregunta si hay
|
||||
alguien ahí. Así, cuando comienza la rutina de prueba
|
||||
de PnP, pregunta si hay alguna tarjeta PnP presente y todas las
|
||||
tarjetas responden con su número de modelo a una lectura I/O
|
||||
del mismo puerto. Así el código de prueba puede conocer
|
||||
el ID de cada tarjeta (asignado por Microsoft/Intel).
|
||||
|
||||
<p>Los ID's son dos campos de 32 bits (2ˆ64) + 8 bits de
|
||||
checksum. Los primeros 32 bits son el identificador del fabricante.
|
||||
No se ha dicho publicamente, pero parece estar asumido que diferentes
|
||||
tipos de tarjeta del mismo fabricante pueden tener diferentes id's de
|
||||
fabricante. La idea de necesitar 32 bits sólo para los
|
||||
fabricantes parece un poco excesiva.
|
||||
|
||||
<p>La parte baja de 32 bits son un número de serie,
|
||||
dirección ethernet, algo que haga a la tarjeta única. El
|
||||
fabricante no debe producir nunca una segunda tarjeta que tenga los
|
||||
mismos 32 bits de la parte baja, aunque los 32 bits de la parte alta sean
|
||||
diferentes. Así puedes tener múltiples tarjetas del mismo
|
||||
tipo en la misma máquina y los 64 bits serán únicos
|
||||
para cada tarjeta.
|
||||
|
||||
<p>Los grupos de 32 bits nunca pueden ser todos cero. Esto permite
|
||||
mostrar todos los bits no-cero durante la búsqueda binaria
|
||||
inicial.
|
||||
|
||||
<p>Una vez el sistema ha identificado todos los ID's de las tarjetas
|
||||
presentes, reactivaráa cada tarjeta, una tras otra (a
|
||||
través de los mismos puertos I/O), y encontrará los
|
||||
recursos que cada tarjeta necesita, que opciones de interrupción
|
||||
están disponibles, etc. Se realiza un escaneo sobre todas y cada
|
||||
una de las tarjetas presentes para conocer esta información.
|
||||
|
||||
<p>Esta información se combina con la información de los
|
||||
ficheros ECU del disco y con las BIOS MLB. El soporte PnP de ECU y las
|
||||
BIOS para hardware en el MLB usualmente es sintético, y los
|
||||
periféricos no hacen PnP genuino. De todas maneras, examinando
|
||||
la información de la BIOS más la información
|
||||
ECU, la rutina de prueba puede causar que los dispositivos que no son
|
||||
PnP puedan evitar a esos dispositivos que el código de prueba
|
||||
no puede volver a posicionar.
|
||||
|
||||
<p>Así, los dispositivos PnP son visitados una vez más
|
||||
y se les asigna su I/O, DMA, IRQ, direcciones del mapa de memoria. Los
|
||||
dispositivos aparecerán en esas direcciones y permanecerán
|
||||
en ellas hasta que se vuelva a reinicializar la máquina.
|
||||
|
||||
<p>Todo el proceso se ha simplificado mucho, pero espero que hayas podido
|
||||
hacerte una idea del proceso.
|
||||
|
||||
<sect1>
|
||||
<heading>Soportar FreeBSD arquitecturas diferentes a x86?</heading>
|
||||
|
||||
<p>Diferentes grupos de personas han expresado su interés en
|
||||
trabajar en un port multi-arquitectura de FreeBSD y FreeBSD/AXP
|
||||
(ALPHA) es un ejemplo de ese esfuerzo realizado, ahora disponible en
|
||||
forma de 3.0 SNAPshot release en <url
|
||||
url="ftp://ftp.freebsd.org/pub/FreeBSD/alpha/"
|
||||
name="ftp://ftp.freebsd.org/pub/FreeBSD/alpha">. El port de ALPHA
|
||||
funciona actualmente en diferentes tipos de máquinas ALPHA,
|
||||
entre ellas, AlphaStation, AXPpci, PC164, Miata y Multia. Este port
|
||||
todavía no se considera una release completa y no lo será
|
||||
hasta que exista una colección completa de herramientas de
|
||||
instalación y una distribución completa en cdrom para
|
||||
instalació, incluyendo un número razonable de ports y
|
||||
packages funcionales. FreeBSD/AXP debe considerarse software de
|
||||
calidad BETA en estos momentos. Para más información del
|
||||
proyecto, subscríbete a la
|
||||
<tt><freebsd-alpha@FreeBSD.ORG></tt><ref id="mailing"
|
||||
name="lista de correo">.
|
||||
|
||||
También se ha expresado interés en un port de FreeBSD para
|
||||
arquitectura SPARC. Subscríbete a
|
||||
<tt><freebsd-sparc@FreeBSD.ORG></tt> <ref id="mailing"
|
||||
name="la lista"> si estás interesado en participar en el proyecto.
|
||||
Para discusiones generales en nuevas arquitecturas, participa en
|
||||
<ref id="mailing" name="la lista">
|
||||
<tt><freebsd-platforms@FreeBSD.ORG></tt>.
|
||||
|
||||
<sect1>
|
||||
<heading>Necesito un numero de dispositivo para un driver propio</heading>
|
||||
|
@ -188,6 +262,293 @@
|
|||
crear cualquier fichero especial que use tu dispositivo. Puedes enviar
|
||||
todo lo necesario a <tt><freebsd-hackers@FreeBSD.ORG></tt>.
|
||||
|
||||
<sect1>
|
||||
<heading>Alternativas a la política de directorios</heading>
|
||||
|
||||
<p>En respuesta a esta pregunta de políticas alternativas
|
||||
para los directorios, el esquema que está actualmente en uso
|
||||
no ha cambiado desde que lo escribí en 1983. Escribí esa
|
||||
política para el sistema de ficheros rápido original, y
|
||||
nunca se ha revisado. Trabaja bién manteniendo los grupos de
|
||||
cilindros. Como muchos de vosotros habreis notado, el rendimiento es
|
||||
muy pobre con "find". Muchos sistemas de ficheros son creados desde
|
||||
archivos que fueron creados por una primera búsqueda en
|
||||
profundidad (también conocido como ftw). Estos directorios
|
||||
terminan esparcidos a través de los grupos de cilindros. Si
|
||||
conociesemos el número total de directorios a crear, la
|
||||
solución sería crear (total / fs_ncg) por grupo de
|
||||
cilindros antes de moverlos. Obviamente, tendriamos que crear
|
||||
algún tipo de heurística para adivinar este número.
|
||||
Usando un número pequeño fijo (como puede ser
|
||||
10) haría de orden de magnitud. Para diferencial restores de
|
||||
operaciones normales (cuando el algoritmo actual es probablemente
|
||||
más sensible), podrís usar el clustering hasta 10 si
|
||||
fueran todos hechos dentro de una ventana de diez segundos. De cualquier
|
||||
manera, mi conclusión es que este es un área para la
|
||||
experimentación.</p>
|
||||
|
||||
<p>Kirk McKusick, Septiembre 1998</p>
|
||||
|
||||
<sect1>
|
||||
<heading>Obtener todo lo posible de un "kernel panic"</heading>
|
||||
|
||||
<p>
|
||||
<em>[Esta sección fue extraida de un mensaje escrito por <url
|
||||
url="mailto:wpaul@FreeBSD.ORG" name="Bill Paul"> en la
|
||||
<ref id="mailing" name="lista"> freebsd-current por <url
|
||||
url="mailto:des@FreeBSD.ORG" name="Dag-Erling Coïdan
|
||||
Smørgrav">, quién a fijado algunos errores y
|
||||
añadido algunos comentarios entre corchetes]</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> envió el siguiente panic]</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>[Cuando] ves un mensaje como este, no es suficiente con solo
|
||||
reproducirlo y enviarlo. El valor del puntero de instrucciones que
|
||||
he marcado arriba es importante; desafortunadamente, depende de la
|
||||
configuración. En otras palabras, el valor varía
|
||||
dependiendo de la imáden de kernel exacta que se use. Si
|
||||
estás usando el kernel GENERIC de uno de los snapshots, entonces
|
||||
es posible que alguien pueda seguir la función
|
||||
problemática, pero si estás usando un kernel
|
||||
personalizado, entonces solo <em>tú</em> puedes decirnos donde
|
||||
ha ocurrido el fallo.
|
||||
|
||||
<p>Tendrías que hacer lo siguiente:
|
||||
|
||||
<itemize>
|
||||
<item>Anotar el valor del puntero de la instrucción. Ten en
|
||||
cuenta la parte <tt/0x8:/ al inicio no es significante en este caso:
|
||||
es la parte <tt/0xf0xxxxxx/ la que queremos.
|
||||
<item>Cuando el sistema rearranca, haz lo siguiente:
|
||||
<verb>
|
||||
% nm /kernel.that.caused.the.panic | grep f0xxxxxx
|
||||
</verb>
|
||||
donde <tt/f0xxxxxx/ es el valor del puntero de la instrucción.
|
||||
El problema es que no obtendrás una búsqueda exacta ya
|
||||
que los símbolos en la tabla de símbolos del kernel
|
||||
son para los puntos de entrada de las funciones y la dirección
|
||||
del puntero de la instrucción estará en algún
|
||||
lugar dentro de una función, no al principio. Si no obtienes
|
||||
un resultado exacto, omite el último dígito del valor
|
||||
del puntero de la instrucción e intentalo otra vez, por
|
||||
ejemplo:
|
||||
<verb>
|
||||
% nm /kernel.that.caused.the.panic | grep f0xxxxx
|
||||
</verb>
|
||||
Si esto no da ningún resultado, elimina otro dígito.
|
||||
Repite la operación hasta que obtengas algún tipo de
|
||||
salida. El resultado será una lista de posibles funciones
|
||||
que causan el panic. Este no es un sistema muy exacto de
|
||||
búsqueda de errores, pero es mejor que nada.
|
||||
</itemize>
|
||||
|
||||
<p>Veo gente que constantemente envía mensajes de panics como
|
||||
este, pero raramente veo que alguien se tome el tiempo de buscar
|
||||
la coincidencia entre el puntero de instrucción y una
|
||||
función en la tabla de símbolos del kernel.
|
||||
|
||||
<p>La mejor manera de hacer el seguimiento de la causa de un panic es
|
||||
capturar un "crash dump", usando <tt/gdb(1)/ para hacer una traza del
|
||||
"crash dump". Por supuesto, esto depende de que <tt/gdb(1)/ funcione
|
||||
correctamente en -current, lo que no puedo garantizar (recuerdo que
|
||||
alguien ha comentado que el nuevo <tt/gdb(1)/ en formato ELF no
|
||||
manejaba bién los "dumps" de un crash del kernel; alguién
|
||||
debería mirar esto antes de que la 3.0 salga del estado beta).
|
||||
|
||||
<p>En cualquier caso, el método que normalmente uso es este:
|
||||
|
||||
<itemize>
|
||||
<item>Crear un fichero de configuración de kernel, opcionalmente
|
||||
añadiendo 'options DDB' si piensas que necesitas el debugger
|
||||
del kernel por algún motivo. (Uso esto principalmente para
|
||||
configurar puntos de salida si sospecho que existe alguna
|
||||
condición que crea un loop infinito).
|
||||
<item>Usar <tt/config -g KERNELCONFIG/ para crear el directorio
|
||||
de configuración del kernel.
|
||||
<item><tt>cd /sys/compile/KERNELCONFIG; make</tt>
|
||||
<item>Esperar a que el kernel termine de compilar.
|
||||
<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>[Nota: ahora que los kernels de FreeBSD 3.x son ELF por defecto
|
||||
debes usar <tt/strip -g/ en lugar de <tt/strip -d/. Si por algún
|
||||
motivo tu kernel es aún a.out, usa <tt/strip -aout -d/.]</em>
|
||||
|
||||
<p>Ten en cuenta que TU <em/NO/ QUIERES ARRANCAR CON UN KERNEL QUE TIENE
|
||||
TODOS LOS SIMBOLOS DE DEBUG EN EL. Un kernel compilado con <tt/-g/
|
||||
puede llegar facilmente a los 10MB de tamaño. No tienes que
|
||||
arrancar esta imán masiva, solo lo necesitas para poder usar
|
||||
después <tt/gdb(1)/ (<tt/gdb(1)/ quiere la tabla de
|
||||
símbolos). Al contrario, quieres mantener una copia de la
|
||||
imágen completa y crear una segunda imágen con los
|
||||
símbolos de debug desactivados usando <tt/strip -d/. Es esta
|
||||
segunda imágen la que quieres arrancar.
|
||||
|
||||
<p>Para asegurarte de capturar un "crash dump", necesitas editar el
|
||||
fichero <tt>/etc/rc.conf</tt> y apuntar <tt/dumpdev/ a tu
|
||||
partición de swap. Esto hará que el script <tt/rc(8)/ use
|
||||
el comando <tt/dumpon(8)/ para activar los "crash dumps". También
|
||||
puedes ejecutar manualmente <tt/dumpon(8)/. Después de un panic,
|
||||
el "crash dump" puede ser recuperado usando <tt/savecore(8)/; si
|
||||
<tt/dumpdev/ está en <tt>/etc/rc.conf</tt>, el script
|
||||
<tt/rc(8)/ ejecutará <tt/savecore(8)/ automaticamente y
|
||||
pondrá el "crash dump" en <tt>/var/crash</tt>.
|
||||
|
||||
<p>NOTA: los "crash dumps" de FreeBSD suelen tener el mismo
|
||||
tamaño que la cantidad total de memoria física del
|
||||
sistema. Esto significa que si tienes 64MB de RAM, obtendrás
|
||||
un "crash dump" de 64MB. Debido a esto, tienes que asegurarte de tener
|
||||
suficiente espacio libre en <tt>/var/crash</tt>. Alternativamente puedes
|
||||
ejecutar <tt/savecore(8)/ manualmente y hacer la recuparación en
|
||||
otro directorio donde tengas más espacio libre. Es posible
|
||||
limitar el tamaño del "crash dump" usando <tt/options MAXMEM=(foo)/
|
||||
para indicar la cantidad de memoria que el kernel puede ocupar. Por
|
||||
ejemplo, si tienes 128MB de RAM, puedes limitar el uso de memoria del
|
||||
kernel a 16MB para que el "crash dump" sea de 16MB y no de 128MB.
|
||||
|
||||
<p>Una vez hayas recuperado el "crash dump", puedes obtener una traza
|
||||
del stack con <tt/gdb(1)/ de la manera siguiente:
|
||||
|
||||
<p>
|
||||
<verb>
|
||||
% gdb -k /sys/compile/KERNELCONFIG/kernel.debug /var/crash/vmcore.0
|
||||
(gdb) where
|
||||
</verb>
|
||||
|
||||
<p>Es posible que aparezcan muchas líneas de información:
|
||||
es una buena idea usar el comando <tt/script(1)/ para capturarlas
|
||||
todas. Usando la imágen del kernel con todos los símbolos
|
||||
de debug deberí mostrar la línea exacta de código
|
||||
fuente del kernel donde ha ocurrido el panic. Normalmente, tienes que
|
||||
leer la traza del stack de abajo hacia arriba para poder conocer la
|
||||
secuencia exacta de eventos que han provocado el crash. También
|
||||
puedes usar <tt/gdb(1)/ para mostrar los contenidos de las diferentes
|
||||
variables o estructuras para examinar el estado del sistema en el
|
||||
momento del crash.
|
||||
|
||||
<p>Ahora, si eres realmente curioso y tienes un segundo ordenador,
|
||||
puedes configurar <tt/gdb(1)/ para hacer un debug remoto de manera
|
||||
que puedes usar <tt/gdb(1)/ en un sistema para revisar el kernel
|
||||
de otro sistema, de la misma manera que lo harías en la
|
||||
máquina local.
|
||||
|
||||
<p><em>[Bill añade: "Olvidé mencionar una cosa: si tienes
|
||||
DDB activado, puedes forzar un panic (y un crash dump) tecleando
|
||||
"panic" en el prompt del ddb. Es posible que el debugger se pare
|
||||
durante la fase del panic. Si esto ocurre, teclea "continue" y el
|
||||
crash dump finalizará"]</em>
|
||||
|
||||
<sect1>
|
||||
<heading>dlsym() no funciona con ejecutables ELF!</heading>
|
||||
|
||||
<p>Las herramientas ELF no hacen por defecto que los símbolos
|
||||
definidos en un ejecutable sean visibles por el linker dinámico.
|
||||
Consecuentemente, <tt/dlsym()/ buscará en datos obtenidos desde
|
||||
llamadas a <tt>dlopen(NULL, flags)</tt>, lo que provoca que no se
|
||||
encuentren esos símbolos.
|
||||
|
||||
<p>Si quieres buscar, usando <tt/dlsym()/ símbolos presentes
|
||||
en el ejecutable principal de un proceso, necesitas linkar el
|
||||
ejecutable usando la opción <tt>-export-dynamic</tt> en el
|
||||
<htmlurl url="http://www.freebsd.org/cgi/man.cgi?ld"
|
||||
name="linkador ELF">.
|
||||
|
||||
<sect1>
|
||||
<heading>Incrementando o reduciendo el espacio de direcciones del
|
||||
kernel</heading>
|
||||
|
||||
<p>Por defecto, el espacio de direcciones del kernel es de 256MB en
|
||||
FreeBSD 3.x y 1GB en FreeBSD 4.x. Si gestionas un servidor de red
|
||||
muy cargado (por ejemplo, servidores FTP o HTTP con mucho
|
||||
tráfico), es posible que encuentres que 256MB no es
|
||||
suficiente.
|
||||
|
||||
<p>Así que... como incremento el espacio de direcciones?. Hay
|
||||
dos aspectos a tener en cuenta. Primero, necesitas indicarle al kernel
|
||||
que reserve una parte mayor del espacio de direcciones para él
|
||||
mismo. Segundo, ya que el kernel se carga al inicio del espacio de
|
||||
direcciones, necesitas disminuir la dirección de carga.
|
||||
|
||||
<p>El primer aspecto lo solucionamos incrementando el valor de
|
||||
<tt/NKPDE/ en <tt>src/sys/i386/include/pmap.h</tt>. Este es una entrada
|
||||
de ejemplo para 1GB de espacio de direcciones:
|
||||
|
||||
<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>Para encontrar el valor correcto de <tt/NKPDE/, divide el espacio de
|
||||
direcciones deseado (en megabytes) por cuatro, después resta uno
|
||||
por UP y dos por SMP.
|
||||
|
||||
<p>Para solucionar el segundo aspecto, necesitas calcular la
|
||||
dirección correcta de carga: simplemente resta el tamaño
|
||||
del espacio de direcciones (en bytes) de 0x100100000; el resultado
|
||||
es 0xc0100000 para 1GB de espacio de direcciones. Ajusta
|
||||
<tt/LOAD_ADDRESS/ en <tt>src/sys/i386/conf/Makefile.i386</tt> a ese
|
||||
valor; a continuación pon el contador al inicio de la
|
||||
sección al mismo valor, como sigue:
|
||||
|
||||
<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>Reconfigura y compial el kernel. Probablemente tengas problemas con
|
||||
<tt/top(1)/, <tt/ps(1)/ y programas así; haciendo un
|
||||
<tt/make world/ deberín solucionarse esos problemas (o una
|
||||
recompilación manual de <tt/libkvm/, <tt/ps/ y <tt/top/
|
||||
después de copiar el <tt/pmap.h/ parcheado a
|
||||
<tt>/usr/include/vm/</tt>.
|
||||
|
||||
<p>NOTA: el tamaño del espacio de direcciones debe ser un
|
||||
múltiplo de cuatro megabytes.
|
||||
|
||||
<p><em>[<url url="mailto:dg@freebsd.org" name="David Greenman">
|
||||
añade:</em> Pienso que el espacio de direcciones del kernel
|
||||
necesita ser una potenica de 2, pero no estoy totalmente seguro.
|
||||
|
||||
</sect>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!-- $Id: hackers.sgml,v 1.5 1999-01-29 19:31:06 jesusr Exp $ -->
|
||||
<!-- $Id: hackers.sgml,v 1.6 1999-03-29 18:46:28 jesusr Exp $ -->
|
||||
<!-- The FreeBSD Documentation Spanish Project -->
|
||||
<sect>
|
||||
<heading>Sólo para hackers serios de FreeBSD<label id="hackers">
|
||||
|
@ -168,13 +168,87 @@
|
|||
<p>Y gracias por pensar en nosotros!
|
||||
|
||||
<sect1>
|
||||
<heading>Soportará FreeBSD otras arquitecturas?</heading>
|
||||
<heading>Cómo se detectan e inicializan las tarjetas ISA y PnP?</heading>
|
||||
|
||||
<p>Diferentes grupos de trabajo nos han expresado su interés en
|
||||
trabajar en el soporte multi-artquitectura para FreeBSD y algunas
|
||||
personas están actualmente trabajando en portar FreeBSD a ALPHA,
|
||||
con la cooperación de DEC. Para discusiones generales sobre
|
||||
nuevas arquietecturas, usa la lista <tt><platforms@FreeBSD.ORG></tt>
|
||||
<p>Brevemente, hay unos cuantos puertos de entrada/salida a los que
|
||||
todas las tarjetas PnP responden cuando el ordenador pregunta si hay
|
||||
alguien ahí. Así, cuando comienza la rutina de prueba
|
||||
de PnP, pregunta si hay alguna tarjeta PnP presente y todas las
|
||||
tarjetas responden con su número de modelo a una lectura I/O
|
||||
del mismo puerto. Así el código de prueba puede conocer
|
||||
el ID de cada tarjeta (asignado por Microsoft/Intel).
|
||||
|
||||
<p>Los ID's son dos campos de 32 bits (2ˆ64) + 8 bits de
|
||||
checksum. Los primeros 32 bits son el identificador del fabricante.
|
||||
No se ha dicho publicamente, pero parece estar asumido que diferentes
|
||||
tipos de tarjeta del mismo fabricante pueden tener diferentes id's de
|
||||
fabricante. La idea de necesitar 32 bits sólo para los
|
||||
fabricantes parece un poco excesiva.
|
||||
|
||||
<p>La parte baja de 32 bits son un número de serie,
|
||||
dirección ethernet, algo que haga a la tarjeta única. El
|
||||
fabricante no debe producir nunca una segunda tarjeta que tenga los
|
||||
mismos 32 bits de la parte baja, aunque los 32 bits de la parte alta sean
|
||||
diferentes. Así puedes tener múltiples tarjetas del mismo
|
||||
tipo en la misma máquina y los 64 bits serán únicos
|
||||
para cada tarjeta.
|
||||
|
||||
<p>Los grupos de 32 bits nunca pueden ser todos cero. Esto permite
|
||||
mostrar todos los bits no-cero durante la búsqueda binaria
|
||||
inicial.
|
||||
|
||||
<p>Una vez el sistema ha identificado todos los ID's de las tarjetas
|
||||
presentes, reactivaráa cada tarjeta, una tras otra (a
|
||||
través de los mismos puertos I/O), y encontrará los
|
||||
recursos que cada tarjeta necesita, que opciones de interrupción
|
||||
están disponibles, etc. Se realiza un escaneo sobre todas y cada
|
||||
una de las tarjetas presentes para conocer esta información.
|
||||
|
||||
<p>Esta información se combina con la información de los
|
||||
ficheros ECU del disco y con las BIOS MLB. El soporte PnP de ECU y las
|
||||
BIOS para hardware en el MLB usualmente es sintético, y los
|
||||
periféricos no hacen PnP genuino. De todas maneras, examinando
|
||||
la información de la BIOS más la información
|
||||
ECU, la rutina de prueba puede causar que los dispositivos que no son
|
||||
PnP puedan evitar a esos dispositivos que el código de prueba
|
||||
no puede volver a posicionar.
|
||||
|
||||
<p>Así, los dispositivos PnP son visitados una vez más
|
||||
y se les asigna su I/O, DMA, IRQ, direcciones del mapa de memoria. Los
|
||||
dispositivos aparecerán en esas direcciones y permanecerán
|
||||
en ellas hasta que se vuelva a reinicializar la máquina.
|
||||
|
||||
<p>Todo el proceso se ha simplificado mucho, pero espero que hayas podido
|
||||
hacerte una idea del proceso.
|
||||
|
||||
<sect1>
|
||||
<heading>Soportar FreeBSD arquitecturas diferentes a x86?</heading>
|
||||
|
||||
<p>Diferentes grupos de personas han expresado su interés en
|
||||
trabajar en un port multi-arquitectura de FreeBSD y FreeBSD/AXP
|
||||
(ALPHA) es un ejemplo de ese esfuerzo realizado, ahora disponible en
|
||||
forma de 3.0 SNAPshot release en <url
|
||||
url="ftp://ftp.freebsd.org/pub/FreeBSD/alpha/"
|
||||
name="ftp://ftp.freebsd.org/pub/FreeBSD/alpha">. El port de ALPHA
|
||||
funciona actualmente en diferentes tipos de máquinas ALPHA,
|
||||
entre ellas, AlphaStation, AXPpci, PC164, Miata y Multia. Este port
|
||||
todavía no se considera una release completa y no lo será
|
||||
hasta que exista una colección completa de herramientas de
|
||||
instalación y una distribución completa en cdrom para
|
||||
instalació, incluyendo un número razonable de ports y
|
||||
packages funcionales. FreeBSD/AXP debe considerarse software de
|
||||
calidad BETA en estos momentos. Para más información del
|
||||
proyecto, subscríbete a la
|
||||
<tt><freebsd-alpha@FreeBSD.ORG></tt><ref id="mailing"
|
||||
name="lista de correo">.
|
||||
|
||||
También se ha expresado interés en un port de FreeBSD para
|
||||
arquitectura SPARC. Subscríbete a
|
||||
<tt><freebsd-sparc@FreeBSD.ORG></tt> <ref id="mailing"
|
||||
name="la lista"> si estás interesado en participar en el proyecto.
|
||||
Para discusiones generales en nuevas arquitecturas, participa en
|
||||
<ref id="mailing" name="la lista">
|
||||
<tt><freebsd-platforms@FreeBSD.ORG></tt>.
|
||||
|
||||
<sect1>
|
||||
<heading>Necesito un numero de dispositivo para un driver propio</heading>
|
||||
|
@ -188,6 +262,293 @@
|
|||
crear cualquier fichero especial que use tu dispositivo. Puedes enviar
|
||||
todo lo necesario a <tt><freebsd-hackers@FreeBSD.ORG></tt>.
|
||||
|
||||
<sect1>
|
||||
<heading>Alternativas a la política de directorios</heading>
|
||||
|
||||
<p>En respuesta a esta pregunta de políticas alternativas
|
||||
para los directorios, el esquema que está actualmente en uso
|
||||
no ha cambiado desde que lo escribí en 1983. Escribí esa
|
||||
política para el sistema de ficheros rápido original, y
|
||||
nunca se ha revisado. Trabaja bién manteniendo los grupos de
|
||||
cilindros. Como muchos de vosotros habreis notado, el rendimiento es
|
||||
muy pobre con "find". Muchos sistemas de ficheros son creados desde
|
||||
archivos que fueron creados por una primera búsqueda en
|
||||
profundidad (también conocido como ftw). Estos directorios
|
||||
terminan esparcidos a través de los grupos de cilindros. Si
|
||||
conociesemos el número total de directorios a crear, la
|
||||
solución sería crear (total / fs_ncg) por grupo de
|
||||
cilindros antes de moverlos. Obviamente, tendriamos que crear
|
||||
algún tipo de heurística para adivinar este número.
|
||||
Usando un número pequeño fijo (como puede ser
|
||||
10) haría de orden de magnitud. Para diferencial restores de
|
||||
operaciones normales (cuando el algoritmo actual es probablemente
|
||||
más sensible), podrís usar el clustering hasta 10 si
|
||||
fueran todos hechos dentro de una ventana de diez segundos. De cualquier
|
||||
manera, mi conclusión es que este es un área para la
|
||||
experimentación.</p>
|
||||
|
||||
<p>Kirk McKusick, Septiembre 1998</p>
|
||||
|
||||
<sect1>
|
||||
<heading>Obtener todo lo posible de un "kernel panic"</heading>
|
||||
|
||||
<p>
|
||||
<em>[Esta sección fue extraida de un mensaje escrito por <url
|
||||
url="mailto:wpaul@FreeBSD.ORG" name="Bill Paul"> en la
|
||||
<ref id="mailing" name="lista"> freebsd-current por <url
|
||||
url="mailto:des@FreeBSD.ORG" name="Dag-Erling Coïdan
|
||||
Smørgrav">, quién a fijado algunos errores y
|
||||
añadido algunos comentarios entre corchetes]</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> envió el siguiente panic]</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>[Cuando] ves un mensaje como este, no es suficiente con solo
|
||||
reproducirlo y enviarlo. El valor del puntero de instrucciones que
|
||||
he marcado arriba es importante; desafortunadamente, depende de la
|
||||
configuración. En otras palabras, el valor varía
|
||||
dependiendo de la imáden de kernel exacta que se use. Si
|
||||
estás usando el kernel GENERIC de uno de los snapshots, entonces
|
||||
es posible que alguien pueda seguir la función
|
||||
problemática, pero si estás usando un kernel
|
||||
personalizado, entonces solo <em>tú</em> puedes decirnos donde
|
||||
ha ocurrido el fallo.
|
||||
|
||||
<p>Tendrías que hacer lo siguiente:
|
||||
|
||||
<itemize>
|
||||
<item>Anotar el valor del puntero de la instrucción. Ten en
|
||||
cuenta la parte <tt/0x8:/ al inicio no es significante en este caso:
|
||||
es la parte <tt/0xf0xxxxxx/ la que queremos.
|
||||
<item>Cuando el sistema rearranca, haz lo siguiente:
|
||||
<verb>
|
||||
% nm /kernel.that.caused.the.panic | grep f0xxxxxx
|
||||
</verb>
|
||||
donde <tt/f0xxxxxx/ es el valor del puntero de la instrucción.
|
||||
El problema es que no obtendrás una búsqueda exacta ya
|
||||
que los símbolos en la tabla de símbolos del kernel
|
||||
son para los puntos de entrada de las funciones y la dirección
|
||||
del puntero de la instrucción estará en algún
|
||||
lugar dentro de una función, no al principio. Si no obtienes
|
||||
un resultado exacto, omite el último dígito del valor
|
||||
del puntero de la instrucción e intentalo otra vez, por
|
||||
ejemplo:
|
||||
<verb>
|
||||
% nm /kernel.that.caused.the.panic | grep f0xxxxx
|
||||
</verb>
|
||||
Si esto no da ningún resultado, elimina otro dígito.
|
||||
Repite la operación hasta que obtengas algún tipo de
|
||||
salida. El resultado será una lista de posibles funciones
|
||||
que causan el panic. Este no es un sistema muy exacto de
|
||||
búsqueda de errores, pero es mejor que nada.
|
||||
</itemize>
|
||||
|
||||
<p>Veo gente que constantemente envía mensajes de panics como
|
||||
este, pero raramente veo que alguien se tome el tiempo de buscar
|
||||
la coincidencia entre el puntero de instrucción y una
|
||||
función en la tabla de símbolos del kernel.
|
||||
|
||||
<p>La mejor manera de hacer el seguimiento de la causa de un panic es
|
||||
capturar un "crash dump", usando <tt/gdb(1)/ para hacer una traza del
|
||||
"crash dump". Por supuesto, esto depende de que <tt/gdb(1)/ funcione
|
||||
correctamente en -current, lo que no puedo garantizar (recuerdo que
|
||||
alguien ha comentado que el nuevo <tt/gdb(1)/ en formato ELF no
|
||||
manejaba bién los "dumps" de un crash del kernel; alguién
|
||||
debería mirar esto antes de que la 3.0 salga del estado beta).
|
||||
|
||||
<p>En cualquier caso, el método que normalmente uso es este:
|
||||
|
||||
<itemize>
|
||||
<item>Crear un fichero de configuración de kernel, opcionalmente
|
||||
añadiendo 'options DDB' si piensas que necesitas el debugger
|
||||
del kernel por algún motivo. (Uso esto principalmente para
|
||||
configurar puntos de salida si sospecho que existe alguna
|
||||
condición que crea un loop infinito).
|
||||
<item>Usar <tt/config -g KERNELCONFIG/ para crear el directorio
|
||||
de configuración del kernel.
|
||||
<item><tt>cd /sys/compile/KERNELCONFIG; make</tt>
|
||||
<item>Esperar a que el kernel termine de compilar.
|
||||
<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>[Nota: ahora que los kernels de FreeBSD 3.x son ELF por defecto
|
||||
debes usar <tt/strip -g/ en lugar de <tt/strip -d/. Si por algún
|
||||
motivo tu kernel es aún a.out, usa <tt/strip -aout -d/.]</em>
|
||||
|
||||
<p>Ten en cuenta que TU <em/NO/ QUIERES ARRANCAR CON UN KERNEL QUE TIENE
|
||||
TODOS LOS SIMBOLOS DE DEBUG EN EL. Un kernel compilado con <tt/-g/
|
||||
puede llegar facilmente a los 10MB de tamaño. No tienes que
|
||||
arrancar esta imán masiva, solo lo necesitas para poder usar
|
||||
después <tt/gdb(1)/ (<tt/gdb(1)/ quiere la tabla de
|
||||
símbolos). Al contrario, quieres mantener una copia de la
|
||||
imágen completa y crear una segunda imágen con los
|
||||
símbolos de debug desactivados usando <tt/strip -d/. Es esta
|
||||
segunda imágen la que quieres arrancar.
|
||||
|
||||
<p>Para asegurarte de capturar un "crash dump", necesitas editar el
|
||||
fichero <tt>/etc/rc.conf</tt> y apuntar <tt/dumpdev/ a tu
|
||||
partición de swap. Esto hará que el script <tt/rc(8)/ use
|
||||
el comando <tt/dumpon(8)/ para activar los "crash dumps". También
|
||||
puedes ejecutar manualmente <tt/dumpon(8)/. Después de un panic,
|
||||
el "crash dump" puede ser recuperado usando <tt/savecore(8)/; si
|
||||
<tt/dumpdev/ está en <tt>/etc/rc.conf</tt>, el script
|
||||
<tt/rc(8)/ ejecutará <tt/savecore(8)/ automaticamente y
|
||||
pondrá el "crash dump" en <tt>/var/crash</tt>.
|
||||
|
||||
<p>NOTA: los "crash dumps" de FreeBSD suelen tener el mismo
|
||||
tamaño que la cantidad total de memoria física del
|
||||
sistema. Esto significa que si tienes 64MB de RAM, obtendrás
|
||||
un "crash dump" de 64MB. Debido a esto, tienes que asegurarte de tener
|
||||
suficiente espacio libre en <tt>/var/crash</tt>. Alternativamente puedes
|
||||
ejecutar <tt/savecore(8)/ manualmente y hacer la recuparación en
|
||||
otro directorio donde tengas más espacio libre. Es posible
|
||||
limitar el tamaño del "crash dump" usando <tt/options MAXMEM=(foo)/
|
||||
para indicar la cantidad de memoria que el kernel puede ocupar. Por
|
||||
ejemplo, si tienes 128MB de RAM, puedes limitar el uso de memoria del
|
||||
kernel a 16MB para que el "crash dump" sea de 16MB y no de 128MB.
|
||||
|
||||
<p>Una vez hayas recuperado el "crash dump", puedes obtener una traza
|
||||
del stack con <tt/gdb(1)/ de la manera siguiente:
|
||||
|
||||
<p>
|
||||
<verb>
|
||||
% gdb -k /sys/compile/KERNELCONFIG/kernel.debug /var/crash/vmcore.0
|
||||
(gdb) where
|
||||
</verb>
|
||||
|
||||
<p>Es posible que aparezcan muchas líneas de información:
|
||||
es una buena idea usar el comando <tt/script(1)/ para capturarlas
|
||||
todas. Usando la imágen del kernel con todos los símbolos
|
||||
de debug deberí mostrar la línea exacta de código
|
||||
fuente del kernel donde ha ocurrido el panic. Normalmente, tienes que
|
||||
leer la traza del stack de abajo hacia arriba para poder conocer la
|
||||
secuencia exacta de eventos que han provocado el crash. También
|
||||
puedes usar <tt/gdb(1)/ para mostrar los contenidos de las diferentes
|
||||
variables o estructuras para examinar el estado del sistema en el
|
||||
momento del crash.
|
||||
|
||||
<p>Ahora, si eres realmente curioso y tienes un segundo ordenador,
|
||||
puedes configurar <tt/gdb(1)/ para hacer un debug remoto de manera
|
||||
que puedes usar <tt/gdb(1)/ en un sistema para revisar el kernel
|
||||
de otro sistema, de la misma manera que lo harías en la
|
||||
máquina local.
|
||||
|
||||
<p><em>[Bill añade: "Olvidé mencionar una cosa: si tienes
|
||||
DDB activado, puedes forzar un panic (y un crash dump) tecleando
|
||||
"panic" en el prompt del ddb. Es posible que el debugger se pare
|
||||
durante la fase del panic. Si esto ocurre, teclea "continue" y el
|
||||
crash dump finalizará"]</em>
|
||||
|
||||
<sect1>
|
||||
<heading>dlsym() no funciona con ejecutables ELF!</heading>
|
||||
|
||||
<p>Las herramientas ELF no hacen por defecto que los símbolos
|
||||
definidos en un ejecutable sean visibles por el linker dinámico.
|
||||
Consecuentemente, <tt/dlsym()/ buscará en datos obtenidos desde
|
||||
llamadas a <tt>dlopen(NULL, flags)</tt>, lo que provoca que no se
|
||||
encuentren esos símbolos.
|
||||
|
||||
<p>Si quieres buscar, usando <tt/dlsym()/ símbolos presentes
|
||||
en el ejecutable principal de un proceso, necesitas linkar el
|
||||
ejecutable usando la opción <tt>-export-dynamic</tt> en el
|
||||
<htmlurl url="http://www.freebsd.org/cgi/man.cgi?ld"
|
||||
name="linkador ELF">.
|
||||
|
||||
<sect1>
|
||||
<heading>Incrementando o reduciendo el espacio de direcciones del
|
||||
kernel</heading>
|
||||
|
||||
<p>Por defecto, el espacio de direcciones del kernel es de 256MB en
|
||||
FreeBSD 3.x y 1GB en FreeBSD 4.x. Si gestionas un servidor de red
|
||||
muy cargado (por ejemplo, servidores FTP o HTTP con mucho
|
||||
tráfico), es posible que encuentres que 256MB no es
|
||||
suficiente.
|
||||
|
||||
<p>Así que... como incremento el espacio de direcciones?. Hay
|
||||
dos aspectos a tener en cuenta. Primero, necesitas indicarle al kernel
|
||||
que reserve una parte mayor del espacio de direcciones para él
|
||||
mismo. Segundo, ya que el kernel se carga al inicio del espacio de
|
||||
direcciones, necesitas disminuir la dirección de carga.
|
||||
|
||||
<p>El primer aspecto lo solucionamos incrementando el valor de
|
||||
<tt/NKPDE/ en <tt>src/sys/i386/include/pmap.h</tt>. Este es una entrada
|
||||
de ejemplo para 1GB de espacio de direcciones:
|
||||
|
||||
<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>Para encontrar el valor correcto de <tt/NKPDE/, divide el espacio de
|
||||
direcciones deseado (en megabytes) por cuatro, después resta uno
|
||||
por UP y dos por SMP.
|
||||
|
||||
<p>Para solucionar el segundo aspecto, necesitas calcular la
|
||||
dirección correcta de carga: simplemente resta el tamaño
|
||||
del espacio de direcciones (en bytes) de 0x100100000; el resultado
|
||||
es 0xc0100000 para 1GB de espacio de direcciones. Ajusta
|
||||
<tt/LOAD_ADDRESS/ en <tt>src/sys/i386/conf/Makefile.i386</tt> a ese
|
||||
valor; a continuación pon el contador al inicio de la
|
||||
sección al mismo valor, como sigue:
|
||||
|
||||
<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>Reconfigura y compial el kernel. Probablemente tengas problemas con
|
||||
<tt/top(1)/, <tt/ps(1)/ y programas así; haciendo un
|
||||
<tt/make world/ deberín solucionarse esos problemas (o una
|
||||
recompilación manual de <tt/libkvm/, <tt/ps/ y <tt/top/
|
||||
después de copiar el <tt/pmap.h/ parcheado a
|
||||
<tt>/usr/include/vm/</tt>.
|
||||
|
||||
<p>NOTA: el tamaño del espacio de direcciones debe ser un
|
||||
múltiplo de cuatro megabytes.
|
||||
|
||||
<p><em>[<url url="mailto:dg@freebsd.org" name="David Greenman">
|
||||
añade:</em> Pienso que el espacio de direcciones del kernel
|
||||
necesita ser una potenica de 2, pero no estoy totalmente seguro.
|
||||
|
||||
</sect>
|
||||
|
|
Loading…
Reference in a new issue