Spis tresci
Tablice rozdzielcze urzadzen blokowych i znakowych sluza do przechowywania informacji o zainstalowanych urzadzeniach w systemie oraz o funkcjach dostepu do tych urzadzen. Wywolanie funkcji systemowej (np. open, close) dla pliku specjalnego przechodzi przez tablice rozdzielcza odpowiadajaca typowi danego pliku.
Tablice rozdzielcze urzadzen znakowych i blokowych zdefiniowane sa nastepujaco
(devices.c):
static struct device_struct chrdevs [MAX_CHRDEV] = {
{ NULL, NULL },
};
static struct device_struct blkdevs [MAX_BLKDEV] = {
{ NULL, NULL },
};
Stale MAX_CHRDEV oraz MAX_BLKDEV sa zdefiniowane w pliku major.h a ich
wartosc jest równa 32.
Struktura device_struct ma nastepujaca postac:
struct device_struct { const char *name; //nazwa urzadzenia struct file_operations *fops //odpowiednie operacje };
Oprocz swojego numeru glownego i drugorzednego (MAJOR i MINOR) urzadzenie
posiada w Linuxie swoj unikalny numer w polu i_rdev w i-wezle. Zmienna
jest typu dev_t (zdefiniowanego jako short).
Funkcje przeliczajace (fs.h):
#define MAJOR(a) (int)((unsigned short)(a) >> 8)
(osiem starszych bitow liczby a)
#define MINOR (a) (int)((unsigned short)(a) & 0xff)
(osiem mlodszych bitow liczby a)
#define MKDEV (a, b) ((int)((((a) & 0xff) << 8) | ((b) &
0xff)))
Funkcje operujace na tablicach rozdzielczych urzadzen to:
- int get_device_list (char * page)
Na zmienna page zwraca informacjê o zainstalowanych urzadzeniach,
wypisuje kolejno (dla urzadzen znakowych i blokowych) numer i nazwe urzadzenia.
- struct file_operations * get_blkfops (unsigned int major)
Dla zadanego wirtualnego urzadzenia blokowego (parametr major) zwraca strukture
file operations z tablicy rozdzielczej.
- int register_blkdev (unsigned int major, const char * name, struct file
operations * fops)
Instaluje w systemie nowe urzadzenie - wpisuje do tablicy rozdzielczej
nowe urzadzenie blokowe o podanych parametrach. Jako liczbe major mozna
podac 0, wtedy szuka pierwszego wolnego numeru. Mozliwe bledy: EBUSY (gdy
major = 0 i nie ma wolnego miejsca, albo podano juz zajety major), EINVAL
(gdy major > MAX_BLKDEV).
- int unregister_blkdev (unsigned int major, const char * name)
Wyinstalowuje urzadzenie - ustawia jego nazwe i wskaznik do operacji na
NULL. Blad: EINVAL (gdy zly numer major lub dla podanego numeru nie zgadza
sie nazwa).
- int check_disk_change (dev_t dev)
Sprawdza czy zadane urzadzenie o wewnetrznym numerze dev nie zmienilo nosnika
(np. wyjecie dyskietki, zmiana plyty CD itp.). Jezeli tak to aktualizuje
dane. Dla kazdego urzadzenia jest inna funkcja sprawdzajaca zmiane nosnika
- pole check_media_change w strukturze fops.
Dla operacji na urzadzeniach blokowych istnieja odpowiedniki znakowe.
Tablice rozdzielcze sa inicjowane podczas ladowania systemu. Odpowiadaja
za to funkcje chr_dev_init() (w mem.c) i blk_dev_init() (w ll_rw_blk.c).
Przykladowo:
- chr_dev_init(); - register_chr_dev(MEM_MAJOR, „mem", &memory_fops); - tty_init(); - lp_init(); - mouse_init(); - itp.
1. Pliki zrodlowe Linuxa: devices.c, major.h.