Hauptindex | Abschnitt 2 | Optionen |
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, einschliesslich Stringtabelle!!! */ int n_symbols; int n_refs; struct internal_symbol symbol[0]; struct module_ref ref[0]; };
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, daß 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, daß 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, daß 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 Addressen 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, daß 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 muß auch die Größe dieser Tabelle enthalten.
Besondere Überlegungen:
Die Elemente
n_symbols und
n_refs sagen aus, wieviele 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 muß 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, daß 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, daß wenn NULL als Argument für delete_module benutzt wird, der Kernel alle Module entfernt.
30. September 1996 | MODULES (2) | Linux |
Hauptindex | Abschnitt 2 | Optionen |
Bitte richten Sie Ihre Kommentare zu diesem Handbuch Seite Service, Ben Bullock. Privacy policy.
“ | How do you pronounce UNIX ? You Nix ! | ” |