Conceitos de Sistemas Operacionais: Chamadas de Sistema Prof Rafael J. Sandim
Conceitos de Sistema Operacional Interface entre o SO e os Programas de usuário é definida pelo conjunto de instruções estendidas que o sistema operacional proporciona. Essas instruções já foram chamada, no passado, de chamadas de sistema e o nome permanece (system calls) Chamadas disponíveis na interface variam de sistema operacional para sistema operacional Porém há semelhanças! Pode ser compatível com o POSIX Nesse curso estudaremos as chamadas de sistema do MINIX.
Chamadas de Sistemas Exemplo: count = read(file, buffer, nbytes); A chamada de sistema (e o procedimento de biblioteca) retorna o número de bytes realmente lido para o count. O count deve ser igual ao nbytes se ele conseguiu ler os nbytes da chamada read; Se o count for menor que nbytes pode significar que a chamada read encontrou o final do arquivo durante a leitura. Se a chamada de sistema não puder ser executada, seja devido a um parâmetro invalido, seja devido a um erro de disco, etc. Count será definido como -1 e o numero do erro é colocado em uma variável global chamada errno.
Chamadas de Sistemas O MINIX tem um total de 53 chamadas de sistema Essas chamadas estão agrupadas de acordo com seis categorias: Gerenciamento Sinais Gerenciamento de Arquivos Gerenciamento de diretórios e de sistema de arquivos Proteção Gerenciamento de tempo Os serviços oferecidos por tais chamadas determinam a maior parte do que um SO pode fazer.
Chamadas de Sistemas Lembrando: O significando de chamada de sistema está aberto a interpretações. POSIX define um número de procedimentos que um sistema compatível deve fornecer, mas não se são chamadas de sistema, chamadas de bibliotecas etc.
Chamadas de Sistemas Chamadas de sistema para o gerenciamento
FORK é um único meio de criar um novo processo Ele cria uma duplicata exata do processo original, incluindo todos os descritores de arquivo, registradores tudo! Depois do FORK, o processo original e a cópia (pai e filho) seguem caminhos diferentes Todas as variáveis têm valores idênticos no momento do FORK, mas como os dados do pai são copiados para o criar o filho, posteriores mudanças em um deles não afetam o outro. FORK retorna um valor Zero no filho e igual ao identificador do processo (PID) do filho no pai. Usando o valor retornado podemos saber qual é o processo pai e qual é o processo filho.
Na maioria dos casos o filho precisará executar um código diferente do pai. Exemplo do SHELL Ler um comando do terminal Criar um processo filho Espera o filho executar Lê um próximo comando após o filho terminar Para esperar o filho terminar, o pai executa uma chamada de sistema WAITPID, que espera o filho terminar. WAITPID pode esperar um filho específico, ou então, qualquer filho, definindo o primeiro parâmetro como -1. Quanto o WAITPID se completa, o endereço apontado pelo segundo parâmetro contém o status de saída do filho (término normal ou anormal e valor de saída)
WAIT foi substituído pelo WAITPID, porém mesmo obsoleta ela continua sendo fornecida por razões de retrocompatibilidade. No exemplo do Shell, é criado um novo processo. Esse processo filho deve executar o comando do usuário. Ele faz isso usando a chamada EXEC, que faz com que toda sua imagem de núcleo seja substituída pelo arquivo nomeado em seu primeiro parâmetro.
Consideremos o seguinte exemplo cp file1 file2 Utilizado para copiar o file1 para file2. Depois que o Shell é bifurcado, o processo filho localiza e executa o arquivo cp e passa para ele os nomes dos arquivos de origem e de destino O programa principal de cp (e o programa principal da maioria dos outros programas) contém a declaração: main(argc, argv, envp)
main(argc, argv, envp) argc é o numero de itens na linha de comando (inclusive o nome do programa) argv é um ponteiro para uma matriz. O elemento i dessa matriz é um ponteiro para i-péssima string na linha de comando. argv[0] = cp, argv[1] = file1 e argv[2] = file2 envp é um ponteiro para o ambiente, uma matriz, uma matriz de string que contem designações na forma nome = valor utilizados para passar informações como o tipo do terminal e o nome do diretório inicial para um programa. No nosso exemplo de código nenhum ambiente é passado, por isso, temos o terceiro parâmetro como zero.
Chamada EXIT Os processos devem usar quando concluem sua execução. Tem um parâmetro, o status de saída 0 ~ 255 É retornado para o pai na variável status da chamada de sistema WAIT ou WAITPID. O byte de ordem inferior do status contem o status do término 0 (zero) sendo o término normal E os outros valores sendo várias condições de erro. O byte de ordem superior contém o status de saída do filho.
Exemplo para Chamada Exit O processo pai executa a instrução n = waitpid(-1, &status, options); Ele será suspenso até que algum processo-filho termine. Se o filho sai com quatro como parâmetro no exit, o pai será despertado com n definido como o pid do filho e o status definido como 0x0400
Os processos no MINIX têm sua memória dividida em três segmentos: Segmento de texto (código do programa, por exemplo) Segmento de dados (as variáveis) Segmento de pilha Segmento de dados cresce para cima Segmento de pilha cresce para baixo Entre eles há um intervalo de endereços não utilizados
A pilha cresce automaticamente, conforme necessário. A expansão do segmento de dados deve ser feita explicitamente, através da chamada de sistema BRK. Chamada BRK Tem um parâmetro addr que é o endereço onde o segmento de dados deve terminar. Se o endereço for maior que o endereço atual O segmento de dados é aumentado Se for menor que o endereço atual O segmento de dados é diminuído O ponteiro do segmento de dados deve ser menor que o ponteiro da pilha para que eles não se sobreponham.
Para facilitar a vida do programador é fornecida uma rotina denominada SBRK que também muda o tamanho do segmento de dados O parâmetro é o número de bytes a adicionar ao segmento de dados Parâmetros negativos reduzem o tamanho do segmento de dados SBRK Tamanho atual do segmento de dados (valor retornado por BRK) Calcula o novo tamanho Faz uma chamada pedindo esse número de bytes
Chamada GETPID Retorna o PID do processo que fez a chamada Chamada SETSID Cria uma nova sessão e define o PID do grupo como o do processo que fez a chamada. As sessões estão relacionadas a um recurso opcional do POSIX chamado controle de job. Porém não é suportado pelo MINIX. Chamada PTRACE Controla o programa que está sendo depurado. Ela permite que o depurador leia e grave a memória do processo controlado e a gerencie de outras maneiras.
Chamadas de Sistemas Chamadas de Sistema para Sinalização
Chamadas de Sistema para Sinalização A maioria das formas de comunicação interprocessos é planejada, mas há situações nas quais uma comunicação inesperada é necessária.
Chamadas de Sistemas Gerenciamento de arquivos
Chamadas de Sistemas Gerenciamento de diretórios e de sistema de arquivos
Chamadas de Sistemas Proteção
Chamadas de Sistemas Gerenciamento de tempo