Ricerca tra la vecchia roba

Printk

Posted: Novembre 21st, 2007 | Author: | Filed under: Programmazione | Commenti disabilitati su Printk

Prima di cercare greppando su tutti i sorgenti, magari prova prima a cercare un file con il nome della funzione che stai cercando, magari printk.c ๐Ÿ˜‰

$ cat kernel/printk.c
[…]
/**
 * printk – print a kernel message
 * @fmt: format string
 *
 * This is printk.  It can be called from any context.  We want it to work.
 *
 * We try to grab the console_sem.  If we succeed, it’s easy – we log the output and
 * call the console drivers.
[…]

Inoltre è più utile visionare i sorgenti magari attraverso la mappa interattiva del kernel. Nel caso comunque che si vogliano utilizzare strumenti più geek, possiamo usare il mitico vim e l’utility ctags: entrate alla base del tree dei sorgenti, lanciate un bel make tags e poi aprite vim indicando una tag con l’opzione -t; nel mio fottuto caso necessito printk quindi

vim -t printk

sfortunatamente ce ne sono multiple di definizioni, quindi posso usare il comando :ts printk che restituisce l’elenco delle tag trovate

  # pri tipo tag               file
  1 F C d    printk            ./drivers/md/raid6.h
               118
  2 F   f    printk            ./kernel/printk.c
               asmlinkage int printk(const char *fmt, …)
  3 F   p    printk            include/linux/kernel.h
               asmlinkage int printk(const char * fmt, …)
  4 F   f    printk            include/linux/kernel.h
               static inline int printk(const char *s, …) { return 0; }
  5 F   p    printk            include/linux/kernel.h
               static inline int printk(const char *s, …)

quindi si seleziona quella voluta. Se invece volete vedere la definizione di una grandezza a partire da un sorgente dove viene utilizzata allora basta posizionare il cursore sopra e poi premere Ctrl-]; poi se si salta da una definizione all’altra, basta premere Ctrl-t, Ctrl-o per andare rispettivamente avanti e indietro.

Aggiornamento

 Il mio scopo era capire come in Linux era la printk, cioé volevo vedere se faceva chiamate ai registri della VGA (mistero della fede hardware) oppure cos’altro… sono arrivato alla seguente conclusione

  1. printk è una funzione che come printf (;-)) prende un numero variabile di argomenti e chiama vprintk
    asmlinkage int printk(const char *fmt, …)
    {
            va_list args;
            int r;

            va_start(args, fmt);
            r = vprintk(fmt, args);
            va_end(args);

            return r;
    }

  2. vprintk chiama prima vscnprintf che riempie il buffer della printk

    /* Emit the output into the temporary buffer */
    printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);

    e poi passa questo buffer ad un algoritmo che ne aggiunge il loglevel ed eventulamente il timing (che personalmente trovo fastidioso).
    Poi viene chiamata release_console_sem che libera il blocco sulla console ed in teoria stampa chiamando call_console_drivers che chiama _call_console_drivers che chiama __call_console_drivers la quale ha la curiosa funzione

    /*
     * Call the console drivers on a range of log_buf
     */
    static void __call_console_drivers(unsigned long start, unsigned long end)
    {
            struct console *con;

            for (con = console_drivers; con; con = con->next) {
                    if ((con->flags & CON_ENABLED) && con->write &&
                                    (cpu_online(smp_processor_id()) ||
                                    (con->flags & CON_ANYTIME)))
                            con->write(con, &LOG_BUF(start), end – start);
            }
    }

evidenziata che dovrebbe svolgere il ruolo cercato da me… adesso mi tocca trovate il driver…


TO BE CONTINUED


Comments are closed.