¡Esta es una revisión vieja del documento!
Tabla de Contenidos
Kernel Linux
El kernel, por regla general, lo mantenemos o actualizamos a través de los repositorios oficiales utilizando las herramientas de gestión de paquetes (apt para Debian, yum para Red Hat…) y parches. Solo compilaríamos por curiosidad o si trabajamos con hardware “embebidos”.
Compilar un kernel desde cero es complejo porque primero tenemos que saber todos los drivers que necesitaríamos para todo el hardware destino.
Para saber la versión del kernel que está en uso:
uname -r
Ejemplo de salida:
3.10.0-327.10.1.el7.x86_64
En las distribuciones de Linux, el kernel se suele instalar en /boot con el nombre de vmlinuz:
vmlinuz-3.10.0-327.10.1.el7.x86_64
Nomenclatura
Formato: A.B.C.D
- A: versión principal del kernel.
- B: rama del kernel.
- C: si es número impar, indica que el kernel no es estable.
Compilación
Pasos:
- Descarga de las fuentes (kernel.org)
- Extracción de las fuentes
- Limpieza
- Selección de opciones (
.config) - Guardar opciones (
.config) - Compilación
- Instalación
Se suele extraer en /usr/src/:
tar xvjf /ruta/kernel/linux-3.13.0.tar.bz2 -C /usr/src
Finalmente las fuentes quedarán en /usrc/src/linux-3.13.0/
Si no fuese la primera vez que compilamos ese kernel, realizamos una limpieza:
make clean && make mrproper
Esto lo hacemos porque dentro del directorio con las fuentes del kernel puede existir (si ya lo habíamos compilado anteriormente) un fichero llamado .config que almacena todas las opciones que vamos eligiendo para la compilación del kernel. Dicho fichero luego se copiaría a /boot.
clean elimina los ficheros generados. Se conserva el archivo .config.
mrproper elimina todos los archivos generados, el archivo .config y también los archivos de respaldo para recuperar la configuración de base tal y como estaba en el archivo.
Para seleccionar las opciones de compilación, aprovecharemos el fichero config existente de un kernel que tengamos. Por ejemplo, el fichero /boot/config-3.10.0-327.10.1.el7.x86_64 y lo copiamos a nuestro directorio con las fuentes de la nueva versión del kernel:
cp /boot/config-3.10.0-327.10.1.el7.x86_64 /usrc/src/linux-3.13.0/.config
Para la compilación, el fichero debe llamarse .config (oculto)
Para seleccionar las opciones que nos interesen, tenemos varias herramientas:
make config: preguntar por pantalla por cada una de las opcionesmake menuconfig: lo mismo, pero a través de un menú desde el cual podremos ir navegando por categoríasmake xconfig: lo mismo quemenuconfig, pero con entorno gráfico.
Lo habitual es usar make menuconfig y desde el menú, cargar el .config para que queden marcadas/desmarcadas las opciones que tenía el kernel instalado. Para ello, se escoge la opción Load an Alternate Configuration File.
Supongamos que queremos añadir soporte para sistemas de ficheros NTFS. Tendríamos que movernos a través del menú a File systems → DOS/FAT/NT filesystems → NTFS file system support.
Las opciones pueden tener los siguientes valores:
<M>: disponible como módulo.<*>: incluido en el kernel, se use o no.[*]: incluirlo.[ ]: excluirlo.
Los cambios se guardarán en el .config y será lo que utilizaremos para compilar.
Finalmente, la compilación del kernel se realiza con:
make all
Compilamos los módulos del kernel:
make modules_install
Finalmente “instalamos” el kernel:
make install
Este último comando crea una nueva entrada de configuración en el GRUB, crea el fichero initrd, vmlinuz…
Parches
Es raro tener que aplicar parches al kernel ya que en el día a día el kernel lo vamos manteniendo a través de repositorios y herramientas de paquetería como apt' o yum.
Si queremos hacerlo, en la página kernel.org hay parches.
==== Aplicar parches ====
Simulación:
<code>
bzip2 -dc patch.X.Y.bz2 | patch -p1 –dry-run
</code>
Aplicación:
<code>
bzip2 -dc patch.X.Y.bz2 | patch -p1
</code>
Si el parche está comprimido en .gz:
<code>
gunzip -c patch.X.Y.gz | patch -p1 –dry-run
gunzip -c patch.X.Y.gz | patch -p1
</code>
==== Retirar parches ====
La retirada de un parche aplicado se realiza con el mismo comando y la misma sintaxis a la que se le añade la opción -R:
<code>
patch -p1 -R < patch-X-Y
</code>
===== Módulos =====
==== modinfo ====
Información sobre un módulo existente:
<code>
modinfo [NOMBRE_MÓDULO|RUTA_FICHERO_MÓDULO]
</code>
Ejemplo:
<code>
# modinfo nfs
filename: /lib/modules/3.10.0-327.10.1.el7.x86_64/kernel/fs/nfs/nfs.ko
license: GPL
author: Olaf Kirch okir@monad.swb.de
alias: nfs4
alias: fs-nfs4
alias: fs-nfs
rhelversion: 7.2
srcversion: 01E39715B5332C751061DF0
depends: fscache,sunrpc,lockd
intree: Y'
vermagic: 3.10.0-327.10.1.el7.x86_64 SMP mod_unload modversions
signer: Red Hat Enterprise Linux kernel signing key
sig_key: E3:9A:6C:00:A1:DE:4D:FA:F5:90:62:8C:AB:EC:BC:EB:07:66:32:8A
sig_hashalgo: sha256
parm: callback_tcpport:portnr
parm: nfs_idmap_cache_timeout:int
parm: nfs4_disable_idmapping:Turn off NFSv4 idmapping when using 'sec=sys' (bool)
parm: max_session_slots:Maximum number of outstanding NFSv4.1 requests the client will negotiate (ushort)
parm: send_implementation_id:Send implementation ID with NFSv4.1 exchange_id (ushort)
parm: nfs4_unique_id:nfs_client_id4 uniquifier string (string)
parm: recover_lost_locks:If the server reports that a lock might be lost, try to recover it risking data corruption. (bool)
parm: enable_ino64:bool
</code>
Lo más importante de esta salida es la ubicación del módulo (filename) y sus dependencias (dep)
==== lsmod ====
Muestra los módulos en uso.
==== insmod ====
Carga módulos en el kernel.
Se debe indicar al ruta completa del módulo.
No gestiona dependencias.
Imaginemos que queremos cargar el módulo vfat. Primero miramos la información con modinfo:
<code>
$ modinfo vfat
filename: /lib/modules/3.10.0-327.10.1.el7.x86_64/kernel/fs/fat/vfat.ko
author: Gordon Chaffee
description: VFAT filesystem support
license: GPL
alias: fs-vfat
rhelversion: 7.2
srcversion: 0146B853C460840F84D5904
depends: fat
intree: Y
vermagic: 3.10.0-327.10.1.el7.x86_64 SMP mod_unload modversions
signer: Red Hat Enterprise Linux kernel signing key
sig_key: E3:9A:6C:00:A1:DE:4D:FA:F5:90:62:8C:AB:EC:BC:EB:07:66:32:8A
sig_hashalgo: sha256
</code>
Ahí vemos que depende del módulo fat. Lo revisamos:
<code>
$ modinfo fat
filename: /lib/modules/3.10.0-327.10.1.el7.x86_64/kernel/fs/fat/fat.ko
license: GPL
rhelversion: 7.2
srcversion: 3A6945250CBE5C12FC57D39
depends:
intree: Y
vermagic: 3.10.0-327.10.1.el7.x86_64 SMP mod_unload modversions
signer: Red Hat Enterprise Linux kernel signing key
sig_key: E3:9A:6C:00:A1:DE:4D:FA:F5:90:62:8C:AB:EC:BC:EB:07:66:32:8A
sig_hashalgo: sha256
</code>
<code>
insmod /lib/modules/3.10.0-327.10.1.el7.x86_64/kernel/fs/fat/fat.ko
</code>
Este ya no depende de ninguno, así que lo cargamos:
<code>
insmod /lib/modules/3.10.0-327.10.1.el7.x86_64/kernel/fs/fat/fat.ko
</code>
Y ahora podemos cargar vfat'':
insmod /lib/modules/3.10.0-327.10.1.el7.x86_64/kernel/fs/fat/vfat.ko
rmmod
Elimina módulos del kernel.
No gestiona dependencias.
modprobe
Carga o elimina módulos del kernel.
Gestiona dependencias.
Cargar:
modprobe [NOMBRE_MÓDULO]
Eliminar:
modprobe -r [NOMBRE_MÓDULO]
