Как на самом деле происходит системный вызов в Linux? - PullRequest
9 голосов
/ 07 августа 2009

Вдохновленный этим вопросом

Как заставить GDB разбирать?

и относится к этому

Что такое INT 21h?

Как на самом деле происходит системный вызов в Linux? что происходит при выполнении вызова до тех пор, пока не будет вызвана действительная процедура ядра?

Ответы [ 4 ]

8 голосов
/ 07 августа 2009

Предполагается, что мы говорим о x86:

  1. Идентификатор системного вызова заносится в регистр EAX
  2. Все аргументы, требуемые системным вызовом, помещаются в местоположения , определяемые системным вызовом . Например, некоторые системные вызовы ожидают, что их аргумент будет находиться в регистре EBX. Другие могут ожидать, что их аргумент находится на вершине стека.
  3. Вызывается INT 0x80 прерывание.
  4. Ядро Linux обслуживает системный вызов, идентифицируемый идентификатором в регистре EAX, помещая любые результаты в заранее определенные местоположения.
  5. Код вызова использует любые результаты.

Возможно, я немного заржавел, прошло несколько лет ...

7 голосов
/ 10 августа 2009

Приведенные ответы верны, но я хотел бы добавить, что есть больше механизмов для входа в режим ядра. Каждое последнее ядро ​​отображает страницу «vsyscall» в адресное пространство каждого процесса. Он содержит чуть больше, чем самый эффективный метод захвата системных вызовов.

Например, в обычной 32-битной системе оно может содержать:

 
0xffffe000: int $0x80
0xffffe002: ret

Но на моей 64-битной системе у меня есть доступ к более эффективному методу, использующему инструкции 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    

Эта страница vsyscall также отображает некоторые системные вызовы, которые могут быть выполнены без переключения контекста. Я знаю, что gettimeofday , time и getcpu сопоставлены там, но я думаю, что getpid может вписаться туда также *

4 голосов
/ 07 августа 2009

На этот вопрос уже ответили
Как реализован системный вызов в Linux?
Вероятно, не соответствовал этому вопросу из-за различий в использовании термина «системный вызов».

3 голосов
/ 07 августа 2009

По сути, все очень просто: где-то в памяти лежит таблица, в которой хранится каждый номер системного вызова и адрес соответствующего обработчика (см. http://lxr.linux.no/linux+v2.6.30/arch/x86/kernel/syscall_table_32.S для версии x86)

Затем обработчик прерываний INT 0x80 просто извлекает аргументы из регистров, помещает их в стек (ядра) и вызывает соответствующий обработчик системного вызова.

...