Co oznacza „wywołanie systemowe”, jeśli nie implementacja w języku programowania?


14

Chciałbym zrozumieć termin „wywołanie systemowe”. Wiem, że wywołania systemowe służą do pobierania usług jądra z aplikacji przestrzeni użytkownika.

Część, z którą muszę wyjaśnić, to różnica między „wywołaniem systemowym” a „implementacją C wywołania systemowego”.

Oto cytat, który mnie myli:

W systemach uniksowych ten interfejs API jest zwykle częścią implementacji biblioteki C (libc), takiej jak glibc, która zapewnia funkcje otoki dla wywołań systemowych, często nazywanych tak samo jak wywołania systemowe, które wywołują

Jakie są „wywołania systemowe, które nazywają”? Gdzie jest ich źródło? Czy mogę dołączyć je bezpośrednio do mojego kodu?

Czy „wywołanie systemowe” w sensie ogólnym jest po prostu interfejsem zdefiniowanym przez POSIX, ale aby faktycznie zobaczyć implementację, można zbadać źródło C i zobaczyć, jak faktycznie przebiega rzeczywista przestrzeń użytkownika do komunikacji z jądrem?

Uwaga: Próbuję zrozumieć, czy ostatecznie każda funkcja c kończy interakcję z urządzeniami z /dev.

Odpowiedzi:


21

Wywołania systemowe per se są pojęciem. Reprezentują działania, które procesy mogą poprosić jądro o wykonanie.

Te wywołania systemowe są implementowane w jądrze systemu podobnego do UNIX. Ta implementacja (napisana w C i asm dla małych części) faktycznie wykonuje akcję w systemie.

Następnie procesy używają interfejsu, aby poprosić system o wykonanie wywołań systemowych. Ten interfejs jest określony przez POSIX. Jest to zestaw funkcji biblioteki standardowej C. W rzeczywistości są opakowaniami, mogą wykonać pewne kontrole, a następnie wywołać funkcję specyficzną dla systemu w jądrze, która nakazuje mu wykonanie czynności wymaganych przez wywołanie systemowe. I sztuczka polega na tym, że te funkcje, które są interfejsem, są nazywane tak samo jak same wywołania systemowe i często są nazywane bezpośrednio „wywołaniami systemowymi”.

Możesz wywołać funkcję w jądrze, która wykonuje wywołanie systemowe bezpośrednio za pośrednictwem mechanizmu specyficznego dla systemu. Problem polega na tym, że twój kod absolutnie nie jest przenośny.

Wywołanie systemowe to:

  • koncepcja, sekwencja działań wykonywanych przez jądro w celu zaoferowania usługi procesowi użytkownika
  • funkcja standardowej biblioteki C, której należy użyć w kodzie, aby uzyskać tę usługę z jądra.

1
Czy masz przykład „funkcji opakowania” i rzeczywistego wywołania systemowego? (ścieżki plików w systemie Linux lub linki do źródeł)
TheMeaningfulEngineer 18.04.2014

3
Na przykład jest to implementacja getpidwywołania systemowego w jądrze systemu Linux: lxr.free-electrons.com/source/kernel/timer.c?v=2.6.35#L1337 . I jest to funkcja owinięcie w bibliotece standardowej GNU C glibc-2,19: fossies.org/dox/glibc-2.19/... .
lgeorget

@Igeorget: Twoje linki już nie działają. Zaktualizowany link do implementacji jądra: github.com/torvalds/linux/blob/… . Nie mogłem znaleźć, co robi glibc w dzisiejszych czasach, nie można nawigować po tym kodzie.
rchard2scout

6

Wywołanie systemowe jest sposobem poprosić systemu operacyjnego (kernel), aby wykonać pewne działania w imieniu swoim programie, że program nie może zrobić sam (lub jest po prostu niewygodne). Przyczyną niemożności wykonania niektórych operacji jest zwykle to, że zezwolenie na wykonanie losowego programu może naruszyć integralność systemu, na przykład wykonywanie operacji we / wy (bezpośrednio do pamięci RAM, nadpisywanie czegokolwiek).

POSIX definiuje interfejs programów, niektóre funkcje, które może wywoływać twój program. Niektóre z nich tłumaczą mniej więcej bezpośrednio na wywołania systemowe, inne wymagają bardziej szczegółowych opracowań. Jest to środowisko uruchomieniowe dla Twojego języka, np. Biblioteki C, która jest odpowiedzialna za oferowanie interfejsu POSIX oraz za pakowanie argumentów i odbieranie wyników z powrotem do osoby dzwoniącej.

Systemy Unixy oferują interfejsy POSIX mniej więcej bezpośrednio jako wywołania systemowe. Zazwyczaj istnieje sposób bezpośredniego wywoływania wywołań systemowych, poszukaj syscall(2)szczegółowych informacji na temat korzystania z tej funkcji w systemie Linux.


1
Dotykasz ważnego punktu, z którym inne odpowiedzi po prostu się ocierają. Każda funkcja, która racjonalnie zdolny programista może napisać dla siebie (takie jak strlen, strcpy, sqrt, i qsort) mogą być i prawdopodobnie jest w przestrzeni użytkownika, ładowane z biblioteki. (Głównie libc; funkcje matematyczne takie jak, sqrta funkcje trygonometryczne i hiperboliczne są prawdopodobnie w libm, bibliotece matematycznej.)… (Ciąg dalszy)
Scott,

1
(ciąg dalszy) ... Ale nie ma mowy, użytkownik może napisać swój własny fork, killlub openfunkcji, ponieważ wymagają one dostęp do przestrzeni jądra systemu operacyjnego pamięci (np tabela proces) lub uprzywilejowanych instrukcji (np, I / O). Dlatego kod wykonujący te funkcje musi znajdować się w jądrze systemu operacyjnego; stąd funkcje systemowe lub wywołania systemowe.
Scott

5

Jasne, zróbmy jak wiele kierunków możemy spojrzeć na tego słonia? rzecz.

Rzeczywistym wywołaniem systemowym jest w twoim wbudowanym programie instrukcja maszynowa, która uruchamia eskalację uprawnień do trybu jądra, aw samym jądrze to kod, który wywołuje instrukcja. Kod libc (i każde środowisko uruchomieniowe każdego języka) konfiguruje rejestry komputera i parametry w pamięci, w których kod jądra oczekuje ich znalezienia, co może być zdecydowanie nieparzystym miejscem ze względu na ograniczenia tej instrukcji maszyny.

Gdy już znajdziesz się w samym kodzie systemu operacyjnego, następuje trochę odwrócenia obrazu lustrzanego specyficznych dla maszyny rzeczy, które wykonało środowisko użytkownika, a następnie zupełnie zwyczajne wywołanie podprogramu.
Jeśli chcesz zobaczyć dokładnie, jak to działa w pełnym systemie operacyjnym, ściągnij jądro source ( git clone https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/) i wykonaj np git grep -i system\ call. Wyciągnij źródło glibc i zrób to samo.


To prawda, ale szperanie w Linuksie lub Glibc jest trochę ciężkie ...
vonbrand

3

W Linuksie przynajmniej mechanizm wywołań systemowych działa pod większością architektur, umieszczając niektóre specjalnie sformatowane dane (zwykle pewnego rodzaju strukturę c) w niektórych rejestrach lub predefiniowanych adresach pamięci.

Problemem jest jednak zmuszanie procesora do przełączenia się w przestrzeń jądra, aby mógł uruchomić uprzywilejowany kod jądra w celu obsługi wywołania. Odbywa się to przez wymuszenie jakiegoś błędu (błąd będący dzieleniem przez 0, niezdefiniowane przepełnienie lub segfault itp.), Co zmusza jądro do przejęcia wykonania w celu obsługi błędu.

Zwykle jądro obsługuje błędy, zabijając proces powodujący lub uruchamiając procedurę obsługi dostarczoną przez użytkownika. Jednak w przypadku wywołania syscall zamiast tego sprawdzi wstępnie zdefiniowane rejestry i lokalizacje pamięci, a jeśli zawierają żądanie syscall, uruchomi je przy użyciu danych dostarczonych przez proces użytkownika w strukturze w pamięci. Zwykle należy tego dokonać przy pomocy specjalnie spreparowanego zestawu. Aby ułatwić użytkownikowi korzystanie z syscall, biblioteka C systemu musi ją zawinąć jako funkcję. Interfejs niższego poziomu można znaleźć na stronie http://man7.org/linux/man-pages/man2/syscall.2.html, aby uzyskać informacje na temat działania wywołań syscall i sposobu, w jaki można dzwonić bez opakowania C.

Jest to uproszczone, nie jest tak we wszystkich architekturach (mips ma specjalną instrukcję syscall) i niekoniecznie działa tak samo na wszystkich systemach operacyjnych. Jeśli jednak masz jakieś uwagi lub pytania, zadaj je.

Poprawiono: Uwaga dotycząca twojego komentarza na temat rzeczy w / dev / jest to w rzeczywistości interfejs wyższego poziomu do jądra, a nie niższy. Urządzenia te używają (około) 4 wywołań systemowych pod spodem. Zapisywanie do nich jest takie samo jak zapisywanie syscall, odczytywanie odczytanego syscall, otwieranie / zamykanie ich jako równoważne otwieraniu i zamykaniu syscall i uruchamianie ioctl powoduje specjalne wywołanie systemowe ioctl, które samo w sobie jest interfejsem umożliwiającym dostęp do jednego z wielu ioctl systemu wywołania (specjalne, zwykle specyficzne dla urządzenia połączenia o zbyt wąskim użyciu, aby napisać dla nich całe połączenie systemowe).


1

Każde wywołanie systemowe ma przypisaną liczbę całkowitą. Ta liczba całkowita jest funkcją wartości zwracanej przez wywołanie systemowe, liczby argumentów do wywołania systemowego i rodzaju argumentów. Ten numer wywołania systemowego jest niczym innym jak przesunięciem do wektora globalnego wywołania systemowego, ten wektor, który jest dostępny tylko w trybie uprzywilejowanym, zawiera wskaźnik do odpowiednich procedur obsługi. Po wywołaniu wywołania systemowego wygenerowane zostanie przerwanie programowe (przerwanie pułapkowe), a zatem zostanie uruchomiona procedura obsługi pułapki, która określa, które wywołanie systemowe powinno zostać wywołane. Następnie jądro kopiuje argumenty wywołania systemowego przekazanego przez użytkownika znajdującego się na stosie do rejestrów procesora, a po zakończeniu żądanej usługi dane zostaną skopiowane z powrotem do stosu z rejestrów procesora. Jest to jeden z powodów, dla których istnieją ograniczone argumenty do wywołań systemowych,


Każde wywołanie (operacja) jest wewnętrznie identyfikowane przez numer, prawda. Ale liczba zależy od operacji , a nie od wartości zwracanej ani liczby argumentów. Wyjaśnienie tego, jak działało z przestrzeni użytkownika na x86, znajduje się tutaj
vonbrand,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.