2011-12-19 16 views
28

Durante la compilazione di un modulo del kernel, ho ricevuto un avviso con una nota per aggiungere un'opzione di compilazione, CONFIG_DEBUG_SECTION_MISMATCH = y. Mi danno informazioni più dettagliate sulla questione:Che cos'è la mancata corrispondenza della sezione del kernel?

WARNING: \**\*path to module\***(.text+0x8d2): Section mismatch in reference from the function Pch_Spi_Enable_Bios_Wr() to the variable .devinit.data:ich9_pci_tbl.22939 
The function Pch_Spi_Enable_Bios_Wr() references 
the variable __devinitdata ich9_pci_tbl.22939. 
This is often because Pch_Spi_Enable_Bios_Wr lacks a __devinitdata 
annotation or the annotation of ich9_pci_tbl.22939 is wrong. 

non riuscivo a trovare che cosa esattamente kernel sezione mancata corrispondenza è, per non parlare di come fare per risolverlo.

risposta

35

Significa che una funzione che si trova in una sezione con una determinata durata fa riferimento a qualcosa che si trova in una sezione con una durata diversa.

Quando il binario del kernel è collegato, parti diverse del codice e dei dati vengono suddivisi in diverse sezioni. Alcune di queste sezioni vengono sempre caricate, ma altre vengono rimosse una volta che non sono più necessarie (le cose che sono necessarie solo durante l'avvio, ad esempio, possono essere liberate una volta eseguito l'avvio - questo risparmia memoria).

Se una funzione che è in una sezione di lunga durata si riferisce a dati in una delle sezioni discardable, c'è un problema - si potrebbe tentare di accedere ai dati quando è già stato rilasciato, portando a tutti i tipi di runtime problemi.

Questo non è un avvertimento che ti aggiusterai, a meno che tu non abbia scritto quel codice o lo abbia familiarizzato. Viene corretto annotando correttamente la funzione (oi dati a cui fa riferimento) in modo che vada nella sezione giusta. La correzione giusta può essere determinata solo con una conoscenza dettagliata di quella parte del kernel.


Per un elenco di queste sezioni e annotazioni, si riferiscono alla intestazione include/linux/init.h nel proprio albero dei sorgenti del kernel:

/* These macros are used to mark some functions or 
* initialized data (doesn't apply to uninitialized data) 
* as `initialization' functions. The kernel can take this 
* as hint that the function is used only during the initialization 
* phase and free up used memory resources after 
* 
* Usage: 
* For functions: 
* 
* You should add __init immediately before the function name, like: 
* 
* static void __init initme(int x, int y) 
* { 
* extern int z; z = x * y; 
* } 
* 
* If the function has a prototype somewhere, you can also add 
* __init between closing brace of the prototype and semicolon: 
* 
* extern int initialize_foobar_device(int, int, int) __init; 
* 
* For initialized data: 
* You should insert __initdata between the variable name and equal 
* sign followed by value, e.g.: 
* 
* static int init_variable __initdata = 0; 
* static const char linux_logo[] __initconst = { 0x32, 0x36, ... }; 
* 
* Don't forget to initialize data not at file scope, i.e. within a function, 
* as gcc otherwise puts the data into the bss section and not into the init 
* section. 
* 
* Also note, that this data cannot be "const". 
*/ 

/* These are for everybody (although not all archs will actually 
    discard it in modules) */ 
#define __init  __section(.init.text) __cold notrace 
#define __initdata __section(.init.data) 
#define __initconst __section(.init.rodata) 
#define __exitdata __section(.exit.data) 
#define __exit_call __used __section(.exitcall.exit) 

Altri seguono, con più commenti e spiegazioni.

Vedere anche il testo di aiuto per il simbolo CONFIG_DEBUG_SECTION_MISMATCH Kconfig:

La sezione di analisi controlli mancata corrispondenza se ci sono illegali
riferimenti da una sezione ad un'altra sezione.
Linux durante il collegamento o durante il runtime rilascia alcune sezioni
e qualsiasi utilizzo di codice/dati precedentemente in queste sezioni corrisponderà a
molto probabilmente in un ops.
Nelle funzioni di codici e variabili è annotato con
__init, __devinit ecc (vedi elenco completo in include/linux/init.h)
che determina il codice/dati che vengono immessi nelle sezioni specifiche.
L'analisi sezione di mancata corrispondenza avviene sempre dopo una completa
di compilazione del kernel, ma l'attivazione di questa opzione in aggiunta
effettuare le seguenti operazioni:

  • aggiungere l'opzione -fno-inline-funzioni-chiamate-una volta per gcc
    Quando si esegue la funzione di annotazione __init in una funzione non init init, si perderebbero le informazioni sulla sezione e quindi
    l'analisi non catturerebbe il riferimento illegale.
    Questa opzione dice a gcc di incorporare meno, ma anche
    risultato in un kernel più grande.
  • eseguire l'analisi sezione di mancata corrispondenza per ogni modulo/built-in.o
    Quando si esegue l'analisi sezione di disadattamento sul vmlinux.o abbiamo
    perdiamo informazioni valueble su dove la mancata corrispondenza era
    introdotto.
    Esecuzione dell'analisi per ciascun modulo/file built-in.o
    indica dove si trova la mancata corrispondenza molto più vicino all'origine
    . Lo svantaggio è che riporteremo lo stesso errore
    almeno due volte.
  • Abilita la segnalazione dettagliata da modpost per aiutare a risolvere
    le disallineamenti di sezione segnalate.
Problemi correlati