hacking.rst (36508B)
1.. include:: ../disclaimer-ita.rst 2 3.. note:: Per leggere la documentazione originale in inglese: 4 :ref:`Documentation/kernel-hacking/hacking.rst <kernel_hacking_hack>` 5 6:Original: :ref:`Documentation/kernel-hacking/hacking.rst <kernel_hacking_hack>` 7:Translator: Federico Vaga <federico.vaga@vaga.pv.it> 8 9.. _it_kernel_hacking_hack: 10 11================================================= 12L'inaffidabile guida all'hacking del kernel Linux 13================================================= 14 15:Author: Rusty Russell 16 17Introduzione 18============ 19 20Benvenuto, gentile lettore, alla notevole ed inaffidabile guida all'hacking 21del kernel Linux ad opera di Rusty. Questo documento descrive le procedure 22più usate ed i concetti necessari per scrivere codice per il kernel: lo scopo 23è di fornire ai programmatori C più esperti un manuale di base per sviluppo. 24Eviterò dettagli implementativi: per questo abbiamo il codice, 25ed ignorerò intere parti di alcune procedure. 26 27Prima di leggere questa guida, sappiate che non ho mai voluto scriverla, 28essendo esageratamente sotto qualificato, ma ho sempre voluto leggere 29qualcosa di simile, e quindi questa era l'unica via. Spero che possa 30crescere e diventare un compendio di buone pratiche, punti di partenza 31e generiche informazioni. 32 33Gli attori 34========== 35 36In qualsiasi momento ognuna delle CPU di un sistema può essere: 37 38- non associata ad alcun processo, servendo un'interruzione hardware; 39 40- non associata ad alcun processo, servendo un softirq o tasklet; 41 42- in esecuzione nello spazio kernel, associata ad un processo 43 (contesto utente); 44 45- in esecuzione di un processo nello spazio utente; 46 47Esiste un ordine fra questi casi. Gli ultimi due possono avvicendarsi (preempt) 48l'un l'altro, ma a parte questo esiste una gerarchia rigida: ognuno di questi 49può avvicendarsi solo ad uno di quelli sottostanti. Per esempio, mentre un 50softirq è in esecuzione su d'una CPU, nessun altro softirq può avvicendarsi 51nell'esecuzione, ma un'interruzione hardware può. Ciò nonostante, le altre CPU 52del sistema operano indipendentemente. 53 54Più avanti vedremo alcuni modi in cui dal contesto utente è possibile bloccare 55le interruzioni, così da impedirne davvero il diritto di prelazione. 56 57Contesto utente 58--------------- 59 60Ci si trova nel contesto utente quando si arriva da una chiamata di sistema 61od altre eccezioni: come nello spazio utente, altre procedure più importanti, 62o le interruzioni, possono far valere il proprio diritto di prelazione sul 63vostro processo. Potete sospendere l'esecuzione chiamando :c:func:`schedule()`. 64 65.. note:: 66 67 Si è sempre in contesto utente quando un modulo viene caricato o rimosso, 68 e durante le operazioni nello strato dei dispositivi a blocchi 69 (*block layer*). 70 71Nel contesto utente, il puntatore ``current`` (il quale indica il processo al 72momento in esecuzione) è valido, e :c:func:`in_interrupt()` 73(``include/linux/preempt.h``) è falsa. 74 75.. warning:: 76 77 Attenzione che se avete la prelazione o i softirq disabilitati (vedere 78 di seguito), :c:func:`in_interrupt()` ritornerà un falso positivo. 79 80Interruzioni hardware (Hard IRQs) 81--------------------------------- 82 83Temporizzatori, schede di rete e tastiere sono esempi di vero hardware 84che possono produrre interruzioni in un qualsiasi momento. Il kernel esegue 85i gestori d'interruzione che prestano un servizio all'hardware. Il kernel 86garantisce che questi gestori non vengano mai interrotti: se una stessa 87interruzione arriva, questa verrà accodata (o scartata). 88Dato che durante la loro esecuzione le interruzioni vengono disabilitate, 89i gestori d'interruzioni devono essere veloci: spesso si limitano 90esclusivamente a notificare la presa in carico dell'interruzione, 91programmare una 'interruzione software' per l'esecuzione e quindi terminare. 92 93Potete dire d'essere in una interruzione hardware perché in_hardirq() 94ritorna vero. 95 96.. warning:: 97 98 Attenzione, questa ritornerà un falso positivo se le interruzioni 99 sono disabilitate (vedere di seguito). 100 101Contesto d'interruzione software: softirq e tasklet 102--------------------------------------------------- 103 104Quando una chiamata di sistema sta per tornare allo spazio utente, 105oppure un gestore d'interruzioni termina, qualsiasi 'interruzione software' 106marcata come pendente (solitamente da un'interruzione hardware) viene 107eseguita (``kernel/softirq.c``). 108 109La maggior parte del lavoro utile alla gestione di un'interruzione avviene qui. 110All'inizio della transizione ai sistemi multiprocessore, c'erano solo i 111cosiddetti 'bottom half' (BH), i quali non traevano alcun vantaggio da questi 112sistemi. Non appena abbandonammo i computer raffazzonati con fiammiferi e 113cicche, abbandonammo anche questa limitazione e migrammo alle interruzioni 114software 'softirqs'. 115 116Il file ``include/linux/interrupt.h`` elenca i differenti tipi di 'softirq'. 117Un tipo di softirq molto importante è il timer (``include/linux/timer.h``): 118potete programmarlo per far si che esegua funzioni dopo un determinato 119periodo di tempo. 120 121Dato che i softirq possono essere eseguiti simultaneamente su più di un 122processore, spesso diventa estenuante l'averci a che fare. Per questa ragione, 123i tasklet (``include/linux/interrupt.h``) vengo usati più di frequente: 124possono essere registrati dinamicamente (il che significa che potete averne 125quanti ne volete), e garantiscono che un qualsiasi tasklet verrà eseguito 126solo su un processore alla volta, sebbene diversi tasklet possono essere 127eseguiti simultaneamente. 128 129.. warning:: 130 131 Il nome 'tasklet' è ingannevole: non hanno niente a che fare 132 con i 'processi' ('tasks'), e probabilmente hanno più a che vedere 133 con qualche pessima vodka che Alexey Kuznetsov si fece a quel tempo. 134 135Potete determinate se siete in un softirq (o tasklet) utilizzando la 136macro :c:func:`in_softirq()` (``include/linux/preempt.h``). 137 138.. warning:: 139 140 State attenti che questa macro ritornerà un falso positivo 141 se :ref:`botton half lock <it_local_bh_disable>` è bloccato. 142 143Alcune regole basilari 144====================== 145 146Nessuna protezione della memoria 147 Se corrompete la memoria, che sia in contesto utente o d'interruzione, 148 la macchina si pianterà. Siete sicuri che quello che volete fare 149 non possa essere fatto nello spazio utente? 150 151Nessun numero in virgola mobile o MMX 152 Il contesto della FPU non è salvato; anche se siete in contesto utente 153 lo stato dell'FPU probabilmente non corrisponde a quello del processo 154 corrente: vi incasinerete con lo stato di qualche altro processo. Se 155 volete davvero usare la virgola mobile, allora dovrete salvare e recuperare 156 lo stato dell'FPU (ed evitare cambi di contesto). Generalmente è una 157 cattiva idea; usate l'aritmetica a virgola fissa. 158 159Un limite rigido dello stack 160 A seconda della configurazione del kernel lo stack è fra 3K e 6K per la 161 maggior parte delle architetture a 32-bit; è di 14K per la maggior 162 parte di quelle a 64-bit; e spesso è condiviso con le interruzioni, 163 per cui non si può usare. 164 Evitare profonde ricorsioni ad enormi array locali nello stack 165 (allocateli dinamicamente). 166 167Il kernel Linux è portabile 168 Quindi mantenetelo tale. Il vostro codice dovrebbe essere a 64-bit ed 169 indipendente dall'ordine dei byte (endianess) di un processore. Inoltre, 170 dovreste minimizzare il codice specifico per un processore; per esempio 171 il codice assembly dovrebbe essere incapsulato in modo pulito e minimizzato 172 per facilitarne la migrazione. Generalmente questo codice dovrebbe essere 173 limitato alla parte di kernel specifica per un'architettura. 174 175ioctl: non scrivere nuove chiamate di sistema 176============================================= 177 178Una chiamata di sistema, generalmente, è scritta così:: 179 180 asmlinkage long sys_mycall(int arg) 181 { 182 return 0; 183 } 184 185Primo, nella maggior parte dei casi non volete creare nuove chiamate di 186sistema. 187Create un dispositivo a caratteri ed implementate l'appropriata chiamata ioctl. 188Questo meccanismo è molto più flessibile delle chiamate di sistema: esso non 189dev'essere dichiarato in tutte le architetture nei file 190``include/asm/unistd.h`` e ``arch/kernel/entry.S``; inoltre, è improbabile 191che questo venga accettato da Linus. 192 193Se tutto quello che il vostro codice fa è leggere o scrivere alcuni parametri, 194considerate l'implementazione di un'interfaccia :c:func:`sysfs()`. 195 196All'interno di una ioctl vi trovate nel contesto utente di un processo. Quando 197avviene un errore dovete ritornare un valore negativo di errno (consultate 198``include/uapi/asm-generic/errno-base.h``, 199``include/uapi/asm-generic/errno.h`` e ``include/linux/errno.h``), altrimenti 200ritornate 0. 201 202Dopo aver dormito dovreste verificare se ci sono stati dei segnali: il modo 203Unix/Linux di gestire un segnale è di uscire temporaneamente dalla chiamata 204di sistema con l'errore ``-ERESTARTSYS``. La chiamata di sistema ritornerà 205al contesto utente, eseguirà il gestore del segnale e poi la vostra chiamata 206di sistema riprenderà (a meno che l'utente non l'abbia disabilitata). Quindi, 207dovreste essere pronti per continuare l'esecuzione, per esempio nel mezzo 208della manipolazione di una struttura dati. 209 210:: 211 212 if (signal_pending(current)) 213 return -ERESTARTSYS; 214 215Se dovete eseguire dei calcoli molto lunghi: pensate allo spazio utente. 216Se **davvero** volete farlo nel kernel ricordatevi di verificare periodicamente 217se dovete *lasciare* il processore (ricordatevi che, per ogni processore, c'è 218un sistema multi-processo senza diritto di prelazione). 219Esempio:: 220 221 cond_resched(); /* Will sleep */ 222 223Una breve nota sulla progettazione delle interfacce: il motto dei sistemi 224UNIX è "fornite meccanismi e non politiche" 225 226La ricetta per uno stallo 227========================= 228 229Non è permesso invocare una procedura che potrebbe dormire, fanno eccezione 230i seguenti casi: 231 232- Siete in un contesto utente. 233 234- Non trattenete alcun spinlock. 235 236- Avete abilitato le interruzioni (in realtà, Andy Kleen dice che 237 lo schedulatore le abiliterà per voi, ma probabilmente questo non è quello 238 che volete). 239 240Da tener presente che alcune funzioni potrebbero dormire implicitamente: 241le più comuni sono quelle per l'accesso allo spazio utente (\*_user) e 242quelle per l'allocazione della memoria senza l'opzione ``GFP_ATOMIC`` 243 244Dovreste sempre compilare il kernel con l'opzione ``CONFIG_DEBUG_ATOMIC_SLEEP`` 245attiva, questa vi avviserà se infrangete una di queste regole. 246Se **infrangete** le regole, allora potreste bloccare il vostro scatolotto. 247 248Veramente. 249 250Alcune delle procedure più comuni 251================================= 252 253:c:func:`printk()` 254------------------ 255 256Definita in ``include/linux/printk.h`` 257 258:c:func:`printk()` fornisce messaggi alla console, dmesg, e al demone syslog. 259Essa è utile per il debugging o per la notifica di errori; può essere 260utilizzata anche all'interno del contesto d'interruzione, ma usatela con 261cautela: una macchina che ha la propria console inondata da messaggi diventa 262inutilizzabile. La funzione utilizza un formato stringa quasi compatibile con 263la printf ANSI C, e la concatenazione di una stringa C come primo argomento 264per indicare la "priorità":: 265 266 printk(KERN_INFO "i = %u\n", i); 267 268Consultate ``include/linux/kern_levels.h`` per gli altri valori ``KERN_``; 269questi sono interpretati da syslog come livelli. Un caso speciale: 270per stampare un indirizzo IP usate:: 271 272 __be32 ipaddress; 273 printk(KERN_INFO "my ip: %pI4\n", &ipaddress); 274 275 276:c:func:`printk()` utilizza un buffer interno di 1K e non s'accorge di 277eventuali sforamenti. Accertatevi che vi basti. 278 279.. note:: 280 281 Saprete di essere un vero hacker del kernel quando inizierete a digitare 282 nei vostri programmi utenti le printf come se fossero printk :) 283 284.. note:: 285 286 Un'altra nota a parte: la versione originale di Unix 6 aveva un commento 287 sopra alla funzione printf: "Printf non dovrebbe essere usata per il 288 chiacchiericcio". Dovreste seguire questo consiglio. 289 290:c:func:`copy_to_user()` / :c:func:`copy_from_user()` / :c:func:`get_user()` / :c:func:`put_user()` 291--------------------------------------------------------------------------------------------------- 292 293Definite in ``include/linux/uaccess.h`` / ``asm/uaccess.h`` 294 295**[DORMONO]** 296 297:c:func:`put_user()` e :c:func:`get_user()` sono usate per ricevere ed 298impostare singoli valori (come int, char, o long) da e verso lo spazio utente. 299Un puntatore nello spazio utente non dovrebbe mai essere dereferenziato: i dati 300dovrebbero essere copiati usando suddette procedure. Entrambe ritornano 301``-EFAULT`` oppure 0. 302 303:c:func:`copy_to_user()` e :c:func:`copy_from_user()` sono più generiche: 304esse copiano una quantità arbitraria di dati da e verso lo spazio utente. 305 306.. warning:: 307 308 Al contrario di:c:func:`put_user()` e :c:func:`get_user()`, queste 309 funzioni ritornano la quantità di dati copiati (0 è comunque un successo). 310 311[Sì, questa stupida interfaccia mi imbarazza. La battaglia torna in auge anno 312dopo anno. --RR] 313 314Le funzioni potrebbero dormire implicitamente. Queste non dovrebbero mai essere 315invocate fuori dal contesto utente (non ha senso), con le interruzioni 316disabilitate, o con uno spinlock trattenuto. 317 318:c:func:`kmalloc()`/:c:func:`kfree()` 319------------------------------------- 320 321Definite in ``include/linux/slab.h`` 322 323**[POTREBBERO DORMIRE: LEGGI SOTTO]** 324 325Queste procedure sono utilizzate per la richiesta dinamica di un puntatore ad 326un pezzo di memoria allineato, esattamente come malloc e free nello spazio 327utente, ma :c:func:`kmalloc()` ha un argomento aggiuntivo per indicare alcune 328opzioni. Le opzioni più importanti sono: 329 330``GFP_KERNEL`` 331 Potrebbe dormire per librarare della memoria. L'opzione fornisce il modo 332 più affidabile per allocare memoria, ma il suo uso è strettamente limitato 333 allo spazio utente. 334 335``GFP_ATOMIC`` 336 Non dorme. Meno affidabile di ``GFP_KERNEL``, ma può essere usata in un 337 contesto d'interruzione. Dovreste avere **davvero** una buona strategia 338 per la gestione degli errori in caso di mancanza di memoria. 339 340``GFP_DMA`` 341 Alloca memoria per il DMA sul bus ISA nello spazio d'indirizzamento 342 inferiore ai 16MB. Se non sapete cos'è allora non vi serve. 343 Molto inaffidabile. 344 345Se vedete un messaggio d'avviso per una funzione dormiente che viene chiamata 346da un contesto errato, allora probabilmente avete usato una funzione 347d'allocazione dormiente da un contesto d'interruzione senza ``GFP_ATOMIC``. 348Dovreste correggerlo. Sbrigatevi, non cincischiate. 349 350Se allocate almeno ``PAGE_SIZE``(``asm/page.h`` o ``asm/page_types.h``) byte, 351considerate l'uso di :c:func:`__get_free_pages()` (``include/linux/gfp.h``). 352Accetta un argomento che definisce l'ordine (0 per per la dimensione di una 353pagine, 1 per una doppia pagina, 2 per quattro pagine, eccetra) e le stesse 354opzioni d'allocazione viste precedentemente. 355 356Se state allocando un numero di byte notevolemnte superiore ad una pagina 357potete usare :c:func:`vmalloc()`. Essa allocherà memoria virtuale all'interno 358dello spazio kernel. Questo è un blocco di memoria fisica non contiguo, ma 359la MMU vi darà l'impressione che lo sia (quindi, sarà contiguo solo dal punto 360di vista dei processori, non dal punto di vista dei driver dei dispositivi 361esterni). 362Se per qualche strana ragione avete davvero bisogno di una grossa quantità di 363memoria fisica contigua, avete un problema: Linux non ha un buon supporto per 364questo caso d'uso perché, dopo un po' di tempo, la frammentazione della memoria 365rende l'operazione difficile. Il modo migliore per allocare un simile blocco 366all'inizio dell'avvio del sistema è attraverso la procedura 367:c:func:`alloc_bootmem()`. 368 369Prima di inventare la vostra cache per gli oggetti più usati, considerate 370l'uso di una cache slab disponibile in ``include/linux/slab.h``. 371 372:c:macro:`current` 373------------------- 374 375Definita in ``include/asm/current.h`` 376 377Questa variabile globale (in realtà una macro) contiene un puntatore alla 378struttura del processo corrente, quindi è valido solo dal contesto utente. 379Per esempio, quando un processo esegue una chiamata di sistema, questo 380punterà alla struttura dati del processo chiamate. 381Nel contesto d'interruzione in suo valore **non è NULL**. 382 383:c:func:`mdelay()`/:c:func:`udelay()` 384------------------------------------- 385 386Definite in ``include/asm/delay.h`` / ``include/linux/delay.h`` 387 388Le funzioni :c:func:`udelay()` e :c:func:`ndelay()` possono essere utilizzate 389per brevi pause. Non usate grandi valori perché rischiate d'avere un 390overflow - in questo contesto la funzione :c:func:`mdelay()` è utile, 391oppure considerate :c:func:`msleep()`. 392 393:c:func:`cpu_to_be32()`/:c:func:`be32_to_cpu()`/:c:func:`cpu_to_le32()`/:c:func:`le32_to_cpu()` 394----------------------------------------------------------------------------------------------- 395 396Definite in ``include/asm/byteorder.h`` 397 398La famiglia di funzioni :c:func:`cpu_to_be32()` (dove "32" può essere 399sostituito da 64 o 16, e "be" con "le") forniscono un modo generico 400per fare conversioni sull'ordine dei byte (endianess): esse ritornano 401il valore convertito. Tutte le varianti supportano anche il processo inverso: 402:c:func:`be32_to_cpu()`, eccetera. 403 404Queste funzioni hanno principalmente due varianti: la variante per 405puntatori, come :c:func:`cpu_to_be32p()`, che prende un puntatore 406ad un tipo, e ritorna il valore convertito. L'altra variante per 407la famiglia di conversioni "in-situ", come :c:func:`cpu_to_be32s()`, 408che convertono il valore puntato da un puntatore, e ritornano void. 409 410:c:func:`local_irq_save()`/:c:func:`local_irq_restore()` 411-------------------------------------------------------- 412 413Definite in ``include/linux/irqflags.h`` 414 415Queste funzioni abilitano e disabilitano le interruzioni hardware 416sul processore locale. Entrambe sono rientranti; esse salvano lo stato 417precedente nel proprio argomento ``unsigned long flags``. Se sapete 418che le interruzioni sono abilite, potete semplicemente utilizzare 419:c:func:`local_irq_disable()` e :c:func:`local_irq_enable()`. 420 421.. _it_local_bh_disable: 422 423:c:func:`local_bh_disable()`/:c:func:`local_bh_enable()` 424-------------------------------------------------------- 425 426Definite in ``include/linux/bottom_half.h`` 427 428 429Queste funzioni abilitano e disabilitano le interruzioni software 430sul processore locale. Entrambe sono rientranti; se le interruzioni 431software erano già state disabilitate in precedenza, rimarranno 432disabilitate anche dopo aver invocato questa coppia di funzioni. 433Lo scopo è di prevenire l'esecuzione di softirq e tasklet sul processore 434attuale. 435 436:c:func:`smp_processor_id()` 437---------------------------- 438 439Definita in ``include/linux/smp.h`` 440 441:c:func:`get_cpu()` nega il diritto di prelazione (quindi non potete essere 442spostati su un altro processore all'improvviso) e ritorna il numero 443del processore attuale, fra 0 e ``NR_CPUS``. Da notare che non è detto 444che la numerazione dei processori sia continua. Quando avete terminato, 445ritornate allo stato precedente con :c:func:`put_cpu()`. 446 447Se sapete che non dovete essere interrotti da altri processi (per esempio, 448se siete in un contesto d'interruzione, o il diritto di prelazione 449è disabilitato) potete utilizzare smp_processor_id(). 450 451 452``__init``/``__exit``/``__initdata`` 453------------------------------------ 454 455Definite in ``include/linux/init.h`` 456 457Dopo l'avvio, il kernel libera una sezione speciale; le funzioni marcate 458con ``__init`` e le strutture dati marcate con ``__initdata`` vengono 459eliminate dopo il completamento dell'avvio: in modo simile i moduli eliminano 460questa memoria dopo l'inizializzazione. ``__exit`` viene utilizzato per 461dichiarare che una funzione verrà utilizzata solo in fase di rimozione: 462la detta funzione verrà eliminata quando il file che la contiene non è 463compilato come modulo. Guardate l'header file per informazioni. Da notare che 464non ha senso avere una funzione marcata come ``__init`` e al tempo stesso 465esportata ai moduli utilizzando :c:func:`EXPORT_SYMBOL()` o 466:c:func:`EXPORT_SYMBOL_GPL()` - non funzionerà. 467 468 469:c:func:`__initcall()`/:c:func:`module_init()` 470---------------------------------------------- 471 472Definite in ``include/linux/init.h`` / ``include/linux/module.h`` 473 474Molte parti del kernel funzionano bene come moduli (componenti del kernel 475caricabili dinamicamente). L'utilizzo delle macro :c:func:`module_init()` 476e :c:func:`module_exit()` semplifica la scrittura di codice che può funzionare 477sia come modulo, sia come parte del kernel, senza l'ausilio di #ifdef. 478 479La macro :c:func:`module_init()` definisce quale funzione dev'essere 480chiamata quando il modulo viene inserito (se il file è stato compilato come 481tale), o in fase di avvio : se il file non è stato compilato come modulo la 482macro :c:func:`module_init()` diventa equivalente a :c:func:`__initcall()`, 483la quale, tramite qualche magia del linker, s'assicura che la funzione venga 484chiamata durante l'avvio. 485 486La funzione può ritornare un numero d'errore negativo per scatenare un 487fallimento del caricamento (sfortunatamente, questo non ha effetto se il 488modulo è compilato come parte integrante del kernel). Questa funzione è chiamata 489in contesto utente con le interruzioni abilitate, quindi potrebbe dormire. 490 491 492:c:func:`module_exit()` 493----------------------- 494 495 496Definita in ``include/linux/module.h`` 497 498Questa macro definisce la funzione che dev'essere chiamata al momento della 499rimozione (o mai, nel caso in cui il file sia parte integrante del kernel). 500Essa verrà chiamata solo quando il contatore d'uso del modulo raggiunge lo 501zero. Questa funzione può anche dormire, ma non può fallire: tutto dev'essere 502ripulito prima che la funzione ritorni. 503 504Da notare che questa macro è opzionale: se non presente, il modulo non sarà 505removibile (a meno che non usiate 'rmmod -f' ). 506 507 508:c:func:`try_module_get()`/:c:func:`module_put()` 509------------------------------------------------- 510 511Definite in ``include/linux/module.h`` 512 513Queste funzioni maneggiano il contatore d'uso del modulo per proteggerlo dalla 514rimozione (in aggiunta, un modulo non può essere rimosso se un altro modulo 515utilizzo uno dei sui simboli esportati: vedere di seguito). Prima di eseguire 516codice del modulo, dovreste chiamare :c:func:`try_module_get()` su quel modulo: 517se fallisce significa che il modulo è stato rimosso e dovete agire come se 518non fosse presente. Altrimenti, potete accedere al modulo in sicurezza, e 519chiamare :c:func:`module_put()` quando avete finito. 520 521La maggior parte delle strutture registrabili hanno un campo owner 522(proprietario), come nella struttura 523:c:type:`struct file_operations <file_operations>`. 524Impostate questo campo al valore della macro ``THIS_MODULE``. 525 526 527Code d'attesa ``include/linux/wait.h`` 528====================================== 529 530**[DORMONO]** 531 532Una coda d'attesa è usata per aspettare che qualcuno vi attivi quando una 533certa condizione s'avvera. Per evitare corse critiche, devono essere usate 534con cautela. Dichiarate una :c:type:`wait_queue_head_t`, e poi i processi 535che vogliono attendere il verificarsi di quella condizione dichiareranno 536una :c:type:`wait_queue_entry_t` facendo riferimento a loro stessi, poi 537metteranno questa in coda. 538 539Dichiarazione 540------------- 541 542Potere dichiarare una ``wait_queue_head_t`` utilizzando la macro 543:c:func:`DECLARE_WAIT_QUEUE_HEAD()` oppure utilizzando la procedura 544:c:func:`init_waitqueue_head()` nel vostro codice d'inizializzazione. 545 546Accodamento 547----------- 548 549Mettersi in una coda d'attesa è piuttosto complesso, perché dovete 550mettervi in coda prima di verificare la condizione. Esiste una macro 551a questo scopo: :c:func:`wait_event_interruptible()` (``include/linux/wait.h``). 552Il primo argomento è la testa della coda d'attesa, e il secondo è 553un'espressione che dev'essere valutata; la macro ritorna 0 quando questa 554espressione è vera, altrimenti ``-ERESTARTSYS`` se è stato ricevuto un segnale. 555La versione :c:func:`wait_event()` ignora i segnali. 556 557Svegliare una procedura in coda 558------------------------------- 559 560Chiamate :c:func:`wake_up()` (``include/linux/wait.h``); questa attiverà tutti 561i processi in coda. Ad eccezione se uno di questi è impostato come 562``TASK_EXCLUSIVE``, in questo caso i rimanenti non verranno svegliati. 563Nello stesso header file esistono altre varianti di questa funzione. 564 565Operazioni atomiche 566=================== 567 568Certe operazioni sono garantite come atomiche su tutte le piattaforme. 569Il primo gruppo di operazioni utilizza :c:type:`atomic_t` 570(``include/asm/atomic.h``); questo contiene un intero con segno (minimo 32bit), 571e dovete utilizzare queste funzione per modificare o leggere variabili di tipo 572:c:type:`atomic_t`. :c:func:`atomic_read()` e :c:func:`atomic_set()` leggono ed 573impostano il contatore, :c:func:`atomic_add()`, :c:func:`atomic_sub()`, 574:c:func:`atomic_inc()`, :c:func:`atomic_dec()`, e 575:c:func:`atomic_dec_and_test()` (ritorna vero se raggiunge zero dopo essere 576stata decrementata). 577 578Sì. Ritorna vero (ovvero != 0) se la variabile atomica è zero. 579 580Da notare che queste funzioni sono più lente rispetto alla normale aritmetica, 581e quindi non dovrebbero essere usate a sproposito. 582 583Il secondo gruppo di operazioni atomiche sono definite in 584``include/linux/bitops.h`` ed agiscono sui bit d'una variabile di tipo 585``unsigned long``. Queste operazioni prendono come argomento un puntatore 586alla variabile, e un numero di bit dove 0 è quello meno significativo. 587:c:func:`set_bit()`, :c:func:`clear_bit()` e :c:func:`change_bit()` 588impostano, cancellano, ed invertono il bit indicato. 589:c:func:`test_and_set_bit()`, :c:func:`test_and_clear_bit()` e 590:c:func:`test_and_change_bit()` fanno la stessa cosa, ad eccezione che 591ritornano vero se il bit era impostato; queste sono particolarmente 592utili quando si vuole impostare atomicamente dei flag. 593 594Con queste operazioni è possibile utilizzare indici di bit che eccedono 595il valore ``BITS_PER_LONG``. Il comportamento è strano sulle piattaforme 596big-endian quindi è meglio evitarlo. 597 598Simboli 599======= 600 601All'interno del kernel, si seguono le normali regole del linker (ovvero, 602a meno che un simbolo non venga dichiarato con visibilita limitata ad un 603file con la parola chiave ``static``, esso può essere utilizzato in qualsiasi 604parte del kernel). Nonostante ciò, per i moduli, esiste una tabella dei 605simboli esportati che limita i punti di accesso al kernel. Anche i moduli 606possono esportare simboli. 607 608:c:func:`EXPORT_SYMBOL()` 609------------------------- 610 611Definita in ``include/linux/export.h`` 612 613Questo è il classico metodo per esportare un simbolo: i moduli caricati 614dinamicamente potranno utilizzare normalmente il simbolo. 615 616:c:func:`EXPORT_SYMBOL_GPL()` 617----------------------------- 618 619Definita in ``include/linux/export.h`` 620 621Essa è simile a :c:func:`EXPORT_SYMBOL()` ad eccezione del fatto che i 622simboli esportati con :c:func:`EXPORT_SYMBOL_GPL()` possono essere 623utilizzati solo dai moduli che hanno dichiarato una licenza compatibile 624con la GPL attraverso :c:func:`MODULE_LICENSE()`. Questo implica che la 625funzione esportata è considerata interna, e non una vera e propria interfaccia. 626Alcuni manutentori e sviluppatori potrebbero comunque richiedere 627:c:func:`EXPORT_SYMBOL_GPL()` quando si aggiungono nuove funzionalità o 628interfacce. 629 630:c:func:`EXPORT_SYMBOL_NS()` 631---------------------------- 632 633Definita in ``include/linux/export.h`` 634 635Questa è una variate di `EXPORT_SYMBOL()` che permette di specificare uno 636spazio dei nomi. Lo spazio dei nomi è documentato in 637Documentation/translations/it_IT/core-api/symbol-namespaces.rst. 638 639:c:func:`EXPORT_SYMBOL_NS_GPL()` 640-------------------------------- 641 642Definita in ``include/linux/export.h`` 643 644Questa è una variate di `EXPORT_SYMBOL_GPL()` che permette di specificare uno 645spazio dei nomi. Lo spazio dei nomi è documentato in 646Documentation/translations/it_IT/core-api/symbol-namespaces.rst. 647 648Procedure e convenzioni 649======================= 650 651Liste doppiamente concatenate ``include/linux/list.h`` 652------------------------------------------------------ 653 654Un tempo negli header del kernel c'erano tre gruppi di funzioni per 655le liste concatenate, ma questa è stata la vincente. Se non avete particolari 656necessità per una semplice lista concatenata, allora questa è una buona scelta. 657 658In particolare, :c:func:`list_for_each_entry()` è utile. 659 660Convenzione dei valori di ritorno 661--------------------------------- 662 663Per codice chiamato in contesto utente, è molto comune sfidare le convenzioni 664C e ritornare 0 in caso di successo, ed un codice di errore negativo 665(eg. ``-EFAULT``) nei casi fallimentari. Questo potrebbe essere controintuitivo 666a prima vista, ma è abbastanza diffuso nel kernel. 667 668Utilizzate :c:func:`ERR_PTR()` (``include/linux/err.h``) per codificare 669un numero d'errore negativo in un puntatore, e :c:func:`IS_ERR()` e 670:c:func:`PTR_ERR()` per recuperarlo di nuovo: così si evita d'avere un 671puntatore dedicato per il numero d'errore. Da brividi, ma in senso positivo. 672 673Rompere la compilazione 674----------------------- 675 676Linus e gli altri sviluppatori a volte cambiano i nomi delle funzioni e 677delle strutture nei kernel in sviluppo; questo non è solo per tenere 678tutti sulle spine: questo riflette cambiamenti fondamentati (eg. la funzione 679non può più essere chiamata con le funzioni attive, o fa controlli aggiuntivi, 680o non fa più controlli che venivano fatti in precedenza). Solitamente a questo 681s'accompagna un'adeguata e completa nota sulla lista di discussone 682linux-kernel; cercate negli archivi. 683Solitamente eseguire una semplice sostituzione su tutto un file rendere 684le cose **peggiori**. 685 686Inizializzazione dei campi d'una struttura 687------------------------------------------ 688 689Il metodo preferito per l'inizializzazione delle strutture è quello 690di utilizzare gli inizializzatori designati, come definiti nello 691standard ISO C99, eg:: 692 693 static struct block_device_operations opt_fops = { 694 .open = opt_open, 695 .release = opt_release, 696 .ioctl = opt_ioctl, 697 .check_media_change = opt_media_change, 698 }; 699 700Questo rende più facile la ricerca con grep, e rende più chiaro quale campo 701viene impostato. Dovreste fare così perché si mostra meglio. 702 703Estensioni GNU 704-------------- 705 706Le estensioni GNU sono esplicitamente permesse nel kernel Linux. Da notare 707che alcune delle più complesse non sono ben supportate, per via dello scarso 708sviluppo, ma le seguenti sono da considerarsi la norma (per maggiori dettagli, 709leggete la sezione "C Extensions" nella pagina info di GCC - Sì, davvero 710la pagina info, la pagina man è solo un breve riassunto delle cose nella 711pagina info). 712 713- Funzioni inline 714 715- Istruzioni in espressioni (ie. il costrutto ({ and }) ). 716 717- Dichiarate attributi di una funzione / variabile / tipo 718 (__attribute__) 719 720- typeof 721 722- Array con lunghezza zero 723 724- Macro varargs 725 726- Aritmentica sui puntatori void 727 728- Inizializzatori non costanti 729 730- Istruzioni assembler (non al di fuori di 'arch/' e 'include/asm/') 731 732- Nomi delle funzioni come stringhe (__func__). 733 734- __builtin_constant_p() 735 736Siate sospettosi quando utilizzate long long nel kernel, il codice generato 737da gcc è orribile ed anche peggio: le divisioni e le moltiplicazioni non 738funzionano sulle piattaforme i386 perché le rispettive funzioni di runtime 739di GCC non sono incluse nell'ambiente del kernel. 740 741C++ 742--- 743 744Solitamente utilizzare il C++ nel kernel è una cattiva idea perché 745il kernel non fornisce il necessario ambiente di runtime e gli header file 746non sono stati verificati. Rimane comunque possibile, ma non consigliato. 747Se davvero volete usarlo, almeno evitate le eccezioni. 748 749NUMif 750----- 751 752Viene generalmente considerato più pulito l'uso delle macro negli header file 753(o all'inizio dei file .c) per astrarre funzioni piuttosto che utlizzare 754l'istruzione di pre-processore \`#if' all'interno del codice sorgente. 755 756Mettere le vostre cose nel kernel 757================================= 758 759Al fine d'avere le vostre cose in ordine per l'inclusione ufficiale, o 760anche per avere patch pulite, c'è del lavoro amministrativo da fare: 761 762- Trovare di chi è lo stagno in cui state pisciando. Guardare in cima 763 ai file sorgenti, all'interno del file ``MAINTAINERS``, ed alla fine 764 di tutti nel file ``CREDITS``. Dovreste coordinarvi con queste persone 765 per evitare di duplicare gli sforzi, o provare qualcosa che è già stato 766 rigettato. 767 768 Assicuratevi di mettere il vostro nome ed indirizzo email in cima a 769 tutti i file che create o che mangeggiate significativamente. Questo è 770 il primo posto dove le persone guarderanno quando troveranno un baco, 771 o quando **loro** vorranno fare una modifica. 772 773- Solitamente vorrete un'opzione di configurazione per la vostra modifica 774 al kernel. Modificate ``Kconfig`` nella cartella giusta. Il linguaggio 775 Config è facile con copia ed incolla, e c'è una completa documentazione 776 nel file ``Documentation/kbuild/kconfig-language.rst``. 777 778 Nella descrizione della vostra opzione, assicuratevi di parlare sia agli 779 utenti esperti sia agli utente che non sanno nulla del vostro lavoro. 780 Menzionate qui le incompatibilità ed i problemi. Chiaramente la 781 descrizione deve terminare con “if in doubt, say N” (se siete in dubbio, 782 dite N) (oppure, occasionalmente, \`Y'); questo è per le persone che non 783 hanno idea di che cosa voi stiate parlando. 784 785- Modificate il file ``Makefile``: le variabili CONFIG sono esportate qui, 786 quindi potete solitamente aggiungere una riga come la seguete 787 "obj-$(CONFIG_xxx) += xxx.o". La sintassi è documentata nel file 788 ``Documentation/kbuild/makefiles.rst``. 789 790- Aggiungete voi stessi in ``CREDITS`` se avete fatto qualcosa di notevole, 791 solitamente qualcosa che supera il singolo file (comunque il vostro nome 792 dovrebbe essere all'inizio dei file sorgenti). ``MAINTAINERS`` significa 793 che volete essere consultati quando vengono fatte delle modifiche ad un 794 sottosistema, e quando ci sono dei bachi; questo implica molto di più 795 di un semplice impegno su una parte del codice. 796 797- Infine, non dimenticatevi di leggere 798 ``Documentation/process/submitting-patches.rst`` e possibilmente anche 799 ``Documentation/process/submitting-drivers.rst``. 800 801Trucchetti del kernel 802===================== 803 804Dopo una rapida occhiata al codice, questi sono i preferiti. Sentitevi liberi 805di aggiungerne altri. 806 807``arch/x86/include/asm/delay.h``:: 808 809 #define ndelay(n) (__builtin_constant_p(n) ? \ 810 ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ 811 __ndelay(n)) 812 813 814``include/linux/fs.h``:: 815 816 /* 817 * Kernel pointers have redundant information, so we can use a 818 * scheme where we can return either an error code or a dentry 819 * pointer with the same return value. 820 * 821 * This should be a per-architecture thing, to allow different 822 * error and pointer decisions. 823 */ 824 #define ERR_PTR(err) ((void *)((long)(err))) 825 #define PTR_ERR(ptr) ((long)(ptr)) 826 #define IS_ERR(ptr) ((unsigned long)(ptr) > (unsigned long)(-1000)) 827 828``arch/x86/include/asm/uaccess_32.h:``:: 829 830 #define copy_to_user(to,from,n) \ 831 (__builtin_constant_p(n) ? \ 832 __constant_copy_to_user((to),(from),(n)) : \ 833 __generic_copy_to_user((to),(from),(n))) 834 835 836``arch/sparc/kernel/head.S:``:: 837 838 /* 839 * Sun people can't spell worth damn. "compatability" indeed. 840 * At least we *know* we can't spell, and use a spell-checker. 841 */ 842 843 /* Uh, actually Linus it is I who cannot spell. Too much murky 844 * Sparc assembly will do this to ya. 845 */ 846 C_LABEL(cputypvar): 847 .asciz "compatibility" 848 849 /* Tested on SS-5, SS-10. Probably someone at Sun applied a spell-checker. */ 850 .align 4 851 C_LABEL(cputypvar_sun4m): 852 .asciz "compatible" 853 854 855``arch/sparc/lib/checksum.S:``:: 856 857 /* Sun, you just can't beat me, you just can't. Stop trying, 858 * give up. I'm serious, I am going to kick the living shit 859 * out of you, game over, lights out. 860 */ 861 862 863Ringraziamenti 864============== 865 866Ringrazio Andi Kleen per le sue idee, le risposte alle mie domande, 867le correzioni dei miei errori, l'aggiunta di contenuti, eccetera. 868Philipp Rumpf per l'ortografia e per aver reso più chiaro il testo, e 869per alcuni eccellenti punti tutt'altro che ovvi. Werner Almesberger 870per avermi fornito un ottimo riassunto di :c:func:`disable_irq()`, 871e Jes Sorensen e Andrea Arcangeli per le precisazioni. Michael Elizabeth 872Chastain per aver verificato ed aggiunto la sezione configurazione. 873Telsa Gwynne per avermi insegnato DocBook.