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
.
źródło
getpid
wywoł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/... .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.źródło
strlen
,strcpy
,sqrt
, iqsort
) mogą być i prawdopodobnie jest w przestrzeni użytkownika, ładowane z biblioteki. (Głównie libc; funkcje matematyczne takie jak,sqrt
a funkcje trygonometryczne i hiperboliczne są prawdopodobnie w libm, bibliotece matematycznej.)… (Ciąg dalszy)fork
,kill
lubopen
funkcji, 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.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 npgit grep -i system\ call
. Wyciągnij źródło glibc i zrób to samo.źródło
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).
źródło
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,
źródło