Provided by: manpages-pl-dev_4.26.0-1_all 

NAZWA
init_module, finit_module - ładuje moduł jądra
BIBLIOTEKA
Standardowa biblioteka C (libc, -lc)
SKŁADNIA
#include <linux/module.h> /* Definicja stałych MODULE_* */
#include <sys/syscall.h> /* Definicja stałych SYS_* */
#include <unistd.h>
int syscall(SYS_init_module, void module_image[.len], unsigned long len,
const char *param_values);
int syscall(SYS_finit_module, int fd,
const char *param_values, int flags);
Uwaga: glibc nie udostępnia opakowania dla tych wywołań systemowych, co wymusza użycie syscall(2).
OPIS
init_module() ładuje obraz ELF do przestrzeni jądra, przeprowadzając wszelkie niezbędne przesunięcia
symboli, inicjuje parametry modułu zgodnie z wartościami przekazanymi przez wywołującego, a następnie
uruchamia funkcję init modułu. To wywołanie systemowe wymaga uprzywilejowania.
Argument module_image wskazuje na bufor zawierający obraz binarny, który ma być załadowany; len określa
rozmiar tego bufora. Obraz modułu powinien być prawidłowym obrazem ELF, zbudowanym do aktualnie
działającego jądra.
Argument param_values jest łańcuchem zawierającym wartości parametrów modułu (zdefiniowanych wewnątrz
modułu za pomocą module_param() i module_param_array()), rozdzielone spacją. Jądra analizuje ten łańcuch
i inicjuje podane parametry. Określenie każdego z parametrów ma postać:
nazwa[ =wartość [,wartość...]]
Parametr nazwa jest jednym ze zdefiniowanych wewnątrz modułu za pomocą module_param() (zob. plik źródeł
jądra Linux include/linux/moduleparam.h). Parametr wartość jest opcjonalny w przypadku parametrów bool i
invbool. Wartości parametrów tablicy są podawane w liście rozdzielonej przecinkami.
finit_module()
Wywołanie systemowe finit_module() jest podobne do init_module(), lecz odczytuje moduł, który ma być
załadowany, z deskryptora pliku fd. Ma to zastosowanie, gdy autentyczność modułu jądra można określić na
podstawie jego położenia w systemie plików; w przypadku gdy jest to możliwe, można w ten sposób uniknąć
narzutu wynikającego z używania modułów podpisanych kryptograficznie. Argument param_values jest taki sam
jak do init_module().
Argument flags modyfikuje działanie finit_module(). Jest maską bitową wartości, utworzoną przez
zsumowanie (OR) zera lub więcej poniższych znaczników:
MODULE_INIT_IGNORE_MODVERSIONS
Ignoruje skróty wersji symboli.
MODULE_INIT_IGNORE_VERMAGIC
Ignoruje magię wersji jądra.
MODULE_INIT_COMPRESSED_FILE (od Linuksa 5.17)
Używa modułu dekompresji w jądrze.
W module są wbudowane pewne mechanizmy bezpieczeństwa zapewniające, że będzie on pasował do jądra, do
którego jest załadowywany. Są one zapisywane przy budowaniu modułu i weryfikowane przy jego ładowaniu. Po
pierwsze, moduł zapisuje łańcuch „vermagic” zawierający łańcuch z numerem wersji jądra i głównymi cechami
(takimi jak typ procesora). Po drugie, jeśli moduł zbudowano z włączoną opcją konfiguracyjną
CONFIG_MODVERSIONS, to zapisywany jest skrót (hash) wersji każdego symbolu, którego używa moduł. Skrót
ten zależy od typów argumentów i zwracanej przez funkcję, nazwaną przez symbol, wartości. W niniejszym
przypadku, numer wersji jądra w „vermagic” jest ignorowany przyjmując, że skróty wersji symboli są
wystarczająco wiarygodne.
Użycie znacznika MODULE_INIT_IGNORE_VERMAGIC wskazuje, że łańcuch „vermagic” ma być zignorowany,
natomiast znacznik MODULE_INIT_IGNORE_MODVERSIONS wskazuje, że skróty wersji symboli mają być
zignorowane. Jeśli jądro zbudowano w sposób umożliwiający wymuszone ładowanie modułów (tj. skonfigurowano
je z opcją CONFIG_MODULE_FORCE_LOAD), to ładowanie będzie kontynuowane, w przeciwnym przypadku zawiedzie
z błędem ENOEXEC, jak jest to spodziewane wobec nieprawidłowych modułów.
Jeśli jądro zbudowano z opcją CONFIG_MODULE_DECOMPRESS, można skorzystać z funkcji dekompresji w jądrze.
Kod w przestrzeni użytkownika może sprawdzić, czy jądro obsługuje dekompresję odczytując atrybut
/sys/module/compression. Jeśli jądro obsługuje dekompresję, skompresowany plik można podać bezpośrednio
do finit_module() za pomocą znacznika MODULE_INIT_COMPRESSED_FILE. Moduł dekompresji w jądrze obsługuje
następujące algorytmy kompresji:
• gzip (od Linuksa 5.17)
• xz (od Linuksa 5.17)
• zstd (od Linuksa 6.2)
Jądro implementuje jedynie pojedynczą metodę dekompresji. Wybiera się ją przy generowaniu modułu, zgodnie
z metodą kompresji użytą w konfiguracji jądra.
WARTOŚĆ ZWRACANA
W przypadku powodzenia, te wywołania zwracają 0. W razie wystąpienia błędu zwracane jest -1 i ustawiane
errno wskazując błąd.
BŁĘDY
EBADMSG (od Linuksa 3.7)
Podpis modułu jest nieprawidłowo sformatowany.
EBUSY Nastąpiło przeterminowanie, przy próbie rozwiązania referencji symbolu przez ten moduł.
EFAULT Argument adresu odnosi się do położenia, znajdującego się poza dostępną przestrzenią adresową
procesu.
ENOKEY (od Linuksa 3.7)
Podpis modułu jest nieprawidłowy albo jądro nie ma klucza do tego modułu. Błąd jest zwracany
tylko, jeśli jądro skonfigurowano z opcją CONFIG_MODULE_SIG_FORCE; w przeciwnym wypadku
nieprawidłowy lub niepodpisany moduł jedynie zatruwa (taint) jądro.
ENOMEM Brak pamięci.
EPERM Wywołujący nie był uprzywilejowany (nie posiadał przywileju (ang. capability) CAP_SYS_MODULE) lub
ładowanie modułów jest wyłączone (zob. /proc/sys/kernel/modules_disabled w proc(5)).
Mogą wystąpić następujące dodatkowe błędy dla init_module():
EEXIST Załadowano już moduł o takiej nazwie.
EINVAL param_values jest nieprawidłowe albo pewne fragmenty obrazu module_image są niespójne.
ENOEXEC
Obraz binarny podany w module_image nie jest obrazem ELF albo jest nieprawidłowym lub
przeznaczonym do innej architektury obrazem ELF.
Mogą wystąpić następujące dodatkowe błędy dla finit_module():
EBADF Plik, do którego odnosi się fd , nie jest otwarty do odczytu.
EFBIG Plik, do którego odnosi się fd, jest zbyt duży.
EINVAL Znaczniki flags są nieprawidłowe.
EINVAL Przy ładowaniu spakowanego modułu ze znacznikiem MODULE_INIT_COMPRESSED_FILE, zawiodło sprawdzanie
poprawności przeprowadzone przez dekompresor.
ENOEXEC
fd nie odnosi się do otwartego pliku.
EOPNOTSUPP (od Linuksa 5.17)
Ustawiono znacznik MODULE_INIT_COMPRESSED_FILE w celu załadowania spakowanego modułu, lecz jądro
zbudowano bez CONFIG_MODULE_DECOMPRESS.
ETXTBSY (od Linuksa 4.7)
Plik, do którego odnosi się fd, jest otwarty do odczytu i zapisu.
Oprócz powyższych błędów, jeśli wykonana funkcja init modułu zwróci błąd, to init_module() lub
finit_module() zawiodą, a errno zostanie ustawione na wartość zwróconą przez funkcję init.
STANDARDY
Linux.
HISTORIA
finit_module()
Linux 3.8.
Wywołanie systemowe init_module() nie jest obsługiwane przez glibc. W nagłówkach glibc nie ma jego
deklaracji, ale z powodów pewnych zaszłości historycznych wersje glibc przed glibc 2.23 eksportowały ABI
dla tego wywołania systemowego. Z tego powodu, aby go użyć wystarczy (przed glibc 2.23) manualnie
zadeklarować interfejs w swoim kodzie; alternatywnie można wywołać to wywołanie systemowe za pomocą
syscall(2).
Linux 2.4 i wcześniejsze
W Linuksie 2.4 i wcześniejszych wywołanie systemowe init_module() było wyraźnie odmienne:
#include <linux/module.h>
int init_module(const char *name, struct module *image);
(Aplikacje w przestrzeni użytkownika mogą wykryć dostępną wersję init_module() przez wywołanie
query_module(); to ostatnie wywołanie zawiedzie z błędem ENOSYS w Linuksie 2.6 i późniejszych).
Starsza wersja tego wywołania systemowego ładowała przesunięty obraz jądra, na który wskazywało image do
przestrzeni jądra i uruchamiało funkcję init modułu. To wywołujący był odpowiedzialny za udostępnienie
przesuniętego obrazu (od Linuksa 2.6, to wywołanie systemowe init_module() dokonuje przesunięcia).
Obraz modułu rozpoczyna się od struktury modułu, po której następują, odpowiednio, kod i dane. Od Linuksa
2.2 struktura modułu jest zdefiniowana następująco:
struct module {
unsigned long size_of_struct;
struct module *next;
const char *name;
unsigned long size;
long usecount;
unsigned long flags;
unsigned int nsyms;
unsigned int ndeps;
struct module_symbol *syms;
struct module_ref *deps;
struct module_ref *refs;
int (*init)(void);
void (*cleanup)(void);
const struct exception_table_entry *ex_table_start;
const struct exception_table_entry *ex_table_end;
#ifdef __alpha__
unsigned long gp;
#endif
};
Wszystkie pola wskazujące, oprócz next i refs, powinny wskazywać na adresy w ciele modułu i zostać
zainicjalizowane odpowiednio dla przestrzeni adresowej jądra, tzn. przesunięte wraz z resztą modułu.
UWAGI
Informacje o obecnie załadowanych modułach są dostępne w /proc/modules oraz w strukturze plików zawartej
w podkatalogach, przypisanych poszczególnym modułom, w katalogu /sys/module.
Więcej przydatnych informacji „od kuchni” znajduje się w pliku źródeł jądra Linux include/linux/module.h.
ZOBACZ TAKŻE
create_module(2), delete_module(2), query_module(2), lsmod(8), modprobe(8)
TŁUMACZENIE
Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Andrzej Krzysztofowicz
<ankry@green.mf.pg.gda.pl> i Michał Kułach <michal.kulach@gmail.com>
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać
zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ
ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-
list@lists.sourceforge.net.
Linux man-pages 6.9.1 2 maja 2024 r. init_module(2)