Co to jest połączenie systemowe Linux?

Co to jest połączenie systemowe Linux?

Pierwsze rzeczy

Zanim zagłębimy się w definicję wywołania systemu Linuksa i zbadamy szczegóły jego wykonania, najlepiej zacząć od zdefiniowania różnych warstw oprogramowania typowego systemu Linux.

Kernel Linux to wyspecjalizowany program, który uruchamia się i działa na najniższym dostępnym poziomie na sprzęcie. Ma zadanie zorganizowania wszystkiego, co działa na komputerze, w tym obsługę zdarzeń klawiatury, dysku i sieci w celu zapewnienia równolegle wielu programów do wykonywania wielu programów.

Kiedy jądro wykonuje program na poziomie użytkownika, wirtualizuje przestrzeń pamięci, aby programy uważały, że są jedynym procesem uruchomionym w pamięci. Ta ochronna bańka sprzętu i izolacji oprogramowania zwiększa bezpieczeństwo i niezawodność. Nieuprzywilejowana aplikacja nie może uzyskać dostępu do pamięci należącej do innych programów, a jeśli ten program się zawiedzie, jądro kończy się tak, aby nie mogła zaszkodzić reszty systemu.

Zamieszanie bariery z wywołani systemem systemu Linux

Ta warstwa izolacji między nieuprzywilejowanymi aplikacjami stanowi doskonałą granicę do ochrony innych aplikacji i użytkowników w systemie. Jednak bez pewnego sposobu interfejsu z innymi elementami w komputerze i świecie zewnętrznym programy nie byłyby w stanie osiągnąć wiele.

Aby ułatwić interakcję, jądro wyznacza bramę oprogramowania, która umożliwia uruchomionemu programowi poprosić o działanie jądra w jego imieniu. Ten interfejs jest znany jako wywołanie systemowe.

Ponieważ Linux postępuje zgodnie z filozofią UNIX „Everything Is a Plik”, wiele funkcji można wykonać, otwierając i czytanie lub zapisanie do pliku, co może być urządzeniem. Na przykład w systemie Windows możesz użyć funkcji o nazwie CryptGenRandom, aby uzyskać dostęp do losowych bajtów. Ale w systemie Linux można to zrobić, po prostu otwierając „Plik”/dev/urandom i odczytując z niego bajty za pomocą standardowych połączeń systemu wejściowego/wyjściowego pliku. Ta kluczowa różnica pozwala na prostszy interfejs wywołania systemu.

Wazer-cienki opakowanie

W większości aplikacji wywołania systemowe nie są wykonywane bezpośrednio do jądra. Praktycznie wszystkie programy łączą się w standardowej bibliotece C, która zapewnia cienkie, ale ważne opakowanie wokół połączeń systemowych Linux. Biblioteka upewnia się, że argumenty funkcyjne są skopiowane do prawidłowych rejestrów procesora, a następnie wydaje odpowiednie połączenie systemowe Linux. Po otrzymaniu danych z wywołania opakowanie interpretuje wyniki i zwraca je z powrotem do programu w spójny sposób.

Za kulisami

Każda funkcja w programie, który wchodzi w interakcję z systemem, jest ostatecznie przetłumaczona na wywołanie systemowe. Aby to zobaczyć w akcji, zacznijmy od podstawowego przykładu.

void main ()

To prawdopodobnie najbardziej trywialny program C, jaki kiedykolwiek zobaczysz. Po prostu zyskuje kontrolę za pośrednictwem głównego punktu wejścia, a następnie wychodzi. Nie zwraca nawet wartości, ponieważ główny jest zdefiniowany jako pustka. Zapisz plik jako CTEST.c i skompilujmy to:

GCC CTEST.C -O CTEST

Po skompilowaniu możemy zobaczyć rozmiar pliku jako 8664 bajtów. Może się nieznacznie różnić w twoim systemie, ale powinien wynosić około 8k. To dużo kodu, aby wejść i wyjść! Powodem, dla którego jest to 8K, jest to, że włączono czas wykonawczy LIBC. Nawet jeśli rozebramy symbole, wciąż jest to odrobina ponad 6k.

W jeszcze prostszym przykładzie możemy sprawić, by system Linux wywołuje wychodzenie, a nie zależnie od czasu wykonania C, aby to zrobić dla nas.

void _start ()
ASM („MOVL 1 USD,%EAX”;
„Xorl %EBX, %EBX;”
„Int 0x80”);

Tutaj przenosimy 1 do rejestru EAX, wyczyść rejestr EBX (który w inny sposób zawiera wartość zwracania), a następnie wywołać przerwanie połączenia systemowego Linux 0x80 (lub 128 w dziesiętnym). To przerwanie uruchamia jądro, aby przetworzyć nasze wezwanie.

Jeśli skompilujemy nasz nowy przykład, zwany asmtest.c i rozbij symbole i wyklucz standardową bibliotekę:

gcc -s -nostdlib asmtest.C -O asmtest

Wyprodukujemy binarne mniej niż 1k (w moim systemie daje 984 bajtów). Większość tego kodu to nagłówki wykonywalne. Teraz wywołujemy bezpośrednie połączenie systemowe Linux.

Do wszystkich praktycznych celów

W prawie wszystkich przypadkach nigdy nie będziesz musiał wykonywać bezpośrednich połączeń systemowych w programach C. Jeśli jednak używasz języka asemblera, może nastąpić potrzeba. Jednak w optymalizacji najlepiej byłoby pozwolić funkcjom biblioteki C wykonać wywoływanie systemu i mieć tylko kod krytyczny w wyniku wyników w dyrektywach montażu.

Jak programować samouczki telefoniczne

  • Wywołanie systemu EXEC
  • Wywołanie systemu widelca
  • Wywołanie systemu statystyk

Lista wszystkich połączeń systemowych

Jeśli chcesz zobaczyć listę wszystkich dostępnych wywołań systemowych dla Linux, możesz sprawdzić te strony referencyjne: Pełna lista wywołań systemowych na Linuxhint.com, Filippo.IO/ Linux-Syscall-Table/ lub Syscalls.Kernelgrok.com