U
Utente cancellato 277320
Ultima modifica da un moderatore:
[editato 01/8/2021, rev 2: alcuni fix di sintassi, aggiunto trace di debug]
[editato 02/8/2021, rev 3: rimosso link matrix, pare violi regolamento, lo terro' nella firma]
Saluti a tutti,
ho deciso di scrivere una piccola guida introduttiva forse utile, per questo simpatico forum.
La guida riguarda il kernel "mainline" noto anche come vanilla, si trova in www.kernel.org, ed e' quello ufficiale (fonte ufficiale chiamata anche "upsteram") gestito da Linus Torvalds, da cui tutti gli altri kernel derivano.
Come saprete, il kernel Linux e' 99% C, quindi stiamo parlando di programmazione C e la guida dovrebbe essere on-topic.
Alcune note preliminari:
Perchè dovrebbe interesssarmi la programmazione nel kernel Linux ?
Intanto perche' anche solo studiarlo un po' e' un ottima scelta a fini didattici, montagne di codice C in genere scritto bene dove e' stato implementato di tutto e di piu' E' codice opensource quindi riutilizzabile, che sia una linked list, un driver o l'intero kernel. Saper metterci mano consente anche di capire la ragione di misteriosi errori/warnings che si incontrano al boot, che spesso nei forum nessuno sa spiegare, o effettuare alcune personalizzazioni. Contribuire al kernel poi, che e' la cosa piu' difficile, consente di acquisire un certo "punteggio" per il proprio cv.
Requisiti: buona conoscenza C e git.
PARTE 1: introduzione e metodologia di lavoro.
1) Puoi prendere visione dei sorgenti del kernel, senza scaricarli, cliccando sorgenti .
2) Dal sito ufficiale kernel.org troverete vari repository, quelli fondamentali sono:
Scaricando il codice dal repository di interesse, e' possibile accedere alla precisa versione su cui si vuole operare (git branch / tag).
3) Per iniziare a mettere mano al codice, pouoi scaricare il codice su pc. Ci sono due vie,
4) Se si intende aggiungere delle funzionalita' o fixare qualche bug, con la finalita' di contribuire inviando la patch upstream, si deve scaricare e lavorare sul kernel mainline, branch "master".
5) Se intendi modificare, compilare e utilizzare il kernel per la tua stessa macchina, la posizione indicata dove scaricarlo sara':
angelo@dfj /usr/src $ lstotal 28
drwxr-xr-x 7 angelo angelo 4096 May 15 11:52 .
drwxr-xr-x 12 root root 4096 Jul 28 12:34 ..
drwxr-xr-x 5 angelo angelo 4096 Mar 22 15:18 kernel-mft-4.16.1
lrwxrwxrwx 1 root root 9 Jul 3 2020 linux -> linux.git
drwxr-xr-x 24 angelo angelo 4096 Dec 12 2019 linux-5.3-rc8
drwxr-xr-x 25 angelo angelo 4096 Mar 31 2020 linux-5.6-rc3
drwxr-xr-x 29 angelo angelo 4096 Apr 28 11:01 linux.git
Se invece intendi cross-compilarlo, ad esempio per una schedina arm, puoi scaricarlo dove piu' ti piace.
6) Una volta scaricato, l'albero dei sorgenti si presenta cosi:
Non entro in questa prima parte nel dettaglio del contenuto di ogni directory. Fondamentali sono comunque
Per configurare il kernel si parte da una configurazione esistente, altrimenti sarebbe un operazione infinita.
Per pre-configurare con una configurazione esistente si utilizzano alcune facilitazioni:
Quella scelta tra le operazioni sopra genera il file .config.
Il centro del processo di configurazione e' il file .config, la compilazione (make) utilizza sempre questo file.
Dopo aver preconfigurato il kernel come sopra, e generato .config, si puo modificarlo con un semplice
.config sara' cosi aggiornato. Dall'attuale .config si puo creare un file "defconfig" ovvero una configurazione predefinita con
E riutilizzarla con
Nota: ogni modulo/driver puo essere compilato built-in [*] o loadable [M]. In un PC in genere si tengono abilitati tantissimi driver come [M] perche vengano riconosciuti in maniera dinamica dispositivi pluggati in bus pci / usb etc. Nelle schedine embedded in genere si abilitano solo i driver per i dispositivi presenti sulla schedina (platform driver/device), quindi pochissimi, la scelta se includerli built-in o caricabili e' dettata dalla strategia scelta (fast boot etc).
8) Modifiche
Aggiungiamo per test un semplice trace di debug,
Dopo il boot, dal "dmesg", all'inizio subito dopo la command line dovrebbe apparire il vs. messaggio.
9) Compilazione
Che ci si trovi a compilare "native", cioe' con gcc installato sul tuo stesso pc dove eseguirai il kernel, o cross-compilare con toolchain specifica, i passi importanti per la compilazione sono:
Questo sopra e' solo il nocciolo della compilazione, lascio a voi arricchire lo script a piacimento.
Dalla zImage generata ogni distribuzione ha i propri comandi per generare l'apposito initramfs.
Questa prima guida si ferma qui, e si propone di avervi portato a generare la Vs. zImage. Spero ci siate riusciti. Per non mettere troppa carne al fuoco, aspetto Vs. commenti per eventualmente creare la parte 2.
[editato 02/8/2021, rev 3: rimosso link matrix, pare violi regolamento, lo terro' nella firma]
Saluti a tutti,
ho deciso di scrivere una piccola guida introduttiva forse utile, per questo simpatico forum.
La guida riguarda il kernel "mainline" noto anche come vanilla, si trova in www.kernel.org, ed e' quello ufficiale (fonte ufficiale chiamata anche "upsteram") gestito da Linus Torvalds, da cui tutti gli altri kernel derivano.
Come saprete, il kernel Linux e' 99% C, quindi stiamo parlando di programmazione C e la guida dovrebbe essere on-topic.
Alcune note preliminari:
Perchè dovrebbe interesssarmi la programmazione nel kernel Linux ?
Intanto perche' anche solo studiarlo un po' e' un ottima scelta a fini didattici, montagne di codice C in genere scritto bene dove e' stato implementato di tutto e di piu' E' codice opensource quindi riutilizzabile, che sia una linked list, un driver o l'intero kernel. Saper metterci mano consente anche di capire la ragione di misteriosi errori/warnings che si incontrano al boot, che spesso nei forum nessuno sa spiegare, o effettuare alcune personalizzazioni. Contribuire al kernel poi, che e' la cosa piu' difficile, consente di acquisire un certo "punteggio" per il proprio cv.
Requisiti: buona conoscenza C e git.
PARTE 1: introduzione e metodologia di lavoro.
1) Puoi prendere visione dei sorgenti del kernel, senza scaricarli, cliccando sorgenti .
2) Dal sito ufficiale kernel.org troverete vari repository, quelli fondamentali sono:
linux (Kernel "mainline", testa dello sviluppo, codice testato) |
kernel/git/torvalds/linux.git - Linux kernel source tree
git.kernel.org
|
linux-next (features aggiunte dai vari maintainers, in fase di test) | |
linux-stable (versioni stable e LTS, con backport di fix importanti) |
kernel/git/stable/linux.git - Linux kernel stable tree
git.kernel.org
|
Scaricando il codice dal repository di interesse, e' possibile accedere alla precisa versione su cui si vuole operare (git branch / tag).
3) Per iniziare a mettere mano al codice, pouoi scaricare il codice su pc. Ci sono due vie,
- rapida, scaricare solo il pacchetto compresso della specifica versione, tipo linux-5.3-rc8.tar.gz
- completa: clonare l'intero repository con tutta la storia, download lungo, ma la storia e' fondamentale per lo sviluppo.
Bash:
# clone completo del kernel mainline
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
4) Se si intende aggiungere delle funzionalita' o fixare qualche bug, con la finalita' di contribuire inviando la patch upstream, si deve scaricare e lavorare sul kernel mainline, branch "master".
5) Se intendi modificare, compilare e utilizzare il kernel per la tua stessa macchina, la posizione indicata dove scaricarlo sara':
angelo@dfj /usr/src $ lstotal 28
drwxr-xr-x 7 angelo angelo 4096 May 15 11:52 .
drwxr-xr-x 12 root root 4096 Jul 28 12:34 ..
drwxr-xr-x 5 angelo angelo 4096 Mar 22 15:18 kernel-mft-4.16.1
lrwxrwxrwx 1 root root 9 Jul 3 2020 linux -> linux.git
drwxr-xr-x 24 angelo angelo 4096 Dec 12 2019 linux-5.3-rc8
drwxr-xr-x 25 angelo angelo 4096 Mar 31 2020 linux-5.6-rc3
drwxr-xr-x 29 angelo angelo 4096 Apr 28 11:01 linux.git
Se invece intendi cross-compilarlo, ad esempio per una schedina arm, puoi scaricarlo dove piu' ti piace.
6) Una volta scaricato, l'albero dei sorgenti si presenta cosi:
Non entro in questa prima parte nel dettaglio del contenuto di ogni directory. Fondamentali sono comunque
- arch, architetture supportate, codice basso livello specifico di ogni architettura, con spesso codici assembly per le prime inizializzazioni (head.S),
- drivers, quasi tutti i driver, eccetto quelli audio in sound,
- include, gli header files,
- mm, memory management,
- fs, file systems,
- net, protocolli di rete.
Per configurare il kernel si parte da una configurazione esistente, altrimenti sarebbe un operazione infinita.
Per pre-configurare con una configurazione esistente si utilizzano alcune facilitazioni:
make oldconfig | cerca un file .config in uso e parte da li, chiedendo le informazioni mancanti rispetto alla versione che si sta compilando |
make olddefconfig | cerca un file .config in uso e parte da li, non domanda nulla, applica i default dove mancano informazioni |
make xxxxx_defconfig | Ogni architettura ha delle configurazioni predefinite, si trovano in arch/xxx/configs |
Quella scelta tra le operazioni sopra genera il file .config.
Il centro del processo di configurazione e' il file .config, la compilazione (make) utilizza sempre questo file.
Dopo aver preconfigurato il kernel come sopra, e generato .config, si puo modificarlo con un semplice
make menuconfig
.config sara' cosi aggiornato. Dall'attuale .config si puo creare un file "defconfig" ovvero una configurazione predefinita con
Codice:
make savedefconfig
cp defconfig arch/arm/configs/mio_defconfig
E riutilizzarla con
Codice:
make mio_defconfig
make
Nota: ogni modulo/driver puo essere compilato built-in [*] o loadable [M]. In un PC in genere si tengono abilitati tantissimi driver come [M] perche vengano riconosciuti in maniera dinamica dispositivi pluggati in bus pci / usb etc. Nelle schedine embedded in genere si abilitano solo i driver per i dispositivi presenti sulla schedina (platform driver/device), quindi pochissimi, la scelta se includerli built-in o caricabili e' dettata dalla strategia scelta (fast boot etc).
8) Modifiche
Aggiungiamo per test un semplice trace di debug,
nano arch/x86/kernel/setup.c
C:
786 * quirk is invoked before subsequent calls to __flush_tlb_all()
787 * so proper operation is guaranteed.
788 */
789 __flush_tlb_all();
790#else
791 printk(KERN_INFO "Command line: %s\n", boot_command_line);
792 boot_cpu_data.x86_phys_bits = MAX_PHYSMEM_BITS;
793
794 printk(KERN_INFO "%s() : boot_cpu_data.x86_phys_bits %d\n",
795 __func__, boot_cpu_data.x86_phys_bits);
796
797#endif
798
799 /*
800 * If we have OLPC OFW, we might end up relocating the fixmap due to
Dopo il boot, dal "dmesg", all'inizio subito dopo la command line dovrebbe apparire il vs. messaggio.
9) Compilazione
Che ci si trovi a compilare "native", cioe' con gcc installato sul tuo stesso pc dove eseguirai il kernel, o cross-compilare con toolchain specifica, i passi importanti per la compilazione sono:
Bash:
# cross compilazione, queste 4 linee non servono se si compila da e per lo stesso pc
export CROSS_COMPILE=/opt/toolchains/m68k/gcc-10.1.0-nolibc/m68k-linux/bin/m68k-linux-
export ARCH=m68k
entry_point=40001000
load_addr=0x${entry_point}
# compilazione
make specifico_defconfig
make -j24 KALLSYMS_EXTRA_PASS=1 LOADADDR=${load_addr} zImage
# moduli, facoltativo
make modules
make modules_install INSTALL_MOD_PATH=/....
Questo sopra e' solo il nocciolo della compilazione, lascio a voi arricchire lo script a piacimento.
Dalla zImage generata ogni distribuzione ha i propri comandi per generare l'apposito initramfs.
Questa prima guida si ferma qui, e si propone di avervi portato a generare la Vs. zImage. Spero ci siate riusciti. Per non mettere troppa carne al fuoco, aspetto Vs. commenti per eventualmente creare la parte 2.