2009-08-07 21 views
9

Zainspirowany to pytanieW jaki sposób działa syscall na Linuksie?

How can I force GDB to disassemble?

i związane z tym jednym

What is INT 21h?

Jak działa faktycznie wywołanie systemowe wydarzyć pod Linuksem? co się dzieje, gdy wywołanie jest wykonywane, do momentu wywołania rzeczywistej procedury jądra?

+0

+1, interesujące pytanie! –

+0

syscall pytanie implementacyjne: http://stackoverflow.com/questions/499188/how-is-the-system-call-in-linux-implemented – nik

+0

głosowanie do zamknięcia. rzeczywiście jest duplikatem (nie pojawił się w wyszukiwaniu, ponieważ użyłem syscall) –

Odpowiedz

8

Zakładając, że mówimy o x86:

  1. ID of the system call osadza się w EAX zarejestrować
  2. Wszelkie argumenty wymagane przez wywołanie systemowe są zdeponowane w locations dictated by the system call. Na przykład niektóre wywołania systemowe oczekują, że ich argument zostanie umieszczony w rejestrze EBX. Inni mogą oczekiwać, że ich argument będzie siedział na szczycie stosu.
  3. Wywołane zostaje przerwanie INT 0x80.
  4. Jądro Linux obsługuje wywołanie systemowe zidentyfikowane przez identyfikator w rejestrze EAX, odkładając wyniki we wcześniej ustalonych lokalizacjach.
  5. Kod wywołujący wykorzystuje dowolne wyniki.

mogę być nieco zardzewiały na to, że już kilka lat ...

+0

Jeśli dobrze pamiętam, ponieważ jądro ma swój własny stos, żaden program przestrzeni użytkownika nie może umieścić na nim czegoś, więc wszystkie argumenty muszą zostać przekazane przez rejestry. – Benno

+0

Naprawdę? Niejasno pamiętam, że mój profesor wspomniał, że Linux ma kilka makr do mapowania adresów przestrzeni użytkownika na jądro ... Mógłbym się mylić. –

+3

INT 0x80 jest używane tylko wtedy, gdy instrukcje SYSCALL/SYSENTER nie są dostępne, IIRC. –

3

Zasadniczo jego bardzo prosta: Gdzieś w pamięci znajduje się stół, gdzie każdy numer syscall i adres odpowiedniej obsługi jest przechowywany (patrz http://lxr.linux.no/linux+v2.6.30/arch/x86/kernel/syscall_table_32.S dla wersji x86)

Program obsługi przerwań INT 0x80 pobiera następnie argumenty z rejestrów, umieszcza je na stosie (jądro) i wywołuje odpowiednią procedurę obsługi syscall.

7

Podane odpowiedzi są poprawne, ale chciałbym dodać, że istnieje więcej mechanizmów wchodzenia w tryb jądra. Każde najnowsze jądro mapuje stronę "vsyscall" w przestrzeni adresowej każdego procesu. Zawiera niewiele więcej niż najbardziej wydajną metodę pułapek systemowych.

Na przykład na zwykłym systemie 32 bitowym mogło zawierać:


0xffffe000: int $0x80 
0xffffe002: ret 

Ale na moim 64-bitsystem mam dostęp do drogi bardziej skuteczną metodą przy użyciu instrukcji syscall/sysenter


0xffffe000: push %ecx 
0xffffe001: push %edx 
0xffffe002: push %ebp 
0xffffe003:  mov %esp,%ebp 
0xffffe005:  sysenter 
0xffffe007: nop  
0xffffe008: nop  
0xffffe009: nop  
0xffffe00a: nop  
0xffffe00b: nop  
0xffffe00c: nop  
0xffffe00d: nop  
0xffffe00e:  jmp 0xffffe003 
0xffffe010: pop %ebp 
0xffffe011: pop %edx 
0xffffe012: pop %ecx 
0xffffe013: ret  

Ta strona vsyscall również mapuje niektóre systemy, które można wykonać bez przełącznika kontekstu. Znam pewną gettimeofday, czas i getcpu są tam odwzorowany, ale mogę sobie wyobrazić getpid zmieściłoby się tam tak dobrze.

Powiązane problemy