Uruchamianie programów w systemie Linux
Linux udostępnia standardowe dla Unixów wywołanie systemowe
execve(). Kontekst programu wołającego zostaje całkowicie
zastąpiony przez kontekst nowego programu. Linux 2.4.7 obsługuje wiele
formatów plików binarnych, w tym programy napisane dla innych systemów
operacyjnych (SunOs, Solaris, RISCOS). Dlatego nie ma jednej procedury
ładowania pliku. Zamiast tego przechowywana jest lista znanych
formatów (są one zmodularyzowane) i przy poleceniu ładowania pliku
próbuje się zastosować kolejno różne funkcje ładujące.
Lista formatów
Jądro utrzymuje na zmiennej formats listę struktur linux_binfmt odpowiadających
zarejestrowanym formatom. Formaty można rejestrować za pomocą funkcji
register_binfmt() biorącej taką strukturę jako parametr.
Przepływ sterowania
-
Funkcja execve() rozwijana jest z makra w pliku
unistd.h. Zachowuje ona w rejestrach numer odpowiadający wywołaniu
execve() (__NR_EXECVE) oraz wskaźniki do swoich parametrów (ścieżka
pliku, tablicę argumentów dla programu oraz tablicę zmiennych
środowiska) oraz wywołuje przerwanie int 0x80.
- Obsługująca to przerwanie funkcja sys_call() zachowuje na
stosie rejestry procesu (makro SAVE_ALL) i uruchamia funkcję znajdującą się
w tablicy sys_call_table pod podanym numerem. W tym przypadku
jest to funkcja sys_execve().
- funkcja sys_execve() kopiuje ścieżkę pliku do pamięci
jądra i przekazuje ją, razem z argumentami, zmiennymi środowiska i
wartościami rejestrów procesu do funkcji
do_execve() . Funkcja ta wykonuje całość pracy; po jej
zakończeniu zwalniana jest już tylko pamięć na ścieżkę pliku i
propagowany kod powrotu funkcji do_execve().
- Po powrocie z wywołania systemowego do trybu użytkownika proces
jest już całkowicie zmieniony; proces po powrocie zastaje nowy kod
który zaczyna wykonywać zamiast wrócić do instrukcji po wywołaniu
funkcji execve() (jest to drobna nieścisłość - najpierw musi zostać wykonany kod interpretera programu; patrz ładowanie programu). Stąd można powiedzieć, że w przypadku
sukcesu funkcja execve() nigdy się nie kończy.