W porównaniu
z poprzednią wersją zmieniono przebieg procesu kompilacji modułu. W jądrze
2.4 do kompilacji wystarczyły pliki nagłówkowe jądra, obecnie oprócz nagłówków
potrzebne jest również skonfigurowane źródłowe drzewo katalogowe jądra.
Struktura pliku makefile do tworzenia modułu uległa w związku z tym zmianie.
Szczegółowe informacje dotyczące tych zmian można znaleźć np w artykule: http://lwn.net/Articles/21823/
W związku
z powyższymi zmianami nie potrzebna staje się w kodzie modułu defincja:
#define MODULE
Dodatkowo
zmieniono rozszerzenia skompilowanych modułów z .o na .ko.
W
kodzie modułu należy jawne podać funkcję inicjującą i fukcję wykonywaną
przy odładowywaniu modułu za pomocą :
module_init(nazwa_funkcji_inicjującej)
module_exit(nazwa_funkcji_zwalniającej)
Próba
użycia dopuszczalnych w jądrze 2.4 makr int_module
oraz cleanup_module
zakończy się
warning'iem przy wgrywaniu.
Domyślnie
w jądrze 2.6 nie są eksportowane żadne identyfikatory, zatem używanie
EXPORT_NO_SYMBOLS
jest redundantne.
Warning'iem
również kończy się nie umieszczenie w kodzie modułu opisu jego licencji za
pomocą MODULE_LICENSE(„Licencja”)
. Makro to było również dostępne w
jądrach
2.4, ale tam miało charakter czysto informacyjny, a tu rodzaj licencji niesie
pewne konsekwencje. Z MODULE_LICENSE
związane jest bowiem makro
EXPORT_SYMBOL_GPL(...)
które pozwala udosępniać identyfikatory tylko modułom
na licencji GPL – jest to krok w celu umocniania rodziny open-sorce’owej.
Wprowadzenie tego rozwiązania było sprawą dyskusyjną.
Używane
w jądrze 2.4 MODULE_PARAM(...)
już nie istnieje. Aby używać parametrów w
wersji 2.6 po pierwsze należy dołączyć plik nagłówkowy:
#include
<linux/moduleparam.h>
Teraz
już w kodzie modułu możemy definiować parametry na kilka sposobów.
Standardowo będzie to makro:
module_param(name, type, perm);
gdzie name
to oczywiście nazwa parametru (a zarazem i
zmiennej); type
to typ parametru: byte,
short,
ushort,
int,
uint,
long,
ulong,
charp,
bool
lub invbool;
perm
natomiast jest w obecnej
implementacji jądra argumentem roboczym (ma być związany z sysfs) więc
bezpiecznie jest ustawić go na 0.
Jeżeli
zewnętrzna nazwa naszego parametru ma być inna niż nazwa zmiennej wewnątrz
kodu to możemy użyć:
module_param_named(name,
value, type, perm);
gdzie
name
to nazwa zewnętrzna; value
to nazwa naszej zmiennej; a type
i perm
są
analogiczne jak powyżej.
Oprócz
tego do dyspozycji mamy dwie możliwości deklaracji:
module_param_string(name,
string, len, perm);
gdy
chcemy parametr który jest stringiem mieć jako tablicę, a nie jako *char
; len
oznacza długość napisu - standardowo powinno to być sizeof(string)
.
module_param_array(name,
typ, num, perm);
gdy chcemy parametr który jest
tablicą typu type
– w momencie ładowania wartości powinny być podane po
przecinkach; num
to zewnętrzny parametr ustawiany na liczbę podanych do
tablicy wartości.
W
jądrze 2.4 aliasy mogły być definiowna w /etc/modules.conf
. W
wersji 2.6 można dodatkowo tworzyć aliasy bezpośrednio w kodzie poprzez makro:
MODULE_ALIAS("alias-name");
W jądrze
2.6 zmienił się sposób zarządzania odwołaniami do modułów. W jądrze 2.4
zarządzanie licznikiem odbywało się wewnątrz kodu modułu poprzez makra
MOD_INC_USE_COUNT, MOD_DEC_USE_COUNT
. Ewentualnie w określonych przypadkach mogło
odbywać się automatycznie poprzez ustawienie pola owner dla zasobów na
THIS_MODULE
. Podejście to często powodowało kłopoty i mogło się zdarzyć iż
następowało odwołanie do właśnie odładowywanago modułu.
Jądro
2.6 przynosi nowe rozwiązanie, nieco odciążające autorów modułów. Otóż
modyfikacja licznika odwołań może odbywać się tylko z zewnątrz kodu modułu
poprzez funkcję:
int
try_module_get(&module);
która zgłasza żądanie na moduł (w przypadku niemożności
dostępu zwraca 0) zwiększając przy okazji licznik odwołań. Zwolnienie modułu
i tym samym zmniejszenie licznika odwołań odbywa się poprzez:
module_put(&module)
Wyjątkiem od reguły może być wywołanie w
uzasadnionych przypadkach try_module_get(...)
od siebie samego.
Podejście to niestety nie jest pozbawione wad – może się np. zdarzyć iż z
powodu jakiegoś niestandardowego błędu proces wykonujący
try_module_get
nie wykona module_put
co zafałszuje licznik odwołań i może sprawić że nigdy nie osiągnie on
zera. W obronie przed takimi sytuacjami powstała opcja:
CONFIG_MODULE_FOR
CE_UNLOAD
Która ustawiona w konfiguracji
zezwala jądru na odładowywanie modułu nawet w przypadku niewyzerowanego
licznika odwołań. Opcja ta powinna być stosowana z należytą ostrożnością.
autor: Paweł Kowalski
http://www.linuxdevcenter.com/pub/a/linux/2002/12/12/vanishing.html
http://www.linux.org.uk/~davej/docs/post-halloween-2.6.txt
http://www.linux-mag.com/2004-06/compile_01.html
www.bashprofile.net/IMG/linux26.pdf
http://lwn.net/Articles/21817/
http://lwn.net/Articles/22197/
http://vmlinux.org/jocke/linux/external-modules-2.6.shtml
http://lwn.net/Articles/21823/