sabato 20 aprile 2013

Compilazione del kernel 3.4.X longterm su Slackware-14.0

Di recente ho avuto un problema riguardante frequenti freeze apparentemente immotivati con l'ultimo rilascio di Slackware_x86_64  e Slackware_i486 entrambi installate sulla mia macchina. Il freeze non sembra interessare solo l'ambiente grafico, poiché è impossibile far rispondere la macchina, tanto meno killare X o semplicemente entrare in una console. L'unica alternativa è lo spegnimento forzato. La causa sembra essere un bug del kernel 3.2.29 che installato di default su Slackware 14.0, in alcune situazioni potrebbe bloccare completamente i sistemi che hanno recenti cpu multi-core, come spiegato in questi due threads di linuxquestions.org:
http://www.linuxquestions.org 1
http://www.linuxquestions.org 2



Naturalmente, questo inconveniente sembrerebbe non sussistere sugli altri modelli di cpu.
La soluzione, come suggerito, sta nella compilazione di una nuova versione del kernel che non sia un semplice aggiornamento della versione 3.2.x. Personalmente ho scelto di compilare l'ultima versione del kernel stabile 3.4.40 longterm.

NOTA: Il kernel compilato e installato seguendo questa guida richiede anche la creazione di un initrd (initial ramdisk), necessario per l'avvio del sistema. Questa guida può essere adattata alla compilazione di kernel-generic-smp (32bit) e  kernel-generic (64bit), basta modificare leggermente il nome usato.
Inoltre, il vecchio kernel potrà sempre essere avviato sul proprio sistema, qualora le cose non andassero a buon fine..

Le versioni del kernel di tipo "longterm" sono stabili e vengono mantenuti per un periodo di tempo relativamente lungo fornendo le correzioni dei bug fino al loro passaggio a EOL (end of life). Quando vengono apportati dei bugfix nel corso del rilascio, il numero di versione (il numero finale) potrebbe cambiare leggermente, esempio:  3.4.40 diventa 3.4.41. 
Per aggiornare versioni di kernel incrementali tipo da 3.4.40 a 3.4.41 si usa una patch senza scaricare nuovamente tutto il kernel, di seguito si applicherà la patch in questo maniera:

        # cp patch-3.x.bz2 /usr/src/linux
       # cd /usr/src/linux
       # bzip2 -dc patch-3.x.bz2 | patch -p1
 

per il formato gzip si usa:


        # gzip -cd patch-3.x.gz | patch -p1

..poi si procede con la normale ricompilazione

fonte: 
http://www.slacky.eu/slacky/Compilazione_e_ricompilazione_Kernel_su_Slackware
 
Di seguito spiego la procedura di compilazione del kernel passo a passo:
  • Scaricare il kernel in formato tar.xz da qui: https://www.kernel.org potrebbe differire l'ultimo numero di versione (infatti, in data odierna, vedo che c'è il 3.4.41), eventualmente correggiamo il numero di versione presente in questa guida.

  • Scaricare il file gpg per la firma digitale con la stessa versione del kernel (linux.version.tar.sign) sempre nel sito kernel.org
  •  
     
    • Ci logghiamo come root e ci posizioniamo nella directory dei sorgenti:
               $ su -

             # cd /usr/src
      • copiamo in /usr/src il kernel e il file .sign che abbiamo appena scaricato
              # cp  /percorso/linux-3.4.40.tar.xz  /percorso/linux-3.4.40.tar.sign /usr/src
      • estrarre l'archivio compresso ed eseguire la verifica:
               # unxz -v linux-3.4.40.tar.xz

              # gpg --verify linux-3.4.40.tar.sign

               L'output dovrebbe assomigliare a questo:

      gpg: Signature made Friday 19 Apr 2013 12:16:46 PM EST using RSA key ID KEY_ID
      gpg: Can't check signature: public key not found


      • Copiare e incollare il numero del key id dell'output precedente:
              # gpg --recv-keys KEY_ID

      • Ricontrolliamo le firme con:
             # gpg --verify linux-3.4.40.tar.sign

        • Estraiamo l'archivio dei sorgenti del kernel
                 # tar -xvf linux-3.4.40.tar
          • Rimuoviamo il link simbolico del vecchio kernel e ne creiamo uno nuovo che punta al nuovo kernel e ci posizioniamo in esso:
                 # rm linux

                 # ln -s linux-3.4.40/  linux 

                 # cd linux

          • Puliamo i sorgenti da ogni eventuale configurazione:
                 # make clean

                 # make mrproper
          • Ora, dal DVD di Slackware, dovremmo copiare il file di configurazione del kernel che si trova in: "/media/SlackDVD/testing/source/config-testing-3.4.11/" . Per Slackware_x86_64 copieremo  config-generic-3.4.11.x64  mentre per Slackware i486 copieremo config-generic-smp-3.4.11-smp

          Per 32 bit:
          # cp  /media/SlackDVD/testing/source/config-testing-3.4.11/config-generic-smp-3.4.11-smp  /usr/src/linux/.config

          Per 64 bit:
          # cp  /media/SlackDVD/testing/source/config-testing-3.4.11/config-generic-3.4.11.x64  /usr/src/linux/.config

          Se vogliamo possiamo scaricare lo stesso file dal mirror di Slackware e copiarlo in /usr/src/linux rinominandolo .config

          Per 32 bit:
          # wget http://mirrors.slackware.com/slackware/slackware-14.0/testing/source/config-testing-3.4.11/config-generic-smp-3.4.11-smp

          # mv  /usr/src/linux/config-generic-smp-3.4.11-smp  /usr/src/linux/.config

          Per 64 bit:
          # wget http://mirrors.slackware.com/slackware/slackware64-14.0/testing/source/config-testing-3.4.11/config-generic-3.4.11.x64

          # mv  /usr/src/linux/config-generic-3.4.11.x64  /usr/src/linux/.config


          A questo punto siamo pronti alla compilazione ma abbiamo due possibilità:
          Personalizzare ulteriormente la configurazione del kernel, come impostare la tipologia di processore nella propria macchina e impostare altri parametri (qui possiamo davvero diventare pazzi), o tenere la configurazione del .config attuale e partire con la compilazione. Personalmente mi sento di consigliare di impostare almeno la propria cpu e se ne siete capaci, di configurare anche gli altri parametri relativi al proprio hardware, ma la strada potrebbe essere molto insidiosa sopratutto se è la prima volta.

          •  Configurazione:
          - Se scegliamo di mantenere la configurazione attuale:
                 # make oldconfig 

          Make oldconfig vi chiederà solo le risposte alle nuove domande di configurazione, che si aggiungono di volta in volta alle release.
          Una volta fatto make oldconfig passiamo sotto alla compilazione..


          - Se invece optiamo per una configurazione più approfondita ma partendo dal .config:
                 # make menuconfig

          Alcuni link utili per la configurazione:

          http://docs.slackware.com/howtos:slackware_admin:building_the_linux_kernel_using_git_repository
          http://www.gentoo.org/doc/it/kernel-config.xml

          questi comandi vi aiuteranno a trovare informazioni utili sul vostro hardware:

                 # lspci -vnn
                # lspci -k
                # lsusb
                # lsmod
                # dmesg   

          • Compilazione: 
                # make all -j5 (su cpu con 4 processori reali) 

          Mentre attendiamo la fine della compilazione, beviamoci un caffè...

          • Installazione moduli, kernel e file di configurazione
          A compilazione ultimata dobbiamo installare i moduli del kernel in /lib/modules e lo faremo con questo comando:

               # make modules_install 

          poi copieremo l'immagine del kernel "bzImage", il file "System.map" e il file ".config" nella directory "/boot "

          Per Slackware 14.0 a 32bit:

              # cp arch/x86/boot/bzImage  /boot/vmlinuz-generic-smp-3.4.40-smp

              # cp System.map  /boot/System.map-generic-smp-3.4.40-smp

              # cp .config  /boot/config-generic-smp-3.4.40-smp 

          Per Slackware 14.0 a 64bit:

             # cp arch/x86_64/boot/bzImage  /boot/vmlinuz-generic-3.4.40

             # cp System.map  /boot/System.map-generic-3.4.40

             # cp .config  /boot/config-generic-3.4.40

          • Generiamo il demone dei moduli per il nostro kernel:
          Per Slackware 14.0 a 32bit: 

              # cp /etc/rc.d/rc.modules-3.2.29-smp  /etc/rc.d/rc.modules-3.4.40-smp

          Per Slackware 14.0 a 64bit:

            # cp /etc/rc.d/rc.modules-3.2.29  /etc/rc.d/rc.modules-3.4.40

          • Creazione di initrd
          Per generare l'initrd, dobbiamo sapere con esatezza in quale partizione si trova la partizione di root e il tipo di file-system utilizzato; Inoltre vogliamo tenere il vecchio kernel e usarlo per l'avvio in caso di necessità, magari generando un initrd se lo desideriamo o se non lo abbiamo ancora fatto; Dobbiamo allora creare il nostro initrd per il nuovo kernel con un nome speciale. Ora supponiamo che il boot si trovi in /dev/sda5 e che il file-system usato sia ext4 faremo così.

           Per Slackware 14.0 a 32bit:

             # mkinitrd -c -k 3.4.40-smp -m ext4 -f ext4 -r /dev/sda5 -o /boot/initrd-generic-smp-3.4.40-smp.gz

          Per Slackware 14.0 a 64bit:  

            # mkinitrd -c -k 3.4.40 -m ext4 -f ext4 -r /dev/sda5 -o /boot/initrd-generic-3.4.40.gz 

          Consiglio di leggere /boot/README.initrd e la guida di Alien dove ho tratto questi spunti: slackware-kernelbuilding

          • Come ultimo passo, editiamo lilo.conf e lo istruiamo ad usare anche il nuovo kernel:

             # nano /etc/lilo.conf

          aggiungiamo queste righe con la raccomandazione di non cancellare quelle del vecchio kernel; facciamo per sicurezza una copia di backup di lilo.conf. Eventualmente sulle righe che incolliamo cambiamo la versione del kernel con la nostra su "image", "initrd" e "label" (o mettiamo un nome che ci piace, label è opzionale), infine impostiamo l'adeguata partizione in "root" :

          Per Slackware 14.0 a 32bit:

          # Linux bootable partition config begins
          image = /boot/vmlinuz-generic-smp-3.4.40-smp
            initrd = /boot/initrd-generic-smp-3.4.40-smp.gz
            root = /dev/sda5
            label = Linux-3.4.40

            read-only
          # Linux bootable partition config ends


          Per Slackware 14.0 a 64bit:

          # Linux bootable partition config begins
          image = /boot/vmlinuz-generic-3.4.40
            initrd = /boot/initrd-generic-3.4.40.gz
            root = /dev/sda5
            label = Linux-3.4.40

            read-only
          # Linux bootable partition config ends 


          Vi raccomando di tenere le righe del vecchio kernel per il semplice motivo di darci la possibilità di utilizzarlo ancora in caso di necessità.

          Salviamo le modifiche con ctrl+x e rispondiamo si

          aggiorniamo lilo con:

              # lilo -v -c

          Se tutto è andato a buon fine possiamo riavviare e usare il nuovo kernel.
          Se abbiamo installato i driver proprietari (ati o nvidia) dovremmo prima rimuoverli e reinstallarli con il nuovo kernel avviato, lo stesso per quanto riguarda i pacchetti che usano i moduli del kernel, come alsa, virtualbox-kernel (se lo usiamo), etc.
          Se per esempio, durante il boot, vi capita di ottenere un messaggio simile a questo: /usr/sbin/alsactl: set_control:1328:failed to obtain info for control#12 (no such file o directory)
          ..dovete semplicemente reinstallare alsa-lib, alsa-oss, alsa-utils dal dvd di slackware per ripristinare il corretto funzionamento di alsa e cancellare il file /var/lib/alsa/asound.state e provare a ricrearlo con alsactl store e quindi riavviare. Il messaggio di alsactl dovrebbe sparire.  Poi se usate virtualbox dovreste ricompilare virtualbox-kernel e reinstallarlo, comunque tutta roba da 5 minuti.
          Questo è tutto. 

          ATTENZIONE: 
          L'autore di questa guida non si assume responsabilità per eventuali perdite di dati e danni alla propria macchina.
          Questa guida è suscettibile a modifiche senza preavviso. 

          Nessun commento:

          Posta un commento