printk ()
La funzione di stampa del kernel printk()
, si comporta quasi in modo identico alla printf()
funzione della libreria C. In effetti, in questo libro non abbiamo fatto uso di differenze reali. Per la maggior parte delle intenzioni, va bene; printk()
è semplicemente il nome della funzione di stampa formattata del kernel. Ha alcune differenze, tuttavia.
La robustezza di printk ()
Una proprietà di dare printk()
rapidamente per scontato è la sua robustezza. La printk()
funzione è richiamabile da qualsiasi parte del kernel in qualsiasi momento. Può essere chiamato dal contesto di processo o di interruzione. Può essere chiamato mentre si tiene un lucchetto. Può essere chiamato contemporaneamente su più processori, ma non richiede al chiamante di tenere un blocco.
È una funzione resiliente. Questo è importante perché l'utilità di si printk()
basa sul fatto che è sempre lì e funziona sempre.
The Nonrobustness of printk ()
Esiste una falla nell'armatura della printk()
robustezza. È inutilizzabile prima di un certo punto del processo di avvio del kernel, prima dell'inizializzazione della console. In effetti, se la console non è inizializzata, dove dovrebbe andare l'output?
Questo non è normalmente un problema, a meno che non si stiano eseguendo debug molto presto nel processo di avvio (ad esempio, in setup_arch()
, che esegue l'inizializzazione specifica dell'architettura). Tale debug è una sfida per cominciare, e l'assenza di qualsiasi tipo di metodo di stampa aggrava solo il problema.
C'è qualche speranza, ma non molto. Gli hacker di architettura hardcore usano l'hardware che funziona (diciamo, una porta seriale) per comunicare con il mondo esterno. Fidati di me, questo non è divertente per la maggior parte delle persone. Alcune architetture supportate implementano una soluzione sana, mentre altre (i386 incluso) hanno patch disponibili che salvano il giorno.
La soluzione è una printk()
variante che può emettere alla console molto presto nel processo di avvio: early_printk()
. Il comportamento è lo stesso printk()
, vengono modificati solo il nome e la sua capacità di lavorare in precedenza. Questa non è una soluzione portatile, tuttavia, poiché non tutte le architetture supportate hanno implementato tale metodo. Potrebbe diventare il tuo migliore amico, se lo fa.
A meno che non sia necessario scrivere sulla console molto presto nel processo di avvio, si può fare affidamento printk()
per lavorare sempre.