INTRODUCCIÓN
Si lo que buscáis es una forma rápida de hacer un nuevo kernel para vuestro FreeBSD, podéis bajar directamente la sección COMPILAR pasando de unos antecedentes que a lo mejor ya conocéis o no queréis conocer porque lo que os interesa ahora es, ir directamente al grano.
Si el nuevo kernel no arranca o surge cualquier otro problema, siempre podéis volver sobre vuestros pasos y leer estos párrafos para recuperarlo, si tenéis una copia de este documento en otra computadora o en papel.
Yo por mi parte soy un poco orejudo* y como tal, amo a los árboles y no uso impresora.
OBJETIVO
Hacer un nuevo kernel (núcleo del sistema operativo - en adelante OS), de una forma ¡¡segura!! . Esto es, sin cometer errores graves que impidan el arranque de la máquina o un comportamiento errático del OS.
ANTECEDENTES Software y hardware
Este kernel lo compilamos en un PC portátil que dispone de un microprocesador Intel, modelo: "Mobile Intel(R) Pentium(R) 4 CPU 3.06GHz (3066.79-MHz 686-class CPU) y aunque no garantizo que todo salga igual en máquinas con otros microprocesadores, puedo asegurar que los resultados serán muy parecidos. Es aconsejable que antes de comenzar a configurar lo que va a ser el nuevo kernel, sepamos de que tipo procesador disponemos. Para ello podemos ejecutar la siguiente orden:
# dmesg -a | grep CPU <---- es importante respetar las mayúsculas en el argumento CPU >
El resultado de la ejecución de la orden anterior en la máquina que usamos es este:
CPU: Mobile Intel(R) Pentium(R) 4 CPU 3.06GHz (3066.79-MHz 686-class CPU)
Hyperthreading: 2 logical CPUs
FreeBSD/SMP: Multiprocessor System Detected: 2 CPUs
cpu0:
cpu1:
SMP: AP CPU #1 Launched!
Evidentemente, en otras máquinas puede (y es lo más probable), ser otro. Si leemos con atención la información anterior, vemos que se trata de un chip fabricado y licenciado por la industria Intel (en realidad las empresas que se dedican a la fabricación de estos complejos artilugios, no pasan de media docena en tod o el mundo).
El modelo es Pentium 4 HT. El kernel de esta máquina ya ha sido compilado específicamente con y para este procesador con soporte para SMP (Symmetric MultiProcessor) y como se puede ver detecta perfectamente que dispone de 2 CPU lógicas (que es lo que viene a significar la tecnología Hyperthreading, hoy desplazada por los modelos Centrino). Si disponéis de un
microprocesador de este tipo, es posible que dmesg lo identifique como un Intel Xeon (sobre todo si se trata de un kernel Linux). No es lo mismo, los Xeon disponen de dos CPU "físicas".
ACPI (Advanced Configuration and Power Management support) se encarga de habilitar las CPUs lógicas por separado a partir de ese momento se repartirán la carga de trabajo y si ejecutáis la orden top -S podréis ver que está haciendo cada una de ellas, prácticamente en tiempo real. Existen programas que permiten manejar algunas opciones de estos microprocesadores tan "especiales". De todas formas, las más básicas, las que tienen que ver con el ahorro de energía están previstas en FreeBSD con algunas opciones de configuración adecuadas, como estas líneas:
performance_cx_lowest="LOW" # Online CPU idle state
performance_throttle_state="HIGH" # Online throttling state
economy_cx_lowest="LOW" # Offline CPU idle state
economy_throttle_state="HIGH" # Offline throttling state
que figuran por defecto en vuestro /etc/defauts/rc.conf. Con esta configuración se consigue que las CPUs trabajen sólo cuando o es necesario y generalmente, descansen mucho. De esta forma se reduce el exceso de temperatura, el tiempo de funcionamiento de los extractores de calor y el consumo de energía en general. Algo muy importante cuando las máquinas portátiles funcionan con baterías.
Lo importante, lo que necesitamos saber para el archivo de configuración, está en la primera línea del resultado que arroja el dmesg y es esto: (3066.79-MHz 686-class CPU), exactamente 686. Se trata de chips mejorados para la arquitectura i386. Esta cadena es la que debemos de poner en la segunda línea del archivo de configuración, justo debajo de la primera i386 que es genérica y obligatoria en PCs. De esta forma, el nuevo kernel identificará correctamente el procesador y usará todas sus mejoras y capacidades añadidas.
Es aconsejable leer detenidamente toda la información que ofrece un dmesg -a para añadir en la configuración del nuevo kernel, soporte para los diversos dispositivos de los que nuestra máquina dispone. Para conocer estos dispositivos leed con atención la información que os ofrecerá la siguiente orden:
# pciconf -lv
Veréis entre otras, líneas parecidas a estas:
ohci0@pci0:19:0: class=0x0c0310 card=0xff101179 chip=0x43471002 rev=0x01 hdr=0x00
atapci0@pci0:20:1: class=0x01018a card=0xff101179 chip=0x43491002 rev=0x00 hdr=0x00
isab0@pci0:20:3: class=0x060100 card=0xff101179 chip=0x434c1002 rev=0x00 hdr=0x00
pcib2@pci0:20:4: class=0x060401 card=0x00000000 chip=0x43421002 rev=0x00 hdr=0x01
drm0@pci1:5:0: class=0x030000 card=0xff101179 chip=0x44371002 rev=0x00 hdr=0x00
ath0@pci2:4:0: class=0x020000 card=0x7064144f chip=0x0013168c rev=0x01 hdr=0x00
rl0@pci2:7:0: class=0x020000 card=0xff101179 chip=0x813910ec rev=0x10 hdr=0x00
fwohci0@pci2:10:0: class=0x0c0010 card=0xff101179 chip=0x8026104c rev=0x00 hdr=0x00
que os servirán para saber que debéis añadir soporte para dispositivos USB, ATA, ISA, wifi, ethernet, FireWire y DRI si vuestra tarjeta gráfica soporta aceleración por hardware.
No me extenderé más en este punto, es evidente que cuanta más información tengáis acerca del hardware de la máquina mejor conoceréis las posibilidades que para él provee el archivo de configuración del nuevo kernel y mejores resultados obtendréis. Pero también lo es que, si no sale redondo a la primera, lo conseguiréis en las próximas compilaciones.
FILOSOFÍA
Primero hablaremos de las razones por las que se suele hacer un nuevo kernel. Generalmente, cuando se instala el OS, el kernel que se instala es del tipo GENERIC. De hecho, si tecleáis la orden uname -a, aparecerá algo parecido a esto:
# uname -a FreeBSD elu.thingol 5.3-RELEASE FreeBSD 5.3-RELEASE #0: Sat Nov 19 12:19:28 UTC 2005
Este kernel tiene soporte para una gran cantidad de hardware, de hecho, para el más común. Esto es debido a que los programadores que hacen FreeBSD, saben muy poco del tipo de máquina en la que se instalará el OS. De hecho hacen varias distribuciones para determinados tipos de computadoras, así que suponen que si tenemos un PC instalaremos la distribución que ellos han empaquetado para i386, porque esta es la arquitectura de los PCs.
Tampoco sería posible instalar en un PC una distribución hecha para otras arquitecturas como, Alpha, Sparc64, muy utilizadas en entornos profesionales y grandes servidores con Sun Solaris, *BSD y otros OS tipo UNIX
PowerPC, utilizado en entornos profesionales con IRIX, AS/400 y últimamente Linux, entre otros OS y también en computadoras personales.
Macintosh fabricados por Apple (este tipo de máquinas pronto incorporarán un nuevo chip fabricado por Intel. No se sabe aun si será del tipo i386). Actualmente ya usan un OS FreeBSD modificado y un kernel Match, un microkernel más parecido al proyecto Hurd que GNU construye para ser usado de la misma forma que hoy se usa el kernel Linux en los OS Linux (que actualmente son todos), aunque desde hace pocos meses en los OS GNU/Debian es posible usar también el kernel FreeBSD
pc98 la arquitectura que usan los japoneses, como en los españoles usan PC o la más reciente amd64, microprocesadores de 64 Bits fabricados por la empresa AMD y dedicada a computadoras de uso personal.
Por lo tanto, si un kernel del tipo GENERIC que tenéis después de una instalación estándar, es perfectamente funcional, no hay muchas razones para hacer uno nuevo, excepto que tiene soporte para mucho hardware que en vuestra máquina no existe.
Como consecuencia, es demasiado grande y si tenéis en cuenta que el kernel se carga en los primeros MB de vuestra RAM y permanece en ella durante toda la "sesión", es posible que estéis desperdiciando memoria física.
Otra buena razón para hacer un kernel nuevo (a veces, imprescindible), es la de incluir soporte para algún dispositivo que no está soportado por el GENERIC o que tiene soporte como módulo y es necesario (o queréis) que esté "dentro" del kernel para asegurar un arranque más eficaz o que exista soporte para módulos "dependientes" que serán cargados más adelante.
Algunos usuarios hacen kernel nuevo, simplemente para probar las nuevas características que se van añadiendo al código fuente de las nuevas versiones, pero esto no es aconsejable para los usuarios que "necesiten" leer este HOWTO. Supongamos pues que lo hacéis por cualquiera de las razones anteriores y vamos a ello.
MÉTODO
Algunos creemos que es mejor tener un kernel "pequeño" y muchos módulos, otros creen lo contrario. Ya he mencionado algunas ventajas de tener un kernel pequeño, pero otros piensan que es mejor tener un kernel grande cargado en su memoria. En todo caso no hay razón alguna para tener en el kernel o fuera de el, soporte para dispositivos que vuestra máquina no tiene. Dejo pues a la elección del lector el método que mejor le parezca.
En cuanto al método de compilación, en este HOWTO veremos solamente uno de ellos. Se trata del estándar. Se pueden utilizar otros pero para "empezar" este es el más aconsejable.
SOFTWARE, COMPROBACIONES PREVIAS
Las órdenes necesarias para configurar, compilar y instalar un nuevo kernel deben de ser ejecutadas en los directorios adecuados, el principal es el que contiene el código fuente, a partir del cual el compilador hará su trabajo según las instrucciones que vosotros especifiquéis en el archivo de configuración. Este directorio es: /usr/src/sys/. Si tenéis las fuentes instaladas, en este directorio habrá una gran cantidad de subdirectorios. Unos pocos llevan el nombre de de algunas de las arquitecturas en las que puede correr FreeBSD y contienen código fuente específico para cada arquitectura. El contenido del resto de los subdirectorios de /usr/src/sys/ es código fuente común a todas arquitecturas.
Si el directorio /usr/src/sys/ no existe o está vacío, significa que no tenéis las fuentes instaladas y en ese caso, este es el momento de instalarlas. Existen para ello (como es natural en el universo UNIX*), varias formas de hacerlo, describiré aquí la más rápida y sencilla.
INSTALANDO LAS FUENTES
A partir de ahora es necesario que sea root quien ejecute las órdenes.
Introducís en el lector de CDs el CDROM que usasteis para instalar FreeBSD y ejecutáis la orden:
# sysinstall
Aparecerá la misma aplicación desde la que se inició la instalación del OS y que permite instalar todo el software disponible en ese CD y en el CD-2 de la distribución. En este caso sólo necesitáis instalar las fuentes del kernel, estos son los pasos:
Seleccionáis: Configure, cambiara de pantalla y mostrará otra con más opciones
Seleccionáis: Distributions, mostrará algunas opciones que podéis marcar para instalar
Seleccionáis: src, y aparecerán las opciones para instalar código fuente de varios tipos
Seleccionáis: sys, son los archivos con el código fuente del kernel y es lo que necesitáis
Seleccionáis: regresar al menú anterior, pulsáis Enter y comenzará la instalación
En pocos minutos el código fuente del kernel estará instalado, ese es uno de los motivos por el que he optado por sysinstall.
La otra es que, de esta forma os aseguráis de que las fuentes que instaláis corresponden a la misma versión del kernel que tenéis y eso os evitará problemas posteriores.
CONFIGURANDO EL NUEVO KERNEL
Regresamos ahora al directorio /usr/src/sys/, si no existía, ahora si existe. Como mencionamos anteriormente contiene muchos subdirectorios, ahora nos interesan los que se refieren a las diversas arquitecturas, entramos en el que corresponde a la nuestra, como se trata de un PC, ejecutamos:
# cd /usr/src/sys/i386
como dije anteriormente este directorio contiene código fuente específico para esta arquitectura en varios subdirectorios. En uno de ellos están los archivos de configuración que nos interesan, el nombre es suficientemente descriptivo, ejecutáis:
# cd /usr/src/sys/i386/conf
No haremos en este HOWTO una descripción detallada de todos los ficheros que contiene este directorio, pero es aconsejable echar un vistazo a uno que se llama NOTES. En este fichero figuran las opciones mas genéricas que podemos habilitar en nuestro nuevo kernel, así como la sintaxis correcta para hacerlo. En el fichero GENERIC.hints podéis hacer algunos cambios referentes a las IRQs que serán adjudicadas por el kernel a los dispositivos durante el arranque del OS (esta labor es peligrosa y deberíais de acometerla sólo en caso de que ocurra algún conflicto o tengáis alguna necesidad específica. Siempre siguiendo las instrucciones del fichero NOTES y en su caso de otra documentación adicional, así como de los man device.hints y man loader.conf
El fichero en el que debéis habilitar (o deshabilitar) las opciones para la compilación es el llamado GENERIC. Siempre que vayáis a editar un archivo de configuración, haréis una copia del original. Pero en este caso, para proteger aun más la copia del GENERIC (que es donde haremos los cambios necesarios), vais a seguir un método diferente al habitual que sería algo como, (cp GENERIC GENERIC.OLD). Haréis una copia del GENERIC, la pondréis en otro directorio (por si deseáis eliminar las fuentes después de la compilación del nuevo kernel). aprovecháis para cambiarle el nombre por otro más personalizado, siempre respetando la costumbre de las mayúsculas y creáis un enlace blando en el directorio de configuración. Ejecutando las siguientes órdenes desde el directorio /usr/src/sys/i386/conf/
# mkdir /root/Kernel.back
# cp GENERIC /root/kernel.back/MELIAN
# ln -s /root/kernel.back/MELIAN
A continuación con el editor que más os guste, abrís la copia del archivo que acabáis de hacer y poner a buen recaudo.
# vi MELIAN
Veréis que el archivo esta muy bien comentado, siguiendo sus instrucciones y las del archivo NOTES que tenéis en el mismo directorio, procedéis a habilitar las opciones necesarias y sobre todo, a deshabilitar aquellas que no necesitáis. NO es necesario eliminar ninguna línea, es suficiente con usar # para comentar las opciones que no queréis
"dentro" del nuevo kernel.
Cuando escribo "dentro" me estoy refiriendo a "enlazar estáticamente" aquellos "fragmentos de código", también llamados "código objeto" y que conocemos como "módulos" o "drivers".
Si los enlazamos estáticamente, el kernel los cargará a su lado en la memoria durante el arranque y permanecerán cargados durante el tiempo que dure la sesión.
Al comentar con # delante de la línea, algunas opciones, lo único que hacéis es poner "fuera" del kernel esos "fragmentos de código objeto". Esto no significa que no vayáis a poder disponer de ellos, en realidad los estáis "enlazando dinámicamente". Es decir, que se compilarán como "módulos" y que el kernel no los cargará durante el arranque (a no ser que le indiquéis que lo haga en el fichero /boot/loader.conf/), sino que los cargará cuando algún dispositivo o programa los necesite.
También es posible cargarlos de forma "manual" con el comando kldload Esto no sólo permite que no estén ocupando espacio de memoria durante toda la sesión, sino que además, cuando no los necesitéis podéis descargarlos usando el comando kldunload, o escribir un script que descargue los módulos que no se estén usando y meterlo en una tabla de cron, para que se ejecute cada cierto tiempo. Pero esto es motivo de otro HOTO.
Algunas opciones que figuran en el fichero de configuración del kernel, no pueden ser deshabilitadas. Los comentarios indican claramente cuales no deben ser alteradas. Al finalizar, cerráis el archivo MELIAN guardando los cambios realizados.
OPTIMIZANDO SUAVEMENTE
Hacemos un pequeño alto en el camino para mirar el contenido del fichero /etc/make.conf. Si no existe, lo creáis. En este fichero podéis poner algunas opciones que el programa make tendrá en cuenta a la hora de compilar, tanto el código fuente del kernel como el de otros programas que queráis instalar a través de los ports. No me extenderé mucho en este apartado porque existen en Internet magníficos documentos sobre el tema. Simplemente sugeriré algunas opciones que harán que vuestro nuevo kernel se compile mejor y más rápido. Editáis el archivo:
# vi /etc/make.conf
y escribís estas líneas:
CPUTYPE=i686<---- aquí ponéis el tipo de procesador del que dispone vuestra
máquina, ya sabéis donde buscar esto
CFLAGS=-O2 -pipe
CXXFLAGS+=-O3
Cerráis el archivo guardando los cambios realizados.
COMPILANDO
Hasta ahora todo han sido preparativos, planes, diseño y comprobaciones, ahora comienza la construcción propiamente dicha.Para empezar ejecutáis config, hará varias cosas para vosotros, lee el archivo de configuración que acabamos de editar hace un análisis previo de los recursos necesarios, genera el código fuente específico para el nuevo kernel y lo pone en el subdirectorio "/usr/src/sys/i386/compile/MELIAN/". Finalmente, reporta los resultados. Ejecutáis:
# config MELIAN
Si algo no ha ido bien, mostrará un mensaje de este tipo:
# config: line 126: syntax error
Es bastante claro. Editaréis de nuevo el archivo de configuración del kernel (MELIAN), corregís el error y repetís la orden anterior. Si tenéis dificultades para encontrar la línea 126 en el fichero, acudid al comando nl que como su nombre indica "filtra y enumera líneas".. aunque no contengan caracteres visibles :-) y lo usaréis así:
# ln -b a MELIAN
Si el programa config encuentra que la construcción del kernel es posible con las opciones que habéis escogido y el código del que disponéis, mostrará un mensaje en inglés, que viene a decir:
# entre en ../compile/MELIAN y ejecute "make depend"
Seguid sus instrucciones, "entrando" en el directorio "/usr/src/sys/i386/compile/MELIAN/" y ejecutando las órdenes:
# make depend
Y en cuanto termine
# make
Es posible que el comando make no acabe bien y muestre un error, no son tan descriptivos como los mensajes de config, pero lo más probable es que se trate de algún error en el archivo de configuración, no detectado anteriormente debéis revisar de nuevo el archivo MELIAN.
Si la orden make llega a buen término (es lo más habitual..) el nuevo kernel ya estará hecho. Antes de instalarlo es bueno "limpiarlo" un poco usando el comando strip. Esto mejorará el tiempo de respuesta de muchos programas y cargará un poco menos la RAM. Y .. antes de limpiarlo podéis guardar una copia del nuevo kernel en el directorio que creasteis hace un rato para guardar el fichero de configuración del kernel. Para ello ejecutáis las órdenes siguientes:
# cp kernel /root/kernel.back/kernel.strip
# strip -g kernel
ahora podéis proceder a instalarlo y a probarlo. Pero antes, quizá debierais leer el apartado siguiente. Explica como arrancar con el kernel que tenéis ahora, si el nuevo se niega o no logra arrancar
¡¡ EN CASO DE PROBLEMAS !!
Los pasos a seguir dependen un poco del cargador (boot loader) que estéis utilizando, aunque todos los que conozco permiten en un momento u otro introducir órdenes para el kernel o para el propio cargador.
Si estáis usando el cargador de FreeBSD procedéis así: pulsáis Power y cuando el cargador empiece su cuenta atrás, pulsáis cualquier tecla (excepto Enter) y ejecutáis las siguientes órdenes:
# unload
# boot kernel.old
Si usáis el cargador Grub, este dará paso a la pantalla de bienvenida de FreeBSD pulsáis cualquier tecla para detener la cuenta atrás, seleccionar la opción: 4 y cuando aparezca la shell ejecutáis:
# boot kernel.old
De esta forma el cargador pasará el control al kernel que teníais antes de instalar el nuevo y "casi nada habrá cambiado" Si tenéis un kernel que sabéis¡¡ que funciona, no es mala idea ponerlo en el directorio /boot/ y en caso de error grave podréis cargarlo, usando cualquiera de los métodos anteriores pero llamándolo por su nombre, claro.
# boot "nombre del kernel funcional que tenéis en el directorio /boot para estos casos :-)"
Cuando se instala un nuevo kernel, el "viejo" pasa del directorio /boot/kernel/ al directorio /boot/kernel.old/ pero.. esto pasa cada vez que se instala un kernel, así que /boot/kernel.old/ no es un buen lugar para tener una copia de un buen kernel. A no ser que estéis seguros de que el que está allí es "bueno". Cada cual que decida por si mismo acerca de este asunto, las copias de respaldo son importantes.
INSTALANDO
Ahora que ya sabéis nadar, podéis tirarnos al mar :-). Ya podéis instalar el nuevo kernel ejecutando la orden:
# make install
Pueden suceder dos cosas: que el kernel se instale, esto es, que el kernel sea instalado en el directorio /boot/kernel/ sustituyendo al kernel actual (que pasa al directorio /boot/kernel.old), o que no se instale y muestre un mensaje de error.
La razón mas habitual, es que no pueda "mover" el kernel anterior. Cuando se instala un nuevo kernel make le coloca un "flag" para que no pueda ser alterado por error (o por alguien con mala leche pero sin la clave de root). Es necesario eliminar temporalmente esa "bandera" para que el nuevo kernel pueda ser instalado, para ello ejecutáis:
# chflags noschg /boot/kernel
Es posible que se ejecute sin más o que encuentre una nueva "barrera" y muestre un error. Si no es posible ejecutar este comando, se debe a que está activado algún nivel de seguridad, igual o mayor a 0 (cero). No hay más remedio que cambiar eso temporalmente para poder desbloquear el kernel "viejo" y instalar el nuevo.
Para ello es necesario editar el fichero /etc/rc.conf y cambiar el valor ésta de la línea kern_securelevel="-1" dejándola precisamente así, con valor -1. A continuación es necesario re-arrancar (rebootar) la máquina ejecutando:
# reboot o mejor esta otra orden.. más civilizada
# shutdown -r now
Ahora ya será posible ejecutar las órdenes pendientes:
# chflags noschg /kernel <----- para desbloquear el kernel viejo> y
# make install <------ para instalar el kernel nuevo>
ARRANCANDO CON EL NUEVO KERNEL
Una vez que el kernel se ha instalado, no queda sino batirse :-), es decir, probarlo ejecutando de nuevo:
# shutdown -r now
Si no arranca ya sabéis lo que hacer. Si el nuevo kernel arranca pero presenta algunas deficiencias poco serias, pero molestas. Como por ejemplo, una respuesta inadecuada del comando ps o incluso de ls, se debe casi siempre a que la versión el kernel que se acaba de compilar no es la misma que la del OS instalado.
Si el kernel arranca y se ejecuta con normalidad, ¡FELICIDADES!. Lo habéis conseguido, ahora toca probar todos los dispositivos y programas, o al menos los más habituales. Proceder a colocar el flag de seguridad, ejecutando la orden:
# chflags schg /boot/kernel
Y fijar el nivel de seguridad de la máquina tal y como estaba antes de la compilación, editando el fichero /etc/rc.conf y poniendo la línea kern_securelevel="?" en el nivel anterior. Siempre superior a -1
Después de un tiempo "prudencial" si el nuevo kernel satisface vuestras expectativas, podréis eliminar la copia hecha antes del strip, el directorio /usr/src/sys/i386/compile/MELIAN/ y si necesitáis "espacio" en el HD, incluso las fuentes descargadas del CD de instalación para hacer este kernel. Siempre es posible instalarlas de nuevo en caso de necesidad.
CRÉDITOS
Es obligado recordar que todo lo que figura en este documento referido a la configuración y compilación del kernel en FreeBSD, se puede encontrar en otros documentos existentes en la red de Internet. He recogido algunos consejos del documento de Julio Merino (Slink) que se podía leer en eldemonio.org, una página en español para los amigos y usuarios de los *BSD. (NOTA 21 de abril de 2011) - desafortunadamente este dominio ahora pertenece a una agencia de viajes; no retiro los links por los créditos, por melancolía y para que se recuerde que hubo un tiempo, no tan lejano, en el que http://eldemonio.org era una web de y para usuarios de Sistemas Operativos BSD.
Leyendo detenidamente el FreeBSD Handbook (también existe una versión en castellano, aunque no está completa ni tan actualizada como la original, por razones evidentes) y los manuales de make, mkdep y make.conf, es posible hacer las mismas cosas que figuran en este documento y llegar a similares resultados, sin haberlo visto nunca. Y de paso ahorrarse todo el parloteo acerca de sistemas operativos y demás filosofía, aunque advierto a los no iniciados que los man están escritos en inglés y no son cortos precisamente. Eso si, contienen mucha más información de la que yo he sintetizado aquí.
Aprovecho una vez más para dar las gracias a las personas que emplean su tiempo y sus conocimientos en escribir, depurar, empaquetar y testear tantos millones de líneas de código, para después "regalarlo" a la humanidad. Son la prueba evidente de que es posible la vida en otros universos y que el software cerrado y las patentes son un "fallo" evolutivo, que contradice las teorías de Darwin.
Salute fratres