20 septiembre 2018

Compilar un kernel en Slackware Linux

Alguna vez leí que existe un momento que define la existencia de un linuxero, un momento en el que dejamos de ser niños y nos convertimos en adultos. Y ese momento es... ¡Cuando compilamos nuestro primer kernel!

Hay muchas cuestiones a tener en cuenta antes de dar este paso, la razón principal es que si lo hacemos sin prestarle la debida atención podemos dejar inutilizado nuestro sistema.

Lo primero y mas importante:

Si ya tenemos un kernel instalado, testeado y funcionando, debemos asegurarnos de que no se estropee ya que sera nuestra base, sera nuestro cimiento para compilar el nuevo núcleo.

Una de las mejores formas de protegerlo es no compilando la misma versión, ya que si lo hacemos podemos “pisar” y dañar las configuraciones y/o módulos que existan en nuestro sistema, pero si aun si decidimos hacerlo, tenemos que asegurarnos de modificar el nombre del kernel de la forma en la que se describe en esta guiá.
Manos a la obra:

Desde aca en adelante solo hay comandos y breves comentarios, para no salirnos de foco.
Debemos estar concentrados y analizar cada comando, ya que esa es la mejor forma de aprender.

Por regla general, las compilaciones deben hacerse en el directorio SRC (SouRCe).

$ cd /usr/src

Descargamos el kernel estable mas reciente, al momento de escribir esta guiá era la versión 4.18, aunque no difiere prácticamente con otras versiones.

# wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.18.9.tar.xz

Descomprimimos el paquete en cuestión.

# tar xvf linux-4.18.9.tar.xz

Ingresamos a la carpeta que hemos descomprimido:

# cd linux-4.18.9

Recomendación a tener en cuenta.

Ejecutar lsmod (y guardar la salida) para conocer los módulos que actualmente están cargados en nuestro sistema.
Nos va a servir como guiá para saber que módulos son útiles, cuales usamos, cuales son necesarios y cuales son descartables.
Tal vez no le prestemos demasiada atención ahora, pero en un futuro van a empezar a chequear este apartado cuando comiencen a optimizar su propia versión de linux adaptada 100% a su equipo.

# lsmod
Module Size Used by
pci_stub 1806 1
vboxpci 16316 0
vboxnetadp 19493 0
vboxnetflt 19359 0
vboxdrv 416698 3 vboxnetadp,vboxnetflt,vboxpci
ipv6 337574 116
fuse 84714 3
joydev 10496 0
ums_realtek 8366 0
uas 14162 0
usb_storage 56102 2 uas,ums_realtek
i2c_dev 6252 0
sparse_keymap 4048 0
coretemp 6780 0
hwmon 4199 1 coretemp
intel_rapl 11044 0
iosf_mbi 3821 1 intel_rapl
x86_pkg_temp_thermal 5665 0
intel_powerclamp 8978 0
kvm_intel 161137 0
rt2800pci 6470 0
kvm 510755 1 kvm_intel
rt2800mmio 9596 1 rt2800pci
irqbypass 3583 1 kvm
rt2800lib 79814 2 rt2800pci,rt2800mmio
crct10dif_pclmul 5461 0
rt2x00pci 3419 1 rt2800pci
rt2x00mmio 3687 2 rt2800pci,rt2800mmio
rt2x00lib 42701 5 rt2x00pci,rt2800lib,rt2800pci,rt2800mmio,rt2x00mmio
snd_hda_codec_hdmi 39459 1
mac80211 612361 3 rt2x00lib,rt2x00pci,rt2800lib
crc32_pclmul 3238 0
crc32c_intel 13583 0
cfg80211 527411 2 mac80211,rt2x00lib
eeprom_93cx6 3762 1 rt2800pci
snd_hda_codec_realtek 73584 1
crc_ccitt 1861 1 rt2800lib
ghash_clmulni_intel 4701 0
psmouse 113450 0
evdev 13220 16
rfkill 18649 2 cfg80211
snd_hda_codec_generic 61252 1 snd_hda_codec_realtek
i915 1195903 4
serio_raw 5146 0
i2c_i801 16909 0
r8169 77031 0
thermal 11441 0
mii 5271 1 r8169
wmi 9259 0
drm_kms_helper 119698 1 i915
battery 14760 0
drm 323926 6 i915,drm_kms_helper
snd_hda_intel 30219 3
intel_gtt 14002 1 i915
video 30072 1 i915
fjes 21479 0
ac 5440 0
snd_hda_codec 108525 4 snd_hda_codec_realtek,snd_hda_codec_hdmi,snd_hda_codec_generic,snd_hda_intel
agpgart 31988 2 drm,intel_gtt
snd_hda_core 53138 5 snd_hda_codec_realtek,snd_hda_codec_hdmi,snd_hda_codec_generic,snd_hda_codec,snd_hda_intel
i2c_algo_bit 6154 1 i915
button 5943 1 i915
snd_hwdep 6656 1 snd_hda_codec
fb_sys_fops 1730 1 drm_kms_helper
syscopyarea 3458 1 drm_kms_helper
snd_pcm 93250 4 snd_hda_codec_hdmi,snd_hda_codec,snd_hda_intel,snd_hda_core
sysfillrect 3950 1 drm_kms_helper
sysimgblt 2608 1 drm_kms_helper
i2c_core 48117 6 drm,i915,i2c_i801,i2c_dev,drm_kms_helper,i2c_algo_bit
snd_timer 22402 1 snd_pcm
mei_me 19011 0
xhci_pci 5065 0
snd 69563 13 snd_hwdep,snd_timer,snd_hda_codec_hdmi,snd_pcm,snd_hda_codec_generic,snd_hda_codec,snd_hda_intel
mei 62863 1 mei_me
tpm_tis 11588 0
xhci_hcd 117945 1 xhci_pci
ehci_pci 4285 0
tpm 36580 1 tpm_tis
shpchp 26680 0
ehci_hcd 44114 1 ehci_pci
soundcore 6876 1 snd
lpc_ich 14738 0
processor 29079 0
loop 21505 0

En este punto recomiendo leer la ayuda del comando make y le vamos a dar un vistazo a esta sección en particular:

    # make help

    Configuration targets:
    config – Update current config utilising a line-oriented program
    nconfig – Update current config utilising a ncurses menu based program
    menuconfig – Update current config utilising a menu based program
    xconfig – Update current config utilising a Qt based front-end
    gconfig – Update current config utilising a GTK+ based front-end
    oldconfig – Update current config utilising a provided .config as base
    localmodconfig – Update current config disabling modules not loaded
    localyesconfig – Update current config converting local mods to core
    defconfig – New config with default from ARCH supplied defconfig
    savedefconfig – Save current config as ./defconfig (minimal config)
    allnoconfig – New config where all options are answered with no
    allyesconfig – New config where all options are accepted with yes
    allmodconfig – New config selecting modules when possible
    alldefconfig – New config with all symbols set to default
    randconfig – New config with random answer to all options
    listnewconfig – List new options
    olddefconfig – Same as oldconfig but sets new symbols to their
    default value without prompting
    kvmconfig – Enable additional options for kvm guest kernel support
    xenconfig – Enable additional options for xen dom0 and guest kernel support
    tinyconfig – Configure the tiniest possible kernel
    testconfig – Run Kconfig unit tests (requires python3 and pytest)


Como pueden observar podemos ejecutar las siguientes opciones:
config, nconfig, menuconfig, xconfig, gconfig

Deben ejecutar solo una de ellas, ya que nos va a permitir trabajar sobre el archivo de configuracion de manera muchas mas interactiva.
En mi caso, como estoy trabajando desde un terminal me resulta mucho mas cómodo usar la opción menuconfig. Pero no nos adelantemos, todavia debemos preparar el terreno para eso hay una serie de pasos.

Debemos asegurarnos de que no hayan binarios (posiblemente de un intento anterior si es que no nos funciono a la primera).
Como vamos a trabajar sobre la configuración de un kernel que ya sabemos que funciona, necesitamos recuperar el .config donde se detallan los modulos con los cuales se compilo.

Limpieza de binarios:

# make clean

Recuperación del archivo de configuración del kernel en uso:

# zcat /proc/config.gz > .config

Aunque también podemos utilizar este comando:

# make oldconfig

Luego nos preguntara por todas las nuevas opciones incluidas en el nuevo kernel, si tenemos tiempo y paciencia, podríamos leer todas las opciones que se nos presenta y configurarlas o… podemos ir a lo seguro presionando ENTER para seleccionar las opciones por default, lo cual me parece lo mas recomendable si no queremos tentar al destino y a los demonios de internet (?

En mi caso particular suelo usar mi equipo para virtualizar tanto con KVM como con VirtualBox, por lo que hago uso del siguiente comando para setear todo los necesario:

# make kvmconfig

Ahora si, la configuracion en tu modo “grafico” preferido.

# make menuconfig

Si sos novato, no te recomiendo tunear demasiado el kernel.
Pero es en definitiva el motivo por el cual alguien realiza la compilación a menos que seas alguien demasiado fanatico y tengas versionitis aguda

Lo ideal seria solo agregar el soporte al hardware puntual que estamos necesitando.

Aunque si ya tenemos cierta experiencia y nos interesa optimizar el kernel, tanto en tamaño como en rendimiento, podemos empezar a quitar cosas que sabemos que no vamos a usar.


Tunning

    General setup > Local version – append to kernel release : -slackUser-05
    Enabe the block layer > Partition types > PC BIOS (MS DOS partition tables) support
    # Solo dejo activa esa opcion ya que es la unica que uso.
    Processor type and features >
    # Esto es a gusto, si no sabemos lo que hacemos, mejor no tocar, en mi caso como mi cpu es intel, desactivo todo lo que diga AMD.
    Processor type and features > Processor family > Core 2/newer Xeon
    # En mi caso elijo esa opcion ya que se ajusta a mi procesador.
    Processor type and features > Maximum number of CPUs > 4
    # Nuevamente seteo ese valor porque se ajusta a mi hardware.
    File systems >
    # Asegurense de tener su sistema de archivos! El que usan dejenlo integrado al kernel, los demas como modulos.
    Device Drivers > Thunderbolt support
    # No tengo una “MAC” de Apple, asi que lo desactivo.
    Device Drivers > Virtualization drivers > Virtual Box Guest integration support
    Device Drivers > Android > Android Drivers
    Device Drivers > Graphics support >
    # Desactivo todo lo relavito a AMD, ATI, Noveau, nVidia, etc… Porque mi GPU es una Intel HD.
    Device Drivers > Graphics support > Maximum number of GPUs : 1
    # Esto como todo en esta seccion, es relativo a nuestro hardware. A mi hardware, en realidad.
    Device Drivers > Graphics support > Bootup logo
    # Para personalizar nuestro logo antes de compilar. Proximamente en otro post.
    Kernel hacking >
    # En mi caso desactivo todo lo relativo a debug para tener una salida limpia y bonita en pantalla.
    Kernel hacking > Printk and dmesg options > Default console log level > 1
    Kernel hacking > Printk and dmesg options > Default message log level > 1
    Virtualization >
    # Una vez mas desactivo todo lo referido a AMD porque mi CPU es Intel.


Personalizar nuestro LINUX LOGO.

En mi caso, ya tengo una imagen personalizada, que suelo usar como logo de todos mis kernels compilados. En otra oportunidad voy a detallar como crearlo sin demasiadas complicaciones, pero para no hacer demasiado extensa la guia, comparto mi “Linux Logo” el cual deben copiarlo en la ruta con el nombre que se detalla a continuacion:

http://please.dontreadthis.site/wp-content/uploads/2018/09/logo_linux_clut224.ppm

# cp logo_linux_clut224.ppm /usr/src/linux-4.18.9/drivers/video/logo/logo_linux_clut224.ppm


Ya es tiempo del trabajo duro…

Compilamos el kernel propiamente dicho.
Como tiempo de referencia, utilizando como base las opciones del kernel huge de Slackware 14.2 este paso a mi me demoro 20 minutos. Aunque con el tunning apropiado no demora mas de 10 minutos en un i7 de segunda generacion.

# make bzImage

Compilamos e instalamos los módulos.
Este paso me demoro 25 minutos, nuevamente es una referencia, obviamente esto varia de equipo en equipo.

# make modules && make modules_install

Copiamos nuestro nuevo kernel a la carpeta boot.

# cp /usr/src/linux-4.18.9/arch/x86_64/boot/bzImage /boot/vmlinuz-slackUser-05

En caso de que hayamos compilado módulos que necesitemos para arrancar el sistema debemos crear el init ram disk.
El siguiente comando nos abrirá una herramienta con la cual haremos el trabajo de una forma mas sencilla:

# /usr/share/mkinitrd/mkinitrd_command_generator.sh -i

Si seguimos los pasos correctamente, la herramienta nos dira que comando ejecutar, seria solo cuestion de copiar y pegar... o de escribir a mano. En mi caso la salida del comando es la siguiente:

mkinitrd -c -k 4.18.9-slackUser-05- -f reiserfs -r /dev/sda5 -m reiserfs -h /dev/sda7 -u -o /boot/initrd-slackUser-05.gz

Como mencione anteriormente, estoy trabajando desde una terminal, así que hago uso de VIM para agregar la entrada correspondiente a mi grub.cfg (Si, uso GRUB - Nota del autor).

Mi forma de trabajar sobre este archivo es sencilla. Copio una entrada valida.
Con 17yy copio (en mi caso 17 son el numero de lineas necesarias a copiar) y con pp pego en donde corresponde.

Luego sobre esta entrada modifico la linea correspondiente al kernel y al initrd con los nombres que corresponde.

# vim /boot/grub/grub.cfg

Si hicieron todo como esta detallado y al pie de la letra, al reiniciar, GRUB les va a mostrar la nueva entrada con el nuevo nucleo personalizado.

Es importante no borrar la entrada al kernel anterior, ya que en caso de que nuestro nuevo “Linux” no funcione, deberemos hacer uso del que ya estaba funcionando en el sistema.
Próximamente voy a detallar como iniciar un sistema con un kernel dañado, porque muy probablemente a alguien le ocurra esta situacion.
Pasos adicionales:

Seguramente ahora vas a hacer uso y abuso de tu nuevo kernel. Y muy probablemente te dediques a compilar nuevas aplicaciones para optimizar todo lo posible tu sistema. Entonces, es mas que seguro que vas a necesitar los headers del kernel:

# make headers_install

¡Compile mi kernel y funciona! ¡Quiero guardarlo!

Esta sección va a ser sencilla, nos vamos a dedicar a guardar todo para no compilar dos veces lo mismos.
Creamos un nuevo directorio donde guardar los headers, lo vamos a instalar ahí y luego vamos a crear un paquete para Slackware Linux.

# mkdir /tmp/linux-4.18.9-headers
# cd /usr/src/linux-4.18.9
# make headers_install INSTALL_HDR_PATH=/tmp/linux-4.18.9-headers/
# cd /tmp/linux-4.18.9-headers
# makepkg -l y -c y /tmp/linux-4.18.9-headers.txz

Deberíamos ver algo asi:

Slackware package /tmp/linux-4.18.9-headers.txz created.

Ahora vamos a hacer lo mismo, pero con los módulos:

# mkdir /tmp/linux-4.18.9-modules
# cd /usr/src/linux-4.18.9
# make modules_install INSTALL_MOD_PATH=/tmp/linux-4.18.9-modules/
# cd /tmp/linux-4.18.9-modules/
# makepkg -l y -c y /tmp/linux-4.18.9-modules.txz

Y obtendremos lo siguiente:

Slackware package /tmp/linux-4.18.9-modules.txz created.

Ahora nos falta empaquetar el binario del kernel:

# cd /usr/src/linux-4.18.9
# make tarxz-pkgmake

Lo cual nos generara un archivo similar a este:

linux-4.18.9-slackUser-05-x86.tar.xz

Copiamos nuestros nuevos binarios a un lugar seguro y damos por finalizada esta guia...!

Tomado de: http://please.dontreadthis.site/?p=47

No hay comentarios:

Publicar un comentario