Jak uzyskać dostęp do wywołania systemowego z przestrzeni użytkownika?

Przeczytałem kilka akapitów w LKD1 i nie mogę po prostu zrozumieć treści poniżej:

Dostęp do wywołania systemowego z przestrzeni użytkownika

Ogólnie biblioteka C zapewnia obsługę wywołań systemowych. Aplikacje użytkownika mogą pobierać prototypy funkcji ze standardowych nagłówków i łączyć się z biblioteką C, aby korzystać z wywołania systemowego (lub procedury bibliotecznej, która z kolei używa wywołania syscall). Jeśli właśnie napisałeś wywołanie systemowe, wątpliwe jest, aby glibc już go obsługiwał!

Na szczęście Linux udostępnia zestaw makr do owijania dostępu do wywołań systemowych. Ustawia zawartość rejestru i wydaje instrukcje pułapki. Te makra są nazwane_syscalln(), gdzien wynosi od zera do sześciu. Liczba odpowiada liczbie parametrów przekazanych do wywołania systemowego, ponieważ makro musi wiedzieć, ile parametrów należy oczekiwać, a co za tym idzie, wprowadzić je do rejestrów. Na przykład rozważ wywołanie systemoweopen(), zdefiniowana jako

long open(const char *filename, int flags, int mode)

Makro syscall, które będzie używać tego wywołania systemowego bez wyraźnej obsługi biblioteki, byłoby

#define __NR_open 5
_syscall3(long, open, const char *, filename, int, flags, int, mode)

Następnie aplikacja może po prostu zadzwonićopen().

Dla każdego makra są 2 + 2 × n parametrów. Pierwszy parametr odpowiada typowi powrotu wywołania systemowego. Druga to nazwa wywołania systemowego. Następnie następuje typ i nazwa każdego parametru w kolejności wywołania systemowego. The__NR_open define jest w<asm/unistd.h>; jest to numer wywołania systemowego. The_syscall3 makro rozwija się w funkcję C z złożeniem inline; zespół wykonuje kroki omówione w poprzedniej sekcji, aby wypchnąć numer wywołania systemowego i parametry do właściwych rejestrów i wydać przerwanie programowe w celu przechwycenia do jądra. Umieszczenie tego makra w aplikacji to wszystko, co jest wymagane do użyciaopen() wywołanie systemowe.

Napiszmy makro, aby użyć naszego wspaniałego nowegofoo() wywołanie systemowe, a następnie napisz kod testowy, aby pokazać nasze wysiłki.

#define __NR_foo 283
__syscall0(long, foo)

int main ()
{
        long stack_size;

        stack_size = foo ();
        printf ("The kernel stack size is %ld\n", stack_size);
        return 0;
}

Co robiaplikacja może po prostu zadzwonićopen() oznaczać?

Poza tym, dla ostatniego kawałka kodu, gdzie jest deklaracjafoo()? Jak mogę sprawić, by ten fragment kodu był kompilowalny i uruchamialny? Jakie pliki nagłówkowe muszę zawrzeć?

__________
1 Rozwój jądra Linux, Robert Love.Plik PDF na wordpress.com (przejdź do strony 81);Wynik Książek Google.

questionAnswers(3)

yourAnswerToTheQuestion