O que significa "uma chamada de sistema", se não a implementação na linguagem de programação?

12

Eu gostaria de entender o termo "chamada do sistema". Estou familiarizado que as chamadas do sistema são usadas para obter serviços do kernel a partir de um aplicativo do espaço do usuário.

A parte que eu preciso esclarecer é a diferença entre uma "chamada de sistema" e uma "implementação C da chamada do sistema".

Aqui está uma citação que me confunde:

On Unix-like systems, that API is usually part of an implementation of the C library (libc), such as glibc, that provides wrapper functions for the system calls, often named the same as the system calls that they call

Quais são as "chamadas de sistema que eles chamam"? Onde está a sua fonte? Posso incluí-los diretamente no meu código?

A "chamada do sistema" é, em um sentido genérico, apenas uma interface definida por POSIX, mas para realmente ver a implementação, é possível examinar a origem C e nela ver como o espaço de usuário real para a comunicação do kernel?

Nota de fundo: Estou tentando entender se, no final, cada função c acaba interagindo com dispositivos de /dev .

    
por TheMeaningfulEngineer 18.04.2014 / 11:04

5 respostas

19

Chamadas de sistema per se são um conceito. Eles representam ações que os processos podem solicitar ao kernel para executar.

Essas chamadas de sistema são implementadas no kernel do sistema semelhante ao UNIX. Essa implementação (escrita em C e em asm para pequenas partes) realmente executa a ação no sistema.

Em seguida, os processos usam uma interface para solicitar ao sistema a execução das chamadas do sistema. Essa interface é especificada pelo POSIX. Este é um conjunto de funções da biblioteca padrão C. Eles são, na verdade, wrappers, eles podem executar algumas verificações e, em seguida, chamar uma função específica do sistema no kernel que o instrui a executar as ações exigidas pela chamada do sistema. E o truque é que essas funções, que são a interface, são nomeadas da mesma forma que as chamadas do sistema em si e geralmente são chamadas diretamente como "as chamadas do sistema".

Você poderia chamar a função no kernel que executa a chamada do sistema diretamente através do mecanismo específico do sistema. O problema é que isso torna o seu código absolutamente não portável.

Então, uma chamada do sistema é:

  • um conceito, uma seqüência de ação executada pelo kernel para oferecer um serviço a um processo do usuário
  • a função da biblioteca padrão C que você deve usar em seu código para obter este serviço do kernel.
por 18.04.2014 / 11:21
6

Uma chamada de sistema é uma maneira de pedir ao seu sistema operacional (kernel) para fazer alguma operação em nome do seu programa, que o programa não pode fazer sozinho (ou é apenas inconveniente). A razão para não ser capaz de fazer alguma operação é normalmente que permitir que um programa aleatório faça isso pode comprometer a integridade do sistema, como fazer E / S (diretamente para a RAM, sobrescrevendo qualquer coisa).

POSIX define uma interface para programas, certas funções que seu programa pode chamar. Alguns deles traduzem mais ou menos diretamente as chamadas do sistema, outros exigem mais elaboração. É o tempo de execução para o seu idioma, por ex. a biblioteca C, que é responsável por oferecer a interface POSIX, e empacotar argumentos e receber resultados de volta para o responsável pela chamada.

Os sistemas Unixy oferecem interfaces POSIX mais ou menos diretamente como chamadas do sistema. Normalmente, há uma maneira de invocar chamadas do sistema diretamente, procure por syscall(2) para obter detalhes sobre como usar esse recurso no Linux.

    
por 18.04.2014 / 15:42
5

Claro, vamos fazer quantas direções-podemos-ver-a-esse-elefante? coisa.

A chamada real do sistema é, no seu programa construído, a instrução da máquina que aciona o escalonamento de privilégios no modo kernel, e no próprio kernel é o código que a instrução invoca. O código libc (e todo tempo de execução de linguagem) configura os registros de máquina e parâmetros de armazenamento onde o código do kernel espera encontrá-los, o que pode ser decididamente lugares ímpares devido a restrições naquela instrução de máquina.

Uma vez no próprio código OS, há um pouco de desdobramento da imagem espelhada do material específico da máquina que o tempo de execução do usuário utilizou e, em seguida, uma chamada de rotina perfeitamente comum.
Se você quiser ver exatamente como isso funciona em um sistema operacional completo, puxe a fonte do kernel ( git clone https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/ ) e faça, por exemplo, %código%. Puxe a fonte glibc e faça o mesmo.

    
por 18.04.2014 / 17:04
3

No Linux, pelo menos, o mecanismo de chamada do sistema funciona sob a maioria das arquiteturas, colocando alguns dados especificamente formatados (geralmente algum tipo de struct) em alguns registradores ou endereços de memória pré-definidos.

O problema vem no entanto, na verdade, forçando a CPU a fazer a mudança no espaço do kernel para que ele possa executar o código do kernel privilegiado para atender a chamada. Isso é feito forçando uma falha de algum tipo (uma falha sendo uma divisão por 0, um estouro indefinido ou um segfault, etc), o que força o kernel a assumir a execução para lidar com a falha.

Normalmente, o kernel manipula falhas matando o processo causador ou executando um manipulador fornecido pelo usuário. No entanto, no caso de um syscall, ele verificará os registros predefinidos e os locais de memória e, se eles contiverem um pedido syscall, ele executará aquele usando os dados fornecidos pelo processo do usuário na estrutura in-memory. Isso geralmente tem que ser feito com uma montagem especialmente feita à mão e para facilitar o uso do syscall para o usuário que a biblioteca C do sistema tem para envolvê-lo como uma função. Para uma interface de nível mais baixo, consulte link para obter algumas informações sobre como funcionam e como você trabalha com o syscalls pode chamar então sem um wrapper C.

Isso é uma simplificação excessiva, não é verdade em todas as arquiteturas (mips tem uma instrução syscall especial) e não necessariamente funciona da mesma forma em todos os sistemas operacionais. Ainda assim, se você tiver algum comentário ou pergunta, por favor, pergunte.

Amended: Note, com relação ao seu comentário sobre coisas em / dev / isto é na verdade uma interface de nível mais alto para o kernel, não uma mais baixa. Esses dispositivos realmente usam (aproximadamente) 4 syscalls por baixo. Escrever para eles é o mesmo que escrever um syscall, ler um syscall de leitura, abrir / fechar o equivalente a syscalls abertos e próximos e executar um ioctl causa um syscall ioctl especial que em si é uma interface para acessar um dos muitos ioctl do sistema chamadas (chamadas especiais, geralmente específicas do dispositivo, com uso muito restrito para escrever um syscall inteiro para elas).

    
por 18.04.2014 / 13:32
1

Toda chamada de sistema tem um inteiro associado. Esse número inteiro é uma função do valor de retorno da chamada do sistema, número de argumentos para a chamada do sistema e tipo dos argumentos. Este número de chamada do sistema não é nada, mas um deslocamento no vetor de chamada do sistema global, esse vetor que é acessível apenas no modo privilegiado contém o ponteiro para manipuladores apropriados. O processo ao invocar uma chamada de sistema, uma interrupção de software (interrupção de interceptação) seria gerada, portanto, um manipulador de interceptações seria executado, o qual determina qual chamada de sistema deve ser invocada. Em seguida, o kernel copiaria os argumentos da chamada de sistema passada pelo usuário que está na pilha para os registradores do processador e, ao concluir o serviço solicitado, os dados seriam copiados de volta para a pilha dos registradores do processador. Esta é uma das razões pelas quais há argumentos limitados para chamadas do sistema, uma vez que os argumentos seriam copiados em registros do processador e os processadores têm registros limitados.

    
por 14.06.2014 / 17:55