1) Ti conviene usare una macchina virtuale, semplicemente perché, se fai casini, non distruggi il file system del tuo PC 2) Se sei sotto Linux, hai due scelte come virtualizzatore: VirtualBox e KVM/QEMU. VirtualBox è forse un po' più facile da configurare, ma può non rispettare la configurazione "Non usare la cache dell'host", necessaria per test di performance da dentro una VM. Per entrambi i virtualizzatori, attenzione al fatto che potrebbero non funzionare correttamente su un kernel custom (ossia fatto da te), perché quest'ultimo potrebbe non avere tutte le opzioni necessarie abilitate. Uno dei modi per assicurarsi di avere un kernel con tutte le opzioni necessarie abilitate è eseguire il passo 6 quando avendo il virtualizzatore che volete utilizzare in funzione. 3) Installa nella macchina virtuale la distribuzione che ti piace di più. In quanto alle dimensioni del disco, ti consiglio di lasciare 30GB liberi. 4) Installati un po' di dipendenze. Per esempio, in un sistema apt-based: apt-get install git build-essential libncurses5-dev wget bzip2 libssl-dev libelf-dev In altri sistemi, cerca ed installa i pacchetti corrispondenti a quelli elencati qui sopra. Ad esempio, in Fedora, CentOS or RHEL, il pacchetto libssl-dev si chiama openssl-devel, e si installa con sudo yum install openssl-devel oppure sudo dnf install openssl-devel Su Fedora ho notato che manca anche il gcc, quindi: sudo dnf install gcc Altra risorsa per Fedora e sistemi simili: https://fedoraproject.org/wiki/Building_a_custom_kernel 5) Da dentro la macchina virtuale, clona il repository mainline. Molto sinteticamente git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 6) Da dentro la cartella del repository che ti sei clonato, esegui: ./scripts/kconfig/streamline_config.pl > minimal_config Questo ti crea un config minimale, con selezionati solo i moduli che il tuo sistema (nella macchina virtuale) sta usando nel momento in cui invochi lo script. Stai quindi attento che tutti i moduli che vuoi avere poi disponibili nel tuo nuovo kernel, siano già in uso nel sistema quando invochi questo script. Se non sai bene come procedere, invoca tranquillamente questo script ora; poi, se mancheranno dei pezzi nel kernel, ripeterai questa operazione e la compilazione successiva, per ottenere un kernel in cui c'è tutto quello che vuoi. Lo script potrebbe segnalare vari errori, e ciononostante produrre lo stesso il file di config. Fondamentalmente, per ogni opzione che non riesce a configurare, segnala quello che non è andato come sperava. 7) Se per caso avevi già un file di config nella cartella del repository, e non vuoi perderlo, mettitelo da parte. Il file di config ha sempre lo stesso nome, e si chiama .config 8) Esegui mv minimal_config .config per avere il file di config minimale pronto all'uso per la compilazione del kernel Poi, se necessario, aggiungi bfq. Per farlo, esegui: make menuconfig Potrebbe essere necessario installare ulteriori dipendenze per far funzionare il menuconfig, installare quanto richiesto. Se il menuconfig funziona, vai in "Enable the Block Layer" -> "I/O Schedulers", e - seleziona BFQ come modulo (cioè fai apparire la m e non l'asterisco) - attiva il supporto Hierarchical Scheduling 9) Compila il kernel make -j L'opzione -j fa sì che make esegui vari thread di compilazione in parallelo. Il numero ideale di thread per avere il massimo delle prestazioni per la macchina in cui esegui la compilazione è tipicamente uguale al numero di processori (virtuali) presenti nella macchina, più uno. Quindi, nel caso di macchina virtuale, più processori dai alla macchina virtuale in fase di configurazione, più veloce riuscirai a compilare il kernel Se per caso la compilazione fallisce con un messaggio del tipo: fatal error: openssl/opensslv.h: File o directory non esistente allora ecco la soluzione (estratta da una pagina di aiuto Linux) To fix this problem, you have to install OpenSSL development package, which is available in standard repositories of all modern Linux distributions. To install OpenSSL development package on Debian, Ubuntu or their derivatives: $ sudo apt-get install libssl-dev To install OpenSSL development package on Fedora, CentOS or RHEL: $ sudo yum install openssl-devel Una volta installato il pacchetto giusto, riprova a compilare. 10) Installa il kernel sudo make modules_install sudo make install 11) Riavvia. Al riavvio è molto probabile che il boot loader abbia scelto il kernel che hai appena installato. Per controllare manualmente il kernel da caricare, assicurati che il boot loader si fermi e ti dia modo di scegliere. A seconda delle distribuzione, il boot loader si ferma da se, oppure vuole che tieni premuto un qualche tasto per farlo fermare (tutta roba che si può riconfigurare se vuoi). 12) Se la macchina si riavvia correttamente, controlla che il kernel sia proprio il tuo, col comando uname -a Nell'output controlla la versione del kernel e la data/ora di compilazione Se invece il kernel che scegliete si blocca al boot, controllate le informazioni aggiuntive in fondo a questo documento. 13) Controllare se c'è bfq: cat /sys/block//queue/scheduler Nella lista deve esserci bfq. Se nella lista non c'è bfq, ma c'è noop, allora non avete blk-mq attivo. Per attivarlo, abilitare blk-mq al boot: modificare il file /etc/default/grub (come superuser), aggiungendo o modificando la riga: GRUB_CMDLINE_LINUX="scsi_mod.use_blk_mq=1" ed invocare sudo update-grub Se nella lista non c'è bfq, ma c'è none, allora avete blk-mq, ma probabilmente bfq è configurato come modulo, per cui va caricato. Per caricare bfq come modulo: sudo modprobe bfq Per controllare se bfq è presente nella lista dei moduli: lsmod 14) Una volta fatta pratica in questo modo, siete pronti per provare l'albero bfq-mq, in cui vi ritrovate, già pronte, tutte le versioni di bfq. La cosa migliore che potete fare è, da dentro la cartella del repository, git remote add bfq-mq https://github.com/Algodev-github/bfq-mq.git git fetch bfq-mq 15) Controllate la lista dei branch con git branch 16) Passate dal branch master al branch bfq-mq, con git checkout bfq-mq 17) Ripetete tutti i passaggi già visti, ma stavolta per compilare, installare e provare il kernel contenuto nel branch bfq-mq. In particolare, però, assicurarsi di abilitare lo scheduler bfq-mq nel config (vedere sotto per la documentazione in cui sono descritti i vari scheduler disponibili). Per modificare il config, eseguire make menuconfig Ed entrare in "enable block layer" -> I"/O schedulers" ove troverete anche bfq-mq. Abilitare tutto, anche il supporto gerarchico. Scegliere pure [M] per bfq-mq, ossia compilarlo come modulo. Il selezionare BFQ come modulo permette i test delle modifiche al codice in maniera molto più rapida, se si hanno problemi le si può selezionare come built-in, cioè [*] 18) Leggere il file Documentation/block/bfq-iosched.txt per farsi un'idea degli scheduler dell'I/O introdotti nel brach bfq-mq 19) Controllare se è presente lo scheduler bfq-mq, mediante cat /sys/block//queue/scheduler Se non è presente, va probabilmente caricato il modulo con sudo modprobe bfq_mq_iosched Se modprobe non trova il modulo, allora forse non è stato abilitato nel config: tornare alla configurazione descritta al passo 17. 20) Se tutto è andato bene, siete pronti allo stadio successivo: prime prove con lo scheduler BFQ! ----------------------------- Informazioni aggiuntive. INIT RAMDISK I kernel moderni non hanno quasi niente builtin (ossia compilato 'dentro' l'eseguibile del kernel), ma quasi tutto compilato come modulo. Un tale tipo di kernel, all'avvio, non ha al suo interno praticamente nessun driver, e non lo può caricare finché il filesystem presente sul disco di sistema è montato. Ma come fa il kernel a montare tale filesystem, se non ha il driver per il dispositivo su cui tale filesystem è memorizzato? Per risolvere questo problema, il kernel è tipicamente (automaticamente) configurato affinché, all'avvio, monti immediatamente uno speciale ramdisk. Tale ramdisk, che può essere montato senza bisogno di driver dipendenti dall'hardware presente nel sistema, viene creato durante la compilazione, e contiene tutti i driver che sono stati compilati come moduli, e che sono ritenuti necessari per il corretto avvio del kernel. Quindi, all'avvio, il kernel carica i moduli che gli servono da questo ramdisk. Usando i moduli presenti nel ramdisk, il kernel riesce quindi ad utilizzare i dischi, dopodiché, una volta montato il filesystem principale, il kernel trova il resto dei moduli in tale filesystem. MANCANZA DRIVER DISCO IN INIT RAMDISK Purtroppo a volte capita che, per qualche motivo, non venga aggiunto il driver del disco di sistema nel ramdisk. Pertanto poi il kernel non riesce poi ad avviarsi, perché non riesce ad accedere al disco di sistema. La soluzione rapida, in questi casi, è ricompilare il kernel abilitando il driver del proprio disco come builtin nel config. Qual'è il driver del proprio disco? Fortunatamente, 9 volte su 10 il generico driver SCSI va bene. Per un elenco più dettagliato delle opzioni del kernel da abilitare, potete dare uno sguardo, ad esempio, a queste pagine: https://wiki.gentoo.org/wiki/HDD https://www.linuxtopia.org/online_books/linux_kernel/kernel_configuration/ch09.html (controllate le sezioni IDE Disks e Serial ATA) MANCANZA SUPPORT FILESYSTEM Un'altra causa di fallimento all'avvio potrebbe essere la mancanza del supporto del filesystem in cui è installato il sistema. Nella seguente pagina dovreste trovare indicazioni sia del messaggio che vi dovrebbe essere stampato sullo schermo, che della soluzione del problema. https://www.linuxtopia.org/online_books/linux_kernel/kernel_configuration/ch08s02.html#LKN-custom_rootfs COMPILAZIONE IN UNA CARTELLA SEPARATA Opzionale, creare una cartella diversa per i file compilati: mkdir ../build cp .config ../build make mrproper make -j$(($(nproc) + 1)) O=../build make -j$(($(nproc) + 1)) O=../build modules sudo make -j$(($(nproc) + 1)) O=../build modules_install sudo make -j$(($(nproc) + 1)) O=../build install RISOLUZIONE ERRORI DI COMPILAZIONE DOVUTI A CORRUZIONE ALBERO SORGENTI A volte la compilazione fallisce per motivi che non dipendono da errori nei file sorgenti, ma dalla corruzione di file necessari per la compilazione stessa. I passi che seguo per uscire da situazioni come questa sono, in ordine dal meno distruttivo al più distruttivo, ove per grado di distruttività intendo numero di file che poi vanno ricompilati: 1. Se l'errore riguarda specifici file oggetto, provare a cancellarli 2. Eseguire make O= clean 3. Eseguire make O= mrproper 4. Rigenerare il file .config. A questo scopo, potete ad esempio rieseguire lo script streamline_config.pl. ELIMINAZIOINE KERNEL INSTALLATI Per eliminare un kernel stock installato da un pacchetto, dovete utilizzare la tecnica opportuna consigliata per la vostra distribuzione. Per eliminare un kernel custom creato da voi, basta: 1) eliminare TUTTI i file che lo riguardano dentro la cartella /boot. Tali file sono tipicamente: il kernel stesso, l'immagine dell initramfs, il config 2) eliminare tutti i moduli relativi a quel kernel. Tali moduli si trovano nella cartella /lib/modules CONDIVISIONE ALBERO SORGENTI LINUX TRA HOST E MACCHINA VIRTUALE Se l'host non è Linux, attenzione al file system: deve supportare la distinzione tra maiuscole e minuscole. Ad esempio, su OS X, usa il formato: Mac OS esteso (distingue tra maiuscole e minuscole, journaled). Sostanzialmente, vi conviene crearvi un'immagine disco con questo formato, e montarla. Nel seguito supporrò che l'host è effettivamente un Mac, e che l'immagine disco si chiama linux-dev.dmg Sull'host, creare o modificare il file /etc/exports. Ecco un esempio di riga che funziona con host MAC: /Volumes/linux-dev -mapall=501 -alldirs -network 192.168.46.0 -mask 255.255.255.0 Poi eseguire nfsd enable # abilita nfs all'avvio, se già non lo si è fatto nfs start # avvia il servizio Se il servizio è già attivo, allora: nfsd restart Per controllare se la configurazione è stata letta correttamente: showmount -e Sul guest, mkdir /mnt/linux-dev/ Poi editare il file /etc/fstab: 192.168.46.1:/Volumes/linux-dev /mnt/linux-dev/ nfs rw 0 0 Infine, per montare, eseguire, per esempio: mount -a