aus hier
48 struct snd_card *snd_cards[SNDRV_CARDS];
49 EXPORT_SYMBOL(snd_cards);
Ich verstehe nicht, was es bedeutet und warum es verwendet wird. Ich habe versucht, danach zu suchen, aber die Bedeutung davon nicht verstanden.
Jeegar Patel
aus hier
48 struct snd_card *snd_cards[SNDRV_CARDS];
49 EXPORT_SYMBOL(snd_cards);
Ich verstehe nicht, was es bedeutet und warum es verwendet wird. Ich habe versucht, danach zu suchen, aber die Bedeutung davon nicht verstanden.
Cnicutar
Es macht ein Symbol für dynamisch geladene Module zugänglich (vorausgesetzt, dass diese Module eine extern
Erklärung).
Vor nicht allzu langer Zeit fragte jemand, wie man es benutzt.
@cirosantilli Es ist definiert in include/linux/export.h
. Suchen ksymtab
und kstrtab
.
– Cnicutar
30. August 2013 um 12:51 Uhr
Weiß jemand, unter welcher Version des Kernels /include/linux/export.h hinzugefügt wurde? (Oder eine einfache Möglichkeit, dies zu überprüfen, ohne jeden einzelnen Kernel-Quellbaum zu durchlaufen) Ich sehe es nicht in 2.6.39.4.
– Sager89
12. März 2014 um 22:37 Uhr
Wenn wir Kernel-Symbole wie Jiffies verwenden, warum ist es dann nicht erforderlich, extern zu tun?
– geschickt
27. April 2014 um 9:20 Uhr
Victor Choi
Hier ist eine gute Erklärung.
https://www.quora.com/What-is-the-difference-between-extern-and-EXPORT_SYMBOL-in-Linux-kernel-codes
Extern ist ein Schlüsselwort der C-Speicherklasse. Im Kernel, wie in jedem anderen C-Code, teilt es dem Compiler mit, dass die Definition der Variable oder Funktion, die es qualifiziert, in einer anderen „Datei“ implementiert ist, oder besser gesagt, Übersetzungseinheit (Programmierung) – Wikipedia. Die Übersetzungseinheit, die sie definiert, sollte den statischen Qualifizierer nicht verwenden. Daher hat die Symboltabelle einen ihr entsprechenden Eintrag. Zur Verbindungszeit wird das Symbol wie gewohnt aufgelöst. Es gibt nichts Kernel-spezifisches über „extern“.
EXPORT_SYMBOL() ist ein Makro, das die Header des Linux-Kernels definieren. Es hat nicht viel mit extern zu tun. Es teilt dem kbuild-Mechanismus mit, dass das Symbol, auf das verwiesen wird, Teil der globalen Liste der Kernel-Symbole sein soll. Das wiederum erlaubt Kernelmodulen, auf sie zuzugreifen. Code, der in den Kernel selbst eingebaut ist (im Gegensatz zu einem Modul), kann natürlich gemäß regulärem C über eine externe Deklaration auf jedes nichtstatische Symbol zugreifen. Der EXPORT_SYMBOL()-Mechanismus ermöglicht es uns, ein Symbol zur Verwendung zu exportieren auch durch ladbare Module. Eine interessante Sache ist, dass ein so von einem Modul exportiertes Symbol für ein anderes Modul zugänglich wird, das möglicherweise davon abhängt!
Zusammenfassend ist extern nicht Kernel-spezifisch. Es wird verwendet, um eine Deklaration zu einem nicht statischen Symbol aus einer anderen Übersetzungseinheit zu qualifizieren. EXPORT_SYMBOL() ist spezifisch für den Linux-Kernel. Es wird in der Übersetzungseinheit der Definition verwendet, um das Symbol für ladbare Module verfügbar zu machen.
EXPORT_SYMBOL ist also nur ein Mechanismus wie extern, aber es dient als Referenz zwischen ladbaren Modulen, nicht als Datei.
Um voranzukommen, können wir vermuten, dass es von extern erreicht wird, da extern Form C ist, das die Grundlage darstellt.
Hier ist ein Hinweis.
https://elixir.bootlin.com/linux/v4.6.7/source/include/linux/export.h#L56
#define EXPORT_SYMBOL(sym) \
__EXPORT_SYMBOL(sym, "")
/* For every exported symbol, place a struct in the __ksymtab section */
#define __EXPORT_SYMBOL(sym, sec) \
extern typeof(sym) sym; \
__CRC_SYMBOL(sym, sec) \
static const char __kstrtab_##sym[] __attribute__((section("__ksymtab_strings"), aligned(1))) = VMLINUX_SYMBOL_STR(sym); \
extern const struct kernel_symbol __ksymtab_##sym; \
__visible const struct kernel_symbol __ksymtab_##sym __used __attribute__((section("___ksymtab" sec "+" #sym), unused)) = { (unsigned long)&sym, __kstrtab_##sym }
Deklarieren Sie zuerst ein externes Sym.
Dann eine Zeichenfolge __kstrtab_##sym = = VMLINUX_SYMBOL_STR(sym).
Letztes externes Struct kernel_symbol __ksymtab_##sym = { (unsigned long)&sym, __kstrtab_##sym }. &sym Notieren Sie die tatsächliche Adresse des Symbols, z. B. eine Funktion oder Variable, _kstrtab##sym Notieren Sie die Namenszeichenfolge.
Keine Antwort an sich, sondern eine Demonstration, wie in meinem Kommentar versprochen, dass Symbole exportiert wurden sind nicht muss nicht statisch sein. Die folgenden 2 Module demonstrieren dies:
/* mod1.c */
#include <linux/module.h>
static int mod1_exp_func(int i)
{
pr_info("%s:%d the value passed in is %d\n",
__func__, __LINE__, i);
return i;
}
EXPORT_SYMBOL(mod1_exp_func); /* export static symbol */
static int __init mod1_init(void)
{
pr_info("Initializing simple mod\n");
return 0;
}
static void __exit mod1_exit(void)
{
pr_info("This module is exiting\n");
}
module_init(mod1_init);
module_exit(mod1_exit);
MODULE_LICENSE("GPL v2");
Und das zweite Modul
/* mod2.c */
#include <linux/module.h>
extern int mod1_exp_func(int);
static int __init mod2_init(void)
{
pr_info("Initializing mod2\n");
pr_info("Calling exported function in mod1\n");
mod1_exp_func(3);
return 0;
}
static void __exit mod2_exit(void)
{
pr_info("mod2 exiting\n");
}
module_init(mod2_init);
module_exit(mod2_exit);
MODULE_LICENSE("GPL v2");
Diese wurden auf CentOS 6 und CentOS 7 getestet: Kernel 2.6.32 bzw. 3.10. Das Laden von mod1.ko und dann mod2.ko führt dazu, dass der an mod1_exp_func() übergebene Wert in die Kernel-Protokollpuffer gedruckt wird.
Funktioniert es, wenn die Funktionen nicht statisch sind? Da ich versucht habe, die Funktionen nicht statisch zu machen, und während eine der Dateien in einem Unterverzeichnis vorhanden war, gab das Erstellen dieses Moduls eine Warnung aus, die besagte, dass die exportierten Funktionen in dem im Unterverzeichnis vorhandenen Modul nicht definiert sind. Und als ich die Definitionen statisch machte, funktionierte es.
– Raunaq Kochar
4. Dezember 2016 um 16:47 Uhr
stackoverflow.com/questions/6670589/use-of-export-symbol könnte von Nutzen sein
– Bart
23. März 2012 um 9:10 Uhr
ausgezeichnete Informationen dazu zu finden hören
– raj_gt1
20. Juni 2013 um 11:09 Uhr
Minimales lauffähiges Beispiel: stackoverflow.com/a/44614246/895245
– Ciro Santilli OurBigBook.com
18. Juni 2017 um 11:06 Uhr