Back to home page

OSCL-LXR

 
 

    


0001 .. include:: ../disclaimer-ita.rst
0002 
0003 .. note:: Per leggere la documentazione originale in inglese:
0004           :ref:`Documentation/kernel-hacking/hacking.rst <kernel_hacking_hack>`
0005 
0006 :Original: :ref:`Documentation/kernel-hacking/hacking.rst <kernel_hacking_hack>`
0007 :Translator: Federico Vaga <federico.vaga@vaga.pv.it>
0008 
0009 .. _it_kernel_hacking_hack:
0010 
0011 =================================================
0012 L'inaffidabile guida all'hacking del kernel Linux
0013 =================================================
0014 
0015 :Author: Rusty Russell
0016 
0017 Introduzione
0018 ============
0019 
0020 Benvenuto, gentile lettore, alla notevole ed inaffidabile guida all'hacking
0021 del kernel Linux ad opera di Rusty. Questo documento descrive le procedure
0022 più usate ed i concetti necessari per scrivere codice per il kernel: lo scopo
0023 è di fornire ai programmatori C più esperti un manuale di base per sviluppo.
0024 Eviterò dettagli implementativi: per questo abbiamo il codice,
0025 ed ignorerò intere parti di alcune procedure.
0026 
0027 Prima di leggere questa guida, sappiate che non ho mai voluto scriverla,
0028 essendo esageratamente sotto qualificato, ma ho sempre voluto leggere
0029 qualcosa di simile, e quindi questa era l'unica via. Spero che possa
0030 crescere e diventare un compendio di buone pratiche, punti di partenza
0031 e generiche informazioni.
0032 
0033 Gli attori
0034 ==========
0035 
0036 In qualsiasi momento ognuna delle CPU di un sistema può essere:
0037 
0038 -  non associata ad alcun processo, servendo un'interruzione hardware;
0039 
0040 -  non associata ad alcun processo, servendo un softirq o tasklet;
0041 
0042 -  in esecuzione nello spazio kernel, associata ad un processo
0043    (contesto utente);
0044 
0045 -  in esecuzione di un processo nello spazio utente;
0046 
0047 Esiste un ordine fra questi casi. Gli ultimi due possono avvicendarsi (preempt)
0048 l'un l'altro, ma a parte questo esiste una gerarchia rigida: ognuno di questi
0049 può avvicendarsi solo ad uno di quelli sottostanti. Per esempio, mentre un
0050 softirq è in esecuzione su d'una CPU, nessun altro softirq può avvicendarsi
0051 nell'esecuzione, ma un'interruzione hardware può. Ciò nonostante, le altre CPU
0052 del sistema operano indipendentemente.
0053 
0054 Più avanti vedremo alcuni modi in cui dal contesto utente è possibile bloccare
0055 le interruzioni, così da impedirne davvero il diritto di prelazione.
0056 
0057 Contesto utente
0058 ---------------
0059 
0060 Ci si trova nel contesto utente quando si arriva da una chiamata di sistema
0061 od altre eccezioni: come nello spazio utente, altre procedure più importanti,
0062 o le interruzioni, possono far valere il proprio diritto di prelazione sul
0063 vostro processo. Potete sospendere l'esecuzione chiamando :c:func:`schedule()`.
0064 
0065 .. note::
0066 
0067     Si è sempre in contesto utente quando un modulo viene caricato o rimosso,
0068     e durante le operazioni nello strato dei dispositivi a blocchi
0069     (*block layer*).
0070 
0071 Nel contesto utente, il puntatore ``current`` (il quale indica il processo al
0072 momento in esecuzione) è valido, e :c:func:`in_interrupt()`
0073 (``include/linux/preempt.h``) è falsa.
0074 
0075 .. warning::
0076 
0077     Attenzione che se avete la prelazione o i softirq disabilitati (vedere
0078     di seguito), :c:func:`in_interrupt()` ritornerà un falso positivo.
0079 
0080 Interruzioni hardware (Hard IRQs)
0081 ---------------------------------
0082 
0083 Temporizzatori, schede di rete e tastiere sono esempi di vero hardware
0084 che possono produrre interruzioni in un qualsiasi momento. Il kernel esegue
0085 i gestori d'interruzione che prestano un servizio all'hardware. Il kernel
0086 garantisce che questi gestori non vengano mai interrotti: se una stessa
0087 interruzione arriva, questa verrà accodata (o scartata).
0088 Dato che durante la loro esecuzione le interruzioni vengono disabilitate,
0089 i gestori d'interruzioni devono essere veloci: spesso si limitano
0090 esclusivamente a notificare la presa in carico dell'interruzione,
0091 programmare una 'interruzione software' per l'esecuzione e quindi terminare.
0092 
0093 Potete dire d'essere in una interruzione hardware perché in_hardirq()
0094 ritorna vero.
0095 
0096 .. warning::
0097 
0098     Attenzione, questa ritornerà un falso positivo se le interruzioni
0099     sono disabilitate (vedere di seguito).
0100 
0101 Contesto d'interruzione software: softirq e tasklet
0102 ---------------------------------------------------
0103 
0104 Quando una chiamata di sistema sta per tornare allo spazio utente,
0105 oppure un gestore d'interruzioni termina, qualsiasi 'interruzione software'
0106 marcata come pendente (solitamente da un'interruzione hardware) viene
0107 eseguita (``kernel/softirq.c``).
0108 
0109 La maggior parte del lavoro utile alla gestione di un'interruzione avviene qui.
0110 All'inizio della transizione ai sistemi multiprocessore, c'erano solo i
0111 cosiddetti 'bottom half' (BH), i quali non traevano alcun vantaggio da questi
0112 sistemi. Non appena abbandonammo i computer raffazzonati con fiammiferi e
0113 cicche, abbandonammo anche questa limitazione e migrammo alle interruzioni
0114 software 'softirqs'.
0115 
0116 Il file ``include/linux/interrupt.h`` elenca i differenti tipi di 'softirq'.
0117 Un tipo di softirq molto importante è il timer (``include/linux/timer.h``):
0118 potete programmarlo per far si che esegua funzioni dopo un determinato
0119 periodo di tempo.
0120 
0121 Dato che i softirq possono essere eseguiti simultaneamente su più di un
0122 processore, spesso diventa estenuante l'averci a che fare. Per questa ragione,
0123 i tasklet (``include/linux/interrupt.h``) vengo usati più di frequente:
0124 possono essere registrati dinamicamente (il che significa che potete averne
0125 quanti ne volete), e garantiscono che un qualsiasi tasklet verrà eseguito
0126 solo su un processore alla volta, sebbene diversi tasklet possono essere
0127 eseguiti simultaneamente.
0128 
0129 .. warning::
0130 
0131     Il nome 'tasklet' è ingannevole: non hanno niente a che fare
0132     con i 'processi' ('tasks').
0133 
0134 Potete determinate se siete in un softirq (o tasklet) utilizzando la
0135 macro :c:func:`in_softirq()` (``include/linux/preempt.h``).
0136 
0137 .. warning::
0138 
0139     State attenti che questa macro ritornerà un falso positivo
0140     se :ref:`botton half lock <it_local_bh_disable>` è bloccato.
0141 
0142 Alcune regole basilari
0143 ======================
0144 
0145 Nessuna protezione della memoria
0146     Se corrompete la memoria, che sia in contesto utente o d'interruzione,
0147     la macchina si pianterà. Siete sicuri che quello che volete fare
0148     non possa essere fatto nello spazio utente?
0149 
0150 Nessun numero in virgola mobile o MMX
0151     Il contesto della FPU non è salvato; anche se siete in contesto utente
0152     lo stato dell'FPU probabilmente non corrisponde a quello del processo
0153     corrente: vi incasinerete con lo stato di qualche altro processo. Se
0154     volete davvero usare la virgola mobile, allora dovrete salvare e recuperare
0155     lo stato dell'FPU (ed evitare cambi di contesto). Generalmente è una
0156     cattiva idea; usate l'aritmetica a virgola fissa.
0157 
0158 Un limite rigido dello stack
0159     A seconda della configurazione del kernel lo stack è fra 3K e 6K per la
0160     maggior parte delle architetture a 32-bit; è di 14K per la maggior
0161     parte di quelle a 64-bit; e spesso è condiviso con le interruzioni,
0162     per cui non si può usare.
0163     Evitare profonde ricorsioni ad enormi array locali nello stack
0164     (allocateli dinamicamente).
0165 
0166 Il kernel Linux è portabile
0167     Quindi mantenetelo tale. Il vostro codice dovrebbe essere a 64-bit ed
0168     indipendente dall'ordine dei byte (endianess) di un processore. Inoltre,
0169     dovreste minimizzare il codice specifico per un processore; per esempio
0170     il codice assembly dovrebbe essere incapsulato in modo pulito e minimizzato
0171     per facilitarne la migrazione. Generalmente questo codice dovrebbe essere
0172     limitato alla parte di kernel specifica per un'architettura.
0173 
0174 ioctl: non scrivere nuove chiamate di sistema
0175 =============================================
0176 
0177 Una chiamata di sistema, generalmente, è scritta così::
0178 
0179     asmlinkage long sys_mycall(int arg)
0180     {
0181             return 0;
0182     }
0183 
0184 Primo, nella maggior parte dei casi non volete creare nuove chiamate di
0185 sistema.
0186 Create un dispositivo a caratteri ed implementate l'appropriata chiamata ioctl.
0187 Questo meccanismo è molto più flessibile delle chiamate di sistema: esso non
0188 dev'essere dichiarato in tutte le architetture nei file
0189 ``include/asm/unistd.h`` e ``arch/kernel/entry.S``; inoltre, è improbabile
0190 che questo venga accettato da Linus.
0191 
0192 Se tutto quello che il vostro codice fa è leggere o scrivere alcuni parametri,
0193 considerate l'implementazione di un'interfaccia :c:func:`sysfs()`.
0194 
0195 All'interno di una ioctl vi trovate nel contesto utente di un processo. Quando
0196 avviene un errore dovete ritornare un valore negativo di errno (consultate
0197 ``include/uapi/asm-generic/errno-base.h``,
0198 ``include/uapi/asm-generic/errno.h`` e ``include/linux/errno.h``), altrimenti
0199 ritornate 0.
0200 
0201 Dopo aver dormito dovreste verificare se ci sono stati dei segnali: il modo
0202 Unix/Linux di gestire un segnale è di uscire temporaneamente dalla chiamata
0203 di sistema con l'errore ``-ERESTARTSYS``. La chiamata di sistema ritornerà
0204 al contesto utente, eseguirà il gestore del segnale e poi la vostra chiamata
0205 di sistema riprenderà (a meno che l'utente non l'abbia disabilitata). Quindi,
0206 dovreste essere pronti per continuare l'esecuzione, per esempio nel mezzo
0207 della manipolazione di una struttura dati.
0208 
0209 ::
0210 
0211     if (signal_pending(current))
0212             return -ERESTARTSYS;
0213 
0214 Se dovete eseguire dei calcoli molto lunghi: pensate allo spazio utente.
0215 Se **davvero** volete farlo nel kernel ricordatevi di verificare periodicamente
0216 se dovete *lasciare* il processore (ricordatevi che, per ogni processore, c'è
0217 un sistema multi-processo senza diritto di prelazione).
0218 Esempio::
0219 
0220     cond_resched(); /* Will sleep */
0221 
0222 Una breve nota sulla progettazione delle interfacce: il motto dei sistemi
0223 UNIX è "fornite meccanismi e non politiche"
0224 
0225 La ricetta per uno stallo
0226 =========================
0227 
0228 Non è permesso invocare una procedura che potrebbe dormire, fanno eccezione
0229 i seguenti casi:
0230 
0231 -  Siete in un contesto utente.
0232 
0233 -  Non trattenete alcun spinlock.
0234 
0235 -  Avete abilitato le interruzioni (in realtà, Andy Kleen dice che
0236    lo schedulatore le abiliterà per voi, ma probabilmente questo non è quello
0237    che volete).
0238 
0239 Da tener presente che alcune funzioni potrebbero dormire implicitamente:
0240 le più comuni sono quelle per l'accesso allo spazio utente (\*_user) e
0241 quelle per l'allocazione della memoria senza l'opzione ``GFP_ATOMIC``
0242 
0243 Dovreste sempre compilare il kernel con l'opzione ``CONFIG_DEBUG_ATOMIC_SLEEP``
0244 attiva, questa vi avviserà se infrangete una di queste regole.
0245 Se **infrangete** le regole, allora potreste bloccare il vostro scatolotto.
0246 
0247 Veramente.
0248 
0249 Alcune delle procedure più comuni
0250 =================================
0251 
0252 :c:func:`printk()`
0253 ------------------
0254 
0255 Definita in ``include/linux/printk.h``
0256 
0257 :c:func:`printk()` fornisce messaggi alla console, dmesg, e al demone syslog.
0258 Essa è utile per il debugging o per la notifica di errori; può essere
0259 utilizzata anche all'interno del contesto d'interruzione, ma usatela con
0260 cautela: una macchina che ha la propria console inondata da messaggi diventa
0261 inutilizzabile. La funzione utilizza un formato stringa quasi compatibile con
0262 la printf ANSI C, e la concatenazione di una stringa C come primo argomento
0263 per indicare la "priorità"::
0264 
0265     printk(KERN_INFO "i = %u\n", i);
0266 
0267 Consultate ``include/linux/kern_levels.h`` per gli altri valori ``KERN_``;
0268 questi sono interpretati da syslog come livelli. Un caso speciale:
0269 per stampare un indirizzo IP usate::
0270 
0271     __be32 ipaddress;
0272     printk(KERN_INFO "my ip: %pI4\n", &ipaddress);
0273 
0274 
0275 :c:func:`printk()` utilizza un buffer interno di 1K e non s'accorge di
0276 eventuali sforamenti. Accertatevi che vi basti.
0277 
0278 .. note::
0279 
0280     Saprete di essere un vero hacker del kernel quando inizierete a digitare
0281     nei vostri programmi utenti le printf come se fossero printk :)
0282 
0283 .. note::
0284 
0285     Un'altra nota a parte: la versione originale di Unix 6 aveva un commento
0286     sopra alla funzione printf: "Printf non dovrebbe essere usata per il
0287     chiacchiericcio". Dovreste seguire questo consiglio.
0288 
0289 :c:func:`copy_to_user()` / :c:func:`copy_from_user()` / :c:func:`get_user()` / :c:func:`put_user()`
0290 ---------------------------------------------------------------------------------------------------
0291 
0292 Definite in ``include/linux/uaccess.h`` / ``asm/uaccess.h``
0293 
0294 **[DORMONO]**
0295 
0296 :c:func:`put_user()` e :c:func:`get_user()` sono usate per ricevere ed
0297 impostare singoli valori (come int, char, o long) da e verso lo spazio utente.
0298 Un puntatore nello spazio utente non dovrebbe mai essere dereferenziato: i dati
0299 dovrebbero essere copiati usando suddette procedure. Entrambe ritornano
0300 ``-EFAULT`` oppure 0.
0301 
0302 :c:func:`copy_to_user()` e :c:func:`copy_from_user()` sono più generiche:
0303 esse copiano una quantità arbitraria di dati da e verso lo spazio utente.
0304 
0305 .. warning::
0306 
0307     Al contrario di:c:func:`put_user()` e :c:func:`get_user()`, queste
0308     funzioni ritornano la quantità di dati copiati (0 è comunque un successo).
0309 
0310 [Sì, questa interfaccia mi imbarazza. La battaglia torna in auge anno
0311 dopo anno. --RR]
0312 
0313 Le funzioni potrebbero dormire implicitamente. Queste non dovrebbero mai essere
0314 invocate fuori dal contesto utente (non ha senso), con le interruzioni
0315 disabilitate, o con uno spinlock trattenuto.
0316 
0317 :c:func:`kmalloc()`/:c:func:`kfree()`
0318 -------------------------------------
0319 
0320 Definite in ``include/linux/slab.h``
0321 
0322 **[POTREBBERO DORMIRE: LEGGI SOTTO]**
0323 
0324 Queste procedure sono utilizzate per la richiesta dinamica di un puntatore ad
0325 un pezzo di memoria allineato, esattamente come malloc e free nello spazio
0326 utente, ma :c:func:`kmalloc()` ha un argomento aggiuntivo per indicare alcune
0327 opzioni. Le opzioni più importanti sono:
0328 
0329 ``GFP_KERNEL``
0330     Potrebbe dormire per librarare della memoria. L'opzione fornisce il modo
0331     più affidabile per allocare memoria, ma il suo uso è strettamente limitato
0332     allo spazio utente.
0333 
0334 ``GFP_ATOMIC``
0335     Non dorme. Meno affidabile di ``GFP_KERNEL``, ma può essere usata in un
0336     contesto d'interruzione. Dovreste avere **davvero** una buona strategia
0337     per la gestione degli errori in caso di mancanza di memoria.
0338 
0339 ``GFP_DMA``
0340     Alloca memoria per il DMA sul bus ISA nello spazio d'indirizzamento
0341     inferiore ai 16MB. Se non sapete cos'è allora non vi serve.
0342     Molto inaffidabile.
0343 
0344 Se vedete un messaggio d'avviso per una funzione dormiente che viene chiamata
0345 da un contesto errato, allora probabilmente avete usato una funzione
0346 d'allocazione dormiente da un contesto d'interruzione senza ``GFP_ATOMIC``.
0347 Dovreste correggerlo. Sbrigatevi, non cincischiate.
0348 
0349 Se allocate almeno ``PAGE_SIZE``(``asm/page.h`` o ``asm/page_types.h``) byte,
0350 considerate l'uso di :c:func:`__get_free_pages()` (``include/linux/gfp.h``).
0351 Accetta un argomento che definisce l'ordine (0 per per la dimensione di una
0352 pagine, 1 per una doppia pagina, 2 per quattro pagine, eccetra) e le stesse
0353 opzioni d'allocazione viste precedentemente.
0354 
0355 Se state allocando un numero di byte notevolemnte superiore ad una pagina
0356 potete usare :c:func:`vmalloc()`. Essa allocherà memoria virtuale all'interno
0357 dello spazio kernel. Questo è un blocco di memoria fisica non contiguo, ma
0358 la MMU vi darà l'impressione che lo sia (quindi, sarà contiguo solo dal punto
0359 di vista dei processori, non dal punto di vista dei driver dei dispositivi
0360 esterni).
0361 Se per qualche strana ragione avete davvero bisogno di una grossa quantità di
0362 memoria fisica contigua, avete un problema: Linux non ha un buon supporto per
0363 questo caso d'uso perché, dopo un po' di tempo, la frammentazione della memoria
0364 rende l'operazione difficile. Il modo migliore per allocare un simile blocco
0365 all'inizio dell'avvio del sistema è attraverso la procedura
0366 :c:func:`alloc_bootmem()`.
0367 
0368 Prima di inventare la vostra cache per gli oggetti più usati, considerate
0369 l'uso di una cache slab disponibile in ``include/linux/slab.h``.
0370 
0371 :c:macro:`current`
0372 -------------------
0373 
0374 Definita in ``include/asm/current.h``
0375 
0376 Questa variabile globale (in realtà una macro) contiene un puntatore alla
0377 struttura del processo corrente, quindi è valido solo dal contesto utente.
0378 Per esempio, quando un processo esegue una chiamata di sistema, questo
0379 punterà alla struttura dati del processo chiamate.
0380 Nel contesto d'interruzione in suo valore **non è NULL**.
0381 
0382 :c:func:`mdelay()`/:c:func:`udelay()`
0383 -------------------------------------
0384 
0385 Definite in ``include/asm/delay.h`` / ``include/linux/delay.h``
0386 
0387 Le funzioni :c:func:`udelay()` e :c:func:`ndelay()` possono essere utilizzate
0388 per brevi pause. Non usate grandi valori perché rischiate d'avere un
0389 overflow - in questo contesto la funzione :c:func:`mdelay()` è utile,
0390 oppure considerate :c:func:`msleep()`.
0391 
0392 :c:func:`cpu_to_be32()`/:c:func:`be32_to_cpu()`/:c:func:`cpu_to_le32()`/:c:func:`le32_to_cpu()`
0393 -----------------------------------------------------------------------------------------------
0394 
0395 Definite in ``include/asm/byteorder.h``
0396 
0397 La famiglia di funzioni :c:func:`cpu_to_be32()` (dove "32" può essere
0398 sostituito da 64 o 16, e "be" con "le") forniscono un modo generico
0399 per fare conversioni sull'ordine dei byte (endianess): esse ritornano
0400 il valore convertito. Tutte le varianti supportano anche il processo inverso:
0401 :c:func:`be32_to_cpu()`, eccetera.
0402 
0403 Queste funzioni hanno principalmente due varianti: la variante per
0404 puntatori, come :c:func:`cpu_to_be32p()`, che prende un puntatore
0405 ad un tipo, e ritorna il valore convertito. L'altra variante per
0406 la famiglia di conversioni "in-situ", come :c:func:`cpu_to_be32s()`,
0407 che convertono il valore puntato da un puntatore, e ritornano void.
0408 
0409 :c:func:`local_irq_save()`/:c:func:`local_irq_restore()`
0410 --------------------------------------------------------
0411 
0412 Definite in ``include/linux/irqflags.h``
0413 
0414 Queste funzioni abilitano e disabilitano le interruzioni hardware
0415 sul processore locale. Entrambe sono rientranti; esse salvano lo stato
0416 precedente nel proprio argomento ``unsigned long flags``. Se sapete
0417 che le interruzioni sono abilite, potete semplicemente utilizzare
0418 :c:func:`local_irq_disable()` e :c:func:`local_irq_enable()`.
0419 
0420 .. _it_local_bh_disable:
0421 
0422 :c:func:`local_bh_disable()`/:c:func:`local_bh_enable()`
0423 --------------------------------------------------------
0424 
0425 Definite in ``include/linux/bottom_half.h``
0426 
0427 
0428 Queste funzioni abilitano e disabilitano le interruzioni software
0429 sul processore locale. Entrambe sono rientranti; se le interruzioni
0430 software erano già state disabilitate in precedenza, rimarranno
0431 disabilitate anche dopo aver invocato questa coppia di funzioni.
0432 Lo scopo è di prevenire l'esecuzione di softirq e tasklet sul processore
0433 attuale.
0434 
0435 :c:func:`smp_processor_id()`
0436 ----------------------------
0437 
0438 Definita in ``include/linux/smp.h``
0439 
0440 :c:func:`get_cpu()` nega il diritto di prelazione (quindi non potete essere
0441 spostati su un altro processore all'improvviso) e ritorna il numero
0442 del processore attuale, fra 0 e ``NR_CPUS``. Da notare che non è detto
0443 che la numerazione dei processori sia continua. Quando avete terminato,
0444 ritornate allo stato precedente con :c:func:`put_cpu()`.
0445 
0446 Se sapete che non dovete essere interrotti da altri processi (per esempio,
0447 se siete in un contesto d'interruzione, o il diritto di prelazione
0448 è disabilitato) potete utilizzare smp_processor_id().
0449 
0450 
0451 ``__init``/``__exit``/``__initdata``
0452 ------------------------------------
0453 
0454 Definite in  ``include/linux/init.h``
0455 
0456 Dopo l'avvio, il kernel libera una sezione speciale; le funzioni marcate
0457 con ``__init`` e le strutture dati marcate con ``__initdata`` vengono
0458 eliminate dopo il completamento dell'avvio: in modo simile i moduli eliminano
0459 questa memoria dopo l'inizializzazione. ``__exit`` viene utilizzato per
0460 dichiarare che una funzione verrà utilizzata solo in fase di rimozione:
0461 la detta funzione verrà eliminata quando il file che la contiene non è
0462 compilato come modulo. Guardate l'header file per informazioni. Da notare che
0463 non ha senso avere una funzione marcata come ``__init`` e al tempo stesso
0464 esportata ai moduli utilizzando :c:func:`EXPORT_SYMBOL()` o
0465 :c:func:`EXPORT_SYMBOL_GPL()` - non funzionerà.
0466 
0467 
0468 :c:func:`__initcall()`/:c:func:`module_init()`
0469 ----------------------------------------------
0470 
0471 Definite in  ``include/linux/init.h`` / ``include/linux/module.h``
0472 
0473 Molte parti del kernel funzionano bene come moduli (componenti del kernel
0474 caricabili dinamicamente). L'utilizzo delle macro :c:func:`module_init()`
0475 e :c:func:`module_exit()` semplifica la scrittura di codice che può funzionare
0476 sia come modulo, sia come parte del kernel, senza l'ausilio di #ifdef.
0477 
0478 La macro :c:func:`module_init()` definisce quale funzione dev'essere
0479 chiamata quando il modulo viene inserito (se il file è stato compilato come
0480 tale), o in fase di avvio : se il file non è stato compilato come modulo la
0481 macro :c:func:`module_init()` diventa equivalente a :c:func:`__initcall()`,
0482 la quale, tramite qualche magia del linker, s'assicura che la funzione venga
0483 chiamata durante l'avvio.
0484 
0485 La funzione può ritornare un numero d'errore negativo per scatenare un
0486 fallimento del caricamento (sfortunatamente, questo non ha effetto se il
0487 modulo è compilato come parte integrante del kernel). Questa funzione è chiamata
0488 in contesto utente con le interruzioni abilitate, quindi potrebbe dormire.
0489 
0490 
0491 :c:func:`module_exit()`
0492 -----------------------
0493 
0494 
0495 Definita in  ``include/linux/module.h``
0496 
0497 Questa macro definisce la funzione che dev'essere chiamata al momento della
0498 rimozione (o mai, nel caso in cui il file sia parte integrante del kernel).
0499 Essa verrà chiamata solo quando il contatore d'uso del modulo raggiunge lo
0500 zero. Questa funzione può anche dormire, ma non può fallire: tutto dev'essere
0501 ripulito prima che la funzione ritorni.
0502 
0503 Da notare che questa macro è opzionale: se non presente, il modulo non sarà
0504 removibile (a meno che non usiate 'rmmod -f' ).
0505 
0506 
0507 :c:func:`try_module_get()`/:c:func:`module_put()`
0508 -------------------------------------------------
0509 
0510 Definite in ``include/linux/module.h``
0511 
0512 Queste funzioni maneggiano il contatore d'uso del modulo per proteggerlo dalla
0513 rimozione (in aggiunta, un modulo non può essere rimosso se un altro modulo
0514 utilizzo uno dei sui simboli esportati: vedere di seguito). Prima di eseguire
0515 codice del modulo, dovreste chiamare :c:func:`try_module_get()` su quel modulo:
0516 se fallisce significa che il modulo è stato rimosso e dovete agire come se
0517 non fosse presente. Altrimenti, potete accedere al modulo in sicurezza, e
0518 chiamare :c:func:`module_put()` quando avete finito.
0519 
0520 La maggior parte delle strutture registrabili hanno un campo owner
0521 (proprietario), come nella struttura
0522 :c:type:`struct file_operations <file_operations>`.
0523 Impostate questo campo al valore della macro ``THIS_MODULE``.
0524 
0525 
0526 Code d'attesa ``include/linux/wait.h``
0527 ======================================
0528 
0529 **[DORMONO]**
0530 
0531 Una coda d'attesa è usata per aspettare che qualcuno vi attivi quando una
0532 certa condizione s'avvera. Per evitare corse critiche, devono essere usate
0533 con cautela. Dichiarate una :c:type:`wait_queue_head_t`, e poi i processi
0534 che vogliono attendere il verificarsi di quella condizione dichiareranno
0535 una :c:type:`wait_queue_entry_t` facendo riferimento a loro stessi, poi
0536 metteranno questa in coda.
0537 
0538 Dichiarazione
0539 -------------
0540 
0541 Potere dichiarare una ``wait_queue_head_t`` utilizzando la macro
0542 :c:func:`DECLARE_WAIT_QUEUE_HEAD()` oppure utilizzando la procedura
0543 :c:func:`init_waitqueue_head()` nel vostro codice d'inizializzazione.
0544 
0545 Accodamento
0546 -----------
0547 
0548 Mettersi in una coda d'attesa è piuttosto complesso, perché dovete
0549 mettervi in coda prima di verificare la condizione. Esiste una macro
0550 a questo scopo: :c:func:`wait_event_interruptible()` (``include/linux/wait.h``).
0551 Il primo argomento è la testa della coda d'attesa, e il secondo è
0552 un'espressione che dev'essere valutata; la macro ritorna 0 quando questa
0553 espressione è vera, altrimenti ``-ERESTARTSYS`` se è stato ricevuto un segnale.
0554 La versione :c:func:`wait_event()` ignora i segnali.
0555 
0556 Svegliare una procedura in coda
0557 -------------------------------
0558 
0559 Chiamate :c:func:`wake_up()` (``include/linux/wait.h``); questa attiverà tutti
0560 i processi in coda. Ad eccezione se uno di questi è impostato come
0561 ``TASK_EXCLUSIVE``, in questo caso i rimanenti non verranno svegliati.
0562 Nello stesso header file esistono altre varianti di questa funzione.
0563 
0564 Operazioni atomiche
0565 ===================
0566 
0567 Certe operazioni sono garantite come atomiche su tutte le piattaforme.
0568 Il primo gruppo di operazioni utilizza :c:type:`atomic_t`
0569 (``include/asm/atomic.h``); questo contiene un intero con segno (minimo 32bit),
0570 e dovete utilizzare queste funzione per modificare o leggere variabili di tipo
0571 :c:type:`atomic_t`. :c:func:`atomic_read()` e :c:func:`atomic_set()` leggono ed
0572 impostano il contatore, :c:func:`atomic_add()`, :c:func:`atomic_sub()`,
0573 :c:func:`atomic_inc()`, :c:func:`atomic_dec()`, e
0574 :c:func:`atomic_dec_and_test()` (ritorna vero se raggiunge zero dopo essere
0575 stata decrementata).
0576 
0577 Sì. Ritorna vero (ovvero != 0) se la variabile atomica è zero.
0578 
0579 Da notare che queste funzioni sono più lente rispetto alla normale aritmetica,
0580 e quindi non dovrebbero essere usate a sproposito.
0581 
0582 Il secondo gruppo di operazioni atomiche sono definite in
0583 ``include/linux/bitops.h`` ed agiscono sui bit d'una variabile di tipo
0584 ``unsigned long``. Queste operazioni prendono come argomento un puntatore
0585 alla variabile, e un numero di bit dove 0 è quello meno significativo.
0586 :c:func:`set_bit()`, :c:func:`clear_bit()` e :c:func:`change_bit()`
0587 impostano, cancellano, ed invertono il bit indicato.
0588 :c:func:`test_and_set_bit()`, :c:func:`test_and_clear_bit()` e
0589 :c:func:`test_and_change_bit()` fanno la stessa cosa, ad eccezione che
0590 ritornano vero se il bit era impostato; queste sono particolarmente
0591 utili quando si vuole impostare atomicamente dei flag.
0592 
0593 Con queste operazioni è possibile utilizzare indici di bit che eccedono
0594 il valore ``BITS_PER_LONG``. Il comportamento è strano sulle piattaforme
0595 big-endian quindi è meglio evitarlo.
0596 
0597 Simboli
0598 =======
0599 
0600 All'interno del kernel, si seguono le normali regole del linker (ovvero,
0601 a meno che un simbolo non venga dichiarato con visibilita limitata ad un
0602 file con la parola chiave ``static``, esso può essere utilizzato in qualsiasi
0603 parte del kernel). Nonostante ciò, per i moduli, esiste una tabella dei
0604 simboli esportati che limita i punti di accesso al kernel. Anche i moduli
0605 possono esportare simboli.
0606 
0607 :c:func:`EXPORT_SYMBOL()`
0608 -------------------------
0609 
0610 Definita in ``include/linux/export.h``
0611 
0612 Questo è il classico metodo per esportare un simbolo: i moduli caricati
0613 dinamicamente potranno utilizzare normalmente il simbolo.
0614 
0615 :c:func:`EXPORT_SYMBOL_GPL()`
0616 -----------------------------
0617 
0618 Definita in ``include/linux/export.h``
0619 
0620 Essa è simile a :c:func:`EXPORT_SYMBOL()` ad eccezione del fatto che i
0621 simboli esportati con :c:func:`EXPORT_SYMBOL_GPL()` possono essere
0622 utilizzati solo dai moduli che hanno dichiarato una licenza compatibile
0623 con la GPL attraverso :c:func:`MODULE_LICENSE()`. Questo implica che la
0624 funzione esportata è considerata interna, e non una vera e propria interfaccia.
0625 Alcuni manutentori e sviluppatori potrebbero comunque richiedere
0626 :c:func:`EXPORT_SYMBOL_GPL()` quando si aggiungono nuove funzionalità o
0627 interfacce.
0628 
0629 :c:func:`EXPORT_SYMBOL_NS()`
0630 ----------------------------
0631 
0632 Definita in ``include/linux/export.h``
0633 
0634 Questa è una variate di `EXPORT_SYMBOL()` che permette di specificare uno
0635 spazio dei nomi. Lo spazio dei nomi è documentato in
0636 Documentation/translations/it_IT/core-api/symbol-namespaces.rst.
0637 
0638 :c:func:`EXPORT_SYMBOL_NS_GPL()`
0639 --------------------------------
0640 
0641 Definita in ``include/linux/export.h``
0642 
0643 Questa è una variate di `EXPORT_SYMBOL_GPL()` che permette di specificare uno
0644 spazio dei nomi. Lo spazio dei nomi è documentato in
0645 Documentation/translations/it_IT/core-api/symbol-namespaces.rst.
0646 
0647 Procedure e convenzioni
0648 =======================
0649 
0650 Liste doppiamente concatenate ``include/linux/list.h``
0651 ------------------------------------------------------
0652 
0653 Un tempo negli header del kernel c'erano tre gruppi di funzioni per
0654 le liste concatenate, ma questa è stata la vincente. Se non avete particolari
0655 necessità per una semplice lista concatenata, allora questa è una buona scelta.
0656 
0657 In particolare, :c:func:`list_for_each_entry()` è utile.
0658 
0659 Convenzione dei valori di ritorno
0660 ---------------------------------
0661 
0662 Per codice chiamato in contesto utente, è molto comune sfidare le convenzioni
0663 C e ritornare 0 in caso di successo, ed un codice di errore negativo
0664 (eg. ``-EFAULT``) nei casi fallimentari. Questo potrebbe essere controintuitivo
0665 a prima vista, ma è abbastanza diffuso nel kernel.
0666 
0667 Utilizzate :c:func:`ERR_PTR()` (``include/linux/err.h``) per codificare
0668 un numero d'errore negativo in un puntatore, e :c:func:`IS_ERR()` e
0669 :c:func:`PTR_ERR()` per recuperarlo di nuovo: così si evita d'avere un
0670 puntatore dedicato per il numero d'errore. Da brividi, ma in senso positivo.
0671 
0672 Rompere la compilazione
0673 -----------------------
0674 
0675 Linus e gli altri sviluppatori a volte cambiano i nomi delle funzioni e
0676 delle strutture nei kernel in sviluppo; questo non è solo per tenere
0677 tutti sulle spine: questo riflette cambiamenti fondamentati (eg. la funzione
0678 non può più essere chiamata con le funzioni attive, o fa controlli aggiuntivi,
0679 o non fa più controlli che venivano fatti in precedenza). Solitamente a questo
0680 s'accompagna un'adeguata e completa nota sulla lista di discussone
0681 più adatta; cercate negli archivi. Solitamente eseguire una semplice
0682 sostituzione su tutto un file rendere le cose **peggiori**.
0683 
0684 Inizializzazione dei campi d'una struttura
0685 ------------------------------------------
0686 
0687 Il metodo preferito per l'inizializzazione delle strutture è quello
0688 di utilizzare gli inizializzatori designati, come definiti nello
0689 standard ISO C99, eg::
0690 
0691     static struct block_device_operations opt_fops = {
0692             .open               = opt_open,
0693             .release            = opt_release,
0694             .ioctl              = opt_ioctl,
0695             .check_media_change = opt_media_change,
0696     };
0697 
0698 Questo rende più facile la ricerca con grep, e rende più chiaro quale campo
0699 viene impostato. Dovreste fare così perché si mostra meglio.
0700 
0701 Estensioni GNU
0702 --------------
0703 
0704 Le estensioni GNU sono esplicitamente permesse nel kernel Linux. Da notare
0705 che alcune delle più complesse non sono ben supportate, per via dello scarso
0706 sviluppo, ma le seguenti sono da considerarsi la norma (per maggiori dettagli,
0707 leggete la sezione "C Extensions" nella pagina info di GCC - Sì, davvero
0708 la pagina info, la pagina man è solo un breve riassunto delle cose nella
0709 pagina info).
0710 
0711 -  Funzioni inline
0712 
0713 -  Istruzioni in espressioni (ie. il costrutto ({ and }) ).
0714 
0715 -  Dichiarate attributi di una funzione / variabile / tipo
0716    (__attribute__)
0717 
0718 -  typeof
0719 
0720 -  Array con lunghezza zero
0721 
0722 -  Macro varargs
0723 
0724 -  Aritmentica sui puntatori void
0725 
0726 -  Inizializzatori non costanti
0727 
0728 -  Istruzioni assembler (non al di fuori di 'arch/' e 'include/asm/')
0729 
0730 -  Nomi delle funzioni come stringhe (__func__).
0731 
0732 -  __builtin_constant_p()
0733 
0734 Siate sospettosi quando utilizzate long long nel kernel, il codice generato
0735 da gcc è orribile ed anche peggio: le divisioni e le moltiplicazioni non
0736 funzionano sulle piattaforme i386 perché le rispettive funzioni di runtime
0737 di GCC non sono incluse nell'ambiente del kernel.
0738 
0739 C++
0740 ---
0741 
0742 Solitamente utilizzare il C++ nel kernel è una cattiva idea perché
0743 il kernel non fornisce il necessario ambiente di runtime e gli header file
0744 non sono stati verificati. Rimane comunque possibile, ma non consigliato.
0745 Se davvero volete usarlo, almeno evitate le eccezioni.
0746 
0747 NUMif
0748 -----
0749 
0750 Viene generalmente considerato più pulito l'uso delle macro negli header file
0751 (o all'inizio dei file .c) per astrarre funzioni piuttosto che utlizzare
0752 l'istruzione di pre-processore \`#if' all'interno del codice sorgente.
0753 
0754 Mettere le vostre cose nel kernel
0755 =================================
0756 
0757 Al fine d'avere le vostre cose in ordine per l'inclusione ufficiale, o
0758 anche per avere patch pulite, c'è del lavoro amministrativo da fare:
0759 
0760 -  Trovare chi è responsabile del codice che state modificando. Guardare in cima
0761    ai file sorgenti, all'interno del file ``MAINTAINERS``, ed alla fine
0762    di tutti nel file ``CREDITS``. Dovreste coordinarvi con queste persone
0763    per evitare di duplicare gli sforzi, o provare qualcosa che è già stato
0764    rigettato.
0765 
0766    Assicuratevi di mettere il vostro nome ed indirizzo email in cima a
0767    tutti i file che create o che maneggiate significativamente. Questo è
0768    il primo posto dove le persone guarderanno quando troveranno un baco,
0769    o quando **loro** vorranno fare una modifica.
0770 
0771 -  Solitamente vorrete un'opzione di configurazione per la vostra modifica
0772    al kernel. Modificate ``Kconfig`` nella cartella giusta. Il linguaggio
0773    Config è facile con copia ed incolla, e c'è una completa documentazione
0774    nel file ``Documentation/kbuild/kconfig-language.rst``.
0775 
0776    Nella descrizione della vostra opzione, assicuratevi di parlare sia agli
0777    utenti esperti sia agli utente che non sanno nulla del vostro lavoro.
0778    Menzionate qui le incompatibilità ed i problemi. Chiaramente la
0779    descrizione deve terminare con “if in doubt, say N” (se siete in dubbio,
0780    dite N) (oppure, occasionalmente, \`Y'); questo è per le persone che non
0781    hanno idea di che cosa voi stiate parlando.
0782 
0783 -  Modificate il file ``Makefile``: le variabili CONFIG sono esportate qui,
0784    quindi potete solitamente aggiungere una riga come la seguete
0785    "obj-$(CONFIG_xxx) += xxx.o". La sintassi è documentata nel file
0786    ``Documentation/kbuild/makefiles.rst``.
0787 
0788 -  Aggiungete voi stessi in ``CREDITS`` se credete di aver fatto qualcosa di
0789    notevole, solitamente qualcosa che supera il singolo file (comunque il vostro
0790    nome dovrebbe essere all'inizio dei file sorgenti). ``MAINTAINERS`` significa
0791    che volete essere consultati quando vengono fatte delle modifiche ad un
0792    sottosistema, e quando ci sono dei bachi; questo implica molto di più di un
0793    semplice impegno su una parte del codice.
0794 
0795 -  Infine, non dimenticatevi di leggere
0796    ``Documentation/process/submitting-patches.rst``.
0797 
0798 Trucchetti del kernel
0799 =====================
0800 
0801 Dopo una rapida occhiata al codice, questi sono i preferiti. Sentitevi liberi
0802 di aggiungerne altri.
0803 
0804 ``arch/x86/include/asm/delay.h``::
0805 
0806     #define ndelay(n) (__builtin_constant_p(n) ? \
0807             ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
0808             __ndelay(n))
0809 
0810 
0811 ``include/linux/fs.h``::
0812 
0813     /*
0814      * Kernel pointers have redundant information, so we can use a
0815      * scheme where we can return either an error code or a dentry
0816      * pointer with the same return value.
0817      *
0818      * This should be a per-architecture thing, to allow different
0819      * error and pointer decisions.
0820      */
0821      #define ERR_PTR(err)    ((void *)((long)(err)))
0822      #define PTR_ERR(ptr)    ((long)(ptr))
0823      #define IS_ERR(ptr)     ((unsigned long)(ptr) > (unsigned long)(-1000))
0824 
0825 ``arch/x86/include/asm/uaccess_32.h:``::
0826 
0827     #define copy_to_user(to,from,n)                         \
0828             (__builtin_constant_p(n) ?                      \
0829              __constant_copy_to_user((to),(from),(n)) :     \
0830              __generic_copy_to_user((to),(from),(n)))
0831 
0832 
0833 ``arch/sparc/kernel/head.S:``::
0834 
0835     /*
0836      * Sun people can't spell worth damn. "compatability" indeed.
0837      * At least we *know* we can't spell, and use a spell-checker.
0838      */
0839 
0840     /* Uh, actually Linus it is I who cannot spell. Too much murky
0841      * Sparc assembly will do this to ya.
0842      */
0843     C_LABEL(cputypvar):
0844             .asciz "compatibility"
0845 
0846     /* Tested on SS-5, SS-10. Probably someone at Sun applied a spell-checker. */
0847             .align 4
0848     C_LABEL(cputypvar_sun4m):
0849             .asciz "compatible"
0850 
0851 
0852 ``arch/sparc/lib/checksum.S:``::
0853 
0854             /* Sun, you just can't beat me, you just can't.  Stop trying,
0855              * give up.  I'm serious, I am going to kick the living shit
0856              * out of you, game over, lights out.
0857              */
0858 
0859 
0860 Ringraziamenti
0861 ==============
0862 
0863 Ringrazio Andi Kleen per le sue idee, le risposte alle mie domande,
0864 le correzioni dei miei errori, l'aggiunta di contenuti, eccetera.
0865 Philipp Rumpf per l'ortografia e per aver reso più chiaro il testo, e
0866 per alcuni eccellenti punti tutt'altro che ovvi. Werner Almesberger
0867 per avermi fornito un ottimo riassunto di :c:func:`disable_irq()`,
0868 e Jes Sorensen e Andrea Arcangeli per le precisazioni. Michael Elizabeth
0869 Chastain per aver verificato ed aggiunto la sezione configurazione.
0870 Telsa Gwynne per avermi insegnato DocBook.