Como é que um syscall realmente acontecer no linux?
-
12-09-2019 - |
Pergunta
Inspirado por esta pergunta ??p>
Como posso forçar GDB desmontar?
e relacionadas com este
Como é que uma chamada de sistema realmente acontecer sob linux? o que acontece quando a chamada é realizada, até que a rotina do kernel real é invocada?
Solução
Assumindo que estamos falando x86:
- ID da chamada de sistema é depositados no registo EAX
- Qualquer argumentos exigidos pela chamada de sistema são depositadas na locais ditada pela chamada de sistema . Por exemplo, algumas chamadas de sistema esperar seu argumento para residir no registo EBX. Outros podem esperar o seu argumento para ser sentado no topo da pilha.
- Uma interrupção
INT 0x80
é invocado. - O kernel do Linux serviços da chamada de sistema identificado pelo ID no registo EAX, depositando qualquer resultado em locais pré-determinados.
- O código de chamada faz uso de nenhum resultado.
Eu posso ser um pouco enferrujado com isso, já faz alguns anos ...
Outras dicas
As respostas dadas estão corretas, mas eu gostaria de acrescentar que há mais mecanismos para entrar no modo kernel. Todo kernel recente mapeia a página "vsyscall" em cada processo espaço de endereço. Ele contém pouco mais do que o método syscall armadilha mais eficiente.
Por exemplo, em um sistema de 32 bits regular, que poderia conter:
0xffffe000: int $0x80
0xffffe002: ret
Mas no meu 64 bitsystem eu tenho acesso ao modo como método mais eficiente usando as instruções 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
Esta página vsyscall também mapeia algumas systemcalls que pode ser feito sem uma mudança de contexto. Eu sei certo gettimeofday , tempo e getcpu são mapeados lá, mas imagino getpid poderia caber lá dentro, assim como bem.
Esta já foi respondida pelo
Como é a chamada de sistema em Linux implementado?
Provavelmente não se encontraram com essa questão por causa do uso do termo diferentes "syscall".
Basicamente, é muito simples: Em algum lugar na memória encontra-se uma tabela onde cada número syscall e o endereço do manipulador correspondente é armazenado (veja http://lxr.linux.no/linux+v2.6.30/arch/x86/kernel/syscall_table_32.S para o x86 versão)
O manipulador de interrupção INT 0x80 então só tem os argumentos para fora dos registros, coloca-los no (kernel) pilha, e chama o manipulador syscall apropriada.