NAME
get_kernel_syms, create_module, init_module, delete_module − Unterstützung für ladbare Module
ÜBERSICHT
#include <linux/module.h>
int get_kernel_syms(struct kernel_sym *table);
int create_module(char *module_name, unsigned long size);
int
init_module(char *module_name, char
*code,
unsigned codesize, struct mod_routines
*routines,
struct symbol_table *symtab);
int delete_module(char *module_name);
struct kernel_sym {
unsigned long value; | ||
char name[SYM_MAX_NAME]; |
};
struct mod_routines {
int (*init)(void); | |
void (*cleanup)(void); |
};
struct module_ref {
struct module *module; | |
struct module_ref *next; |
};
struct internal_symbol {
void *addr; | |
char *name; |
};
struct symbol_table {
int size; /* insgesamt, einschließlich Stringtabelle!!! */ | |
int n_symbols; | |
int n_refs; | |
struct internal_symbol symbol[0]; | |
struct module_ref ref[0]; |
};
BESCHREIBUNG
Diese Systemaufrufe sind noch nicht in eine Bibliothek eingebunden, das heißt, sie müssen durch den Mechanismus syscall(__NR_function) aufgerufen werden.
get_kernel_syms(table);
hat zwei Aufgaben: Zum einen, wenn table NULL ist,
gibt dieser Aufruf nur die Anzahl der Symbole,
einschließlich Modulnamen, zurück, die
verfügbar sind. Diese Anzahl sollte benutzt werden um
Speicher zu reservieren für diese Anzahl von
Einträgen von struct kernel_sym.
Wenn table nicht NULL ist kopiert dieser Aufruf alle
Kernel-Symbole und Modulnamen (und Versionsinformationen)
vom Kernel in der Bereich, auf den table zeigt. Die
Einträge sind nach LIFO-Prinzip geordnet. Für
jedes Modul wird ein Eintrag, der das Modul beschreibt,
gefolgt von Einträgen, die die Symbole beschreiben, die
von diesem Modul exportiert werden, erzeugt.
Beachte, dass
für Symbole die ein Modul beschreiben, der Wert-Teil
value der Struktur die kernel Adresse der
Struktur enthält, die das Modul beschreibt.
Im Teil name der Struktur ist dem Modul-Namen ein
# vorausgestellt, wie in #my_module. Das
Symbol, dass ein Modul beschreibt erscheint vor den
Symbolen, die durch dieses Modul definiert werden.
Vor den residenten Symbolen des Kernels erscheint ein
Modulnamen-Symbol mit dem Dummynamen #. Diese
Information kann benutzt werden um eine Tabelle von
Modulreferenzen aufzubauen, wenn Module gestapelt (oder
geschichtet) werden.
create_module(module_name, size); belegt size Byte Kernelspeicher für ein Modul, und erzeugt die nötigen Kernelstrukturen für das neue Modul name. Das Modul existiert nun im Kernelspeicher, mit dem Status MOD_UNINITIALIZED.
init_module(module_name,
code, codesize,
routines, symtab);
Dies ist der wirkliche "module loader", der das
Modul name in den Kernel lädt. Die Parameter
code und codesize beziehen sich auf das
verschobene Binärobjektmodul, welches codesize
Byte groß ist.
Wenn der Parameter codesize oder-verknüpft mit MOD_AUTOCLEAN ist, wird das Modul für "autocleaning" vorgesehen, d.h. für das regelmäßige entfernen ungenutzter Module.
Beachte, dass die ersten 4 Byte in der Moduldatei als Referenzzähler im Kernelbereich benutzt werden und von den Makros MOD_INC_USE_COUNT und MOD_DEC_USE_COUNT aktualisiert werden. Dieser Zähler enthält auch die Kennzeichenbits MOD_AUTOCLEAN sowie MOD_VISITED, die für "autocleaning" benutzt werden.
Die Funktionen, die in routines beschrieben werden, werden zum Starten und Stoppen des Moduls benutzt. Diese Zeiger sollten daher die Adressen der Funktionen init_module() und cleanup_module() enthalten, die für jedes ladbare Modul definiert sein müssen.
Wenn ein Modul Symbole für die Benutzung durch andere Module exportieren will, oder wenn das Modul Referenzen erstellt zu Symbolen, die durch andere Module definiert wird, dann hat der Parameter symtab auf eine Struktur zu zeigen, die dies beschreibt. Ein NULL-Wert für symtab bedeutet, dass keine Symbole exportiert werden und keine Referenzen zu anderen Modulen gemacht werden.
Die symtab, die in den Kernel hinein kopiert wird, enthält eine Struktur symbol_table direkt gefolgt von einer Stringtabelle, die die Namen der Symbole enthält, die von dem Modul definiert werden. Das Element size muss auch die Größe dieser Tabelle enthalten.
Besondere
Überlegungen:
Die Elemente n_symbols und n_refs sagen aus,
wie viele Symbole und wie viele Mudolreferenzen in der
Struktur symbol_table enthalten sind. Direkt nach
diesen Ganzzahlen folgen die Felder mit den
Symboldefinitionen. Das Element name in jeder
struct internal_symbol sollte kein gewöhnlicher
Pointer sein, sondern der offset zu dem
zugehörigen Eintrag in der Stringtabelle relativ zum
Start der Struktur symbol_table.
Wenn alle definierten Symbole aufgelistet sind, folgt das Feld der Modulreferenzen wie in den Elementen struct module_ref Beschrieben. Nur das Feld module dieser Struktur muss initialisiert sein. Die Moduladressen, die durch einen früheren Aufrufe von get_kernel_syms erhalten wurden, von Elementen deren Namen mit # beginnen, sollte in dieses Feld kopiert werden.
Wenn das Modul erfolgreich geladen werden konnte und wenn der Aufruf der Modulfunktion init_module() auch Erfolg hatte, dann wird der Status des Moduls nach MOD_RUNNING geändert. Anderenfalls wird der Kernelspeicher, der von dem Modul belegt wird, freigegeben.
delete_module(module_name);
Diese Routine sollte benutzt werden um ein Modul zu
entladen. Wenn der Modulreferenzzähler anzeigt, dass
das Modul nicht aktiv ist, und wenn es keine Referenzen zu
diesem Modul von anderen Modulen gibt, wird die
Modulfunktion cleanup_module() aufgerufen.
Wenn all diese Schritt erfolgreich sind wird der Kernelspeicher, der durch das Modul und seine Strukturen belegt ist, freigegeben.
Beachte, dass wenn NULL als Argument für delete_module benutzt wird, der Kernel alle Module entfernt.
DIAGNOSE
Wenn Fehler auftreten geben diese Funktionen den Wert -1 zurück und setzen die globale Variable errno mit der Fehlernummer. Auch wird ein beschreibender Text auf der Konsole ausgegeben.
SIEHE AUCH
insmod(1), rmmod(1), lsmod(1), ksyms(1), genksyms(8).
GESCHICHTE
Modul-Support wurde von A. Nonym eingeführt. Die Linux-Version stammt u.a. von Bas Laarhoven <bas [AT] vimec.nl>, Version 0.99.14 von Jon Tombs <jon [AT] gtex02.es>, erweitert durch Bjorn Ekwall <bj0rn [AT] blox.se>.
BUGS
Naah...