Histórico
Década de 1960
O responsável pelo
desenvolvimento do sistema Unix foi Ken Thompson chamando de Unics(
UNiplexed Information and Computing Service) e, posteriormente Unix.
Inicialmente ele foi desenvolvido em assembly para um minicomputador,
mas para torná-lo mais fácil de ser portado em outras plataformas
foi desenvolvida uma linguagem de alto nível, e reescreveu o código
do sistema nessa nova linguagem.
Em 1991, o finlandês
Linus Torvalds começou o desenvolvimento Linux, com base no em suas
experiências com o sistema Minix. O Linux evoluiu a partir da
colaboração de vários programadores que ajudaram no
desenvolvimento do kernel, utilitários e vários aplicativos.
A imagem a segui mostra as diversas ramificações do Unix.
Microsystem (SunOS e
Solaris), HP (HP-UX), IBM (AIX) e compaq(Compaq Unix).
Características
Unix é um sistema
operacional multiprogramável, multiusuário, que suporta múltiplos
processadores e implementa memória virtual . Com as características
a seguir:
- Escrito em linguagem de alto nível, tornando fácil a compreensão e alteração do seu código e portabilidade para outras plataformas de hardware;
- Oferece um conjunto de system calls que permite que programas complexos sejam desenvolvidos a partir de uma interface simples;
- Flexibilidade, podendo se utilizado como sistema operacional de computadores pessoais, estações de trabalho e servidores de todos os portes, voltados para bando de dados, web, correio eletrônico e aplicação;
- Implementação de threads, em algumas versões , e diversos mecanismos de comunicação e sincronização, como memória compartilhada, pipes e semáforos;
- Suporte a um grande número de aplicativos disponíveis no mercado, sendo muitos gratuitos;
- Suporte a diversos protocolos de rede, como o TCP/IP, e interfaces de programação, como sockets, podendo ser utilizado como servidor de comunicação, roteador, firewall e Proxy;
- Implementação de sistema de arquivos com uma estrutura bastante simples, onde os arquivos são representados apenas como uma sequência de bytes. Além disso, existem diversas opções para sistemas de arquivos distribuídos, como NFS(Network File System), AFS (Andrew File System) e DFS( Distributed File System);
- Oferece uma interface simples e uniforme com os dispositivos de I/O.
A maior parte do código
do Unix é escrita em C e o restante como device drivers, em assembly
o que possibilita uma grande portabilidade para diferentes
plataformas de hardware. O Unix utiliza a estrutura de camadas para a
construção do sistema, implementando dois modos de acesso, modo
usuário e modo kernel:
Kernel
Kernel é responsável
por controlar o hardware e fornecer as system calls para que os
programas tenham acesso às rotinas do sistema, como criação e
gerencia de processos, gerencia de memória virtual, sistema de
arquivos e gerencia de I/O, assim facilitando o desenvolvimento de
aplicativos, e pode ser dividido em 2 partes: a parte dependente de
hardware e a independente de hardware.
A parte dependente de
hardware consiste nas rotinas de tratamentos de interrupções e
exceções , device drives e interpretação de sinais ou seja todo o
código que deve ser reescrito quando se está portando o sistema
Unix para outra plataforma.
A parte independente de
hardware não tem nenhum vinculo com aparente com a plataforma onde
esta sendo executada, e é responsável pelo tratamento das system
calls, gerência de processos, gerência de memória, escalonamento,
pipes, paginação, swapping e sistema de arquivos.
System calls:
Uma System Call (chamada de sistema) é usado pela aplicação (usuário) programas para solicitação de serviços do sistema operacional. Um sistema operacional pode acessar o hardware de um sistema diretamente, mas um programa do usuário não tem acesso direto ao hardware. Isto é feito para que o kernel possa manter o sistema seguro de programas de usuário mal-intencionado. Mas, muitas vezes, um programa do usuário requer algumas informações do hardware (por exemplo, de uma câmera web para mostrar-lhe a imagem), mas não pode obter as informações diretamente. Assim, solicita ao sistema operacional para
Fornecer-lhe a solicitação. Esta solicitação é feita usando uma chamada de sistema adequada. A chamada de sistema executa no modo kernel. Cada chamada de sistema tem um número associado a ele. Este número é passado para o kernel e é assim que o kernel sabe qual a System Call foi feita. Quando um programa de usuário emite uma chamada de sistema, na realidade, é chamada uma rotina da biblioteca.
Biblioteca padrão
Para cada rotina do
sistema, existe uma biblioteca padrão do Unix que permite esconder
os detalhes da mudança de modo de acesso usuário-kernel-usuário,
A biblioteca implementa uma interface entre os programas e o sistema
operacional, fazendo com que as system calls sejam chamadas.
Processos e threads
O Unix suporta inúmeros
processos, que poder ser executados concorrentemente ou
simultaneamente. As primeiras versões do Unix não implementavam o
conceito de threads, porem versões mais recentes já oferecem algum
tipo de suporte a aplicações multithread.
Um processo é criado
através da system call fork. O processo de executa o fork é chamado
de processo pai, enquanto que o novo processo é chamado de processo
filho ou subprocesso. Cada processo filho tem seu próprio espaço
de endereçamento, independente do processo pai. Apesar de o espaço
de endereçamento dos subprocessos ser independente. Sempre que um
processo é criado, o sistema associa identificadores, que fazem
parte do contexto de software, permitindo implementar mecanismos de
segurança.
A system call fork ,
além de criar o subprocesso, copia o espaço de endereçamento do
processo pai para o filho, incluindo o código executável e suas
variáveis. As versões mais recentes do Unix utilizam a técnica
conhecida como copy-on-write para evitar a duplicação de todo o
espaço de endereçamento do processo pai e o tempo gasto na tarefa.
Quando o sistema é
ativado, o processo 0(zero) é criado, o qual por sua vez cria o
processo 1, conhecido como Init, é o pai de todos os outros
processos que venham a ser ciados pelo sistema.
Processos do sistema
operacional no Unix são chamados de daemons. Os daemons são
responsáveis por tarefas administrativas do sistema, por exemplo,
escalonamento de tarefas (com), gerencia de filas de impressão,
suporte a serviços de rede, suporte a gerencia de memória (swapper)
e gerencia de logs. Os daemons são criados automaticamente durante a
inicialização do sistema.
Processos no Unix podem
se comunicar através de um mecanismo de troca de mensagens,
conhecido como pipe. Outro mecanismo de comunicação entre
processos muito importante no Unix é conhecido como sinal. Um sinal
permite que um processo seja avisado da ocorrência de eventos
síncronos ou assíncronos. Por exemplo, quando o programa executa
uma divisão por zero , o sistema avisa ao processo do programa
através de um sinal. O processador pode aceitar o sinal ou
ignorá-lo. Caso o processo aceite o sinal, é possível especificar
uma rotina de tratamento.
Um processo no Unix é
formado por duas estruturas de dados: estrutura do processo (proc
structure) ea área do usuário (user área ou u área). A estrutura
do processo, que contem o seu contexto de software, deve ficar sempre
residente na memória principal, enquanto a área do usuário pode
ser retirada da memória. Sendo necessária apenas quando o processo
é executado.
Os processos existentes
no sistema são organizados em um vetor, chamado de tabela de
processos, onde cada elemento representa uma estrutura do processo. O
tamanho desse vetor é predefinido e limita o número máximo de
processos no sistema. A estrutura do processo, por sua vez, possui um
ponteiro para a área do usuário. Quando um processo executa um
fork, o sistema procura por um elemento livre na tabela de processos,
onde é criada a estrutura do processo filho, a partir das
informações copiadas da estrutura do processo pai.
Algumas system calls
voltadas para a gerência de processos disponíveis na maioria dos
sistemas Unix.
Gerência do
processador
A gerência do
processador no Unix utiliza dois tipos de escalonamento:
escalonamento circular com prioridades e escalonamentos por
prioridades.
Os processos no Unix
podem ter prioridades entre 0 e 127, e quanto menos o valor maior a
prioridade. Processos executados no modo usuário tem valor de
prioridade entre 50 a 137 (menor prioridade), enquanto os processos
em modo kernel tem prioridade entre 0 e 49 (maior prioridade)
Gerência de memória
As primeiras
versões do Unix utilizavam basicamente a técnica de swapping para a gerência de
memória. Apenas a partir da versão 3BSD, O Unix passou a utilizar a paginação
por demanda. Atualmente, a grande maioria das versões do Unix, tento BSD como
System V, implementam gerencia de memória virtual por paginação com swapping.
Iremos abordar a versão 4BSD.
No Unix, os
conceitos de espaço de endereçamento virtual e mapeamento tem muitos detalhes
de implementação, como tamanho da página, níveis de tabelas de páginas e TLBs,
são dependentes da arquitetura de hardware, podendo variar conforme a versão de
cada sistema.
O
espaço de endereçamento dos processos no Unix é dividido em três segmentos:
texto, dados e pilha. O segmento de texto corresponde a área onde está o código executável dos
programas, sendo uma área protegida contra gravação. O seguimento de texto é
estático e pode ser compartilhado por vários processos, utilizando o esquema de
memória compartilhada. O segmento de dados corresponde as variáveis do
programa, como tipos numéricos, vetores e strings. A área de dados é dinâmica
podendo aumentar ou diminuir durante o processo, como parâmetros passados a um
procedimento ou system call. A pilha cresce dinamicamente do endereço virtual
mais alto para o mais baixo.
O Unix
implementa o esquema de paginação por demanda como política de busca de
páginas. Nesse esquema , páginas do processo são trazidas do disco para a
memória principal apenas quando são referenciadas. O sistema matem uma lista de
páginas livres com todos os frames disponíveis na memória e gerência os frames
de todos os processos em uma lista de páginas em uso. Quando um processo faz
referência a uma página que não se encontra na lista de páginas em uso, ocorre
um Page facult. O sistema identifica se a página está na memória através do bit
de validade. Nesse caso a gerência de memória retira uma página da lista de
páginas livres e transfere para a lista de páginas em uso. O Unix utiliza uma
PL de substituição de política global de páginas.
As páginas de
texto podem ser transferidas sem problemas para a lista de páginas livres, pois
podem ser recuperadas no arquivo executável. Por outro lado, para as páginas de
dados, o sistema utiliza o bit de modificação para verificar se a página foi
modificada. Nesse caso, antes de ser liberada para a lista e páginas livres a
página é gravada em disco.
Em casos onde o
sistema não consegue manter o número suficiente de páginas livres o mecanismo
de swapping é ativado. Nesse caso, o daemon swapper seleciona, inicialmente, os
processos que estão há mais tempo inativos. Em seguida, o swapper seleciona
dente os quatro processos que mais consomem memória principal aquele que
estiver a mais tempo inativo. Esse para cada processo transferido para o disco
é atribuída uma prioridade, calculada em função de vários parâmetros. Em geral,
o processo que esta a mais tempo em disco é selecionado para retornar a memória
principal.
Para controlar
todas as páginas e listas na memória principal, a gerência de memória mantém
uma estrutura de mapeamento dos frames na memória (core map), com informações
sobre todas as páginas livre e em uso. O core map fica residente na parte não
paginável da memória principal, juntamente com o kernel do sistema.
Sistema de arquivos
O sistema de
arquivos foi o primeiro componente s ser desenvolvido no Unix, um arquivo no Unix é simplesmente uma
sequencia de bytes sem significados para o sistema operacional, que desconhece
se o conteúdo do arquivo representa um texto ou um programa executável. O
sistema tem apenas a função de prover o acesso sequencial o aleatório ao
arquivo, ficando a cargo da aplicação a organização de outros métodos de
acesso.
A localização de
um arquivo dentro da estrutura de diretórios é indicada utilizando-se um
pathname, que representa uma sequencia de diretórios separados por barra.
Existem dois tipos de pathname: absoluto e relativo. Um pathname absoluto
indica a localização de um arquivo através de uma sequancia completa de
diretórios e subdiretórios, a partir da raiz do sistema de arquivos. Um
pathname relativo indica a localização de um arquivo do diretório corrente. Por
exemplo o “pathname/usr/maia/livro.txt representa o caminho absoluto para o
arquivo litro.txt
Caso um usuário
esteja posicionado no diretório /usr/machado, basta especificar o caminho
relativo ../maia/livro.txt para ter acesso ao mesmo arquivo.
A tabela a
seguir apresenta algumas systems calls relacionada a gerencia do sistema de
arquivos, envolvendo operações com arquivos e diretórios.
No
Unix não existe uma dependência entre a estrutura lógica do sistema de arquivos
e o local onde os arquivos estão fisicamente armazenados. Dessa forma é
possível criar um sistema de arquivos onde os diretórios e arquivos estão
fisicamente distribuídos em vários discos, porem para o usuário é como se
existisse uma única estrutura lógica de diretórios. Nesse caso, existem padrões
para a implementação de sistemas de arquivos remotos, como Network File System
(NFS), Remote File System (RFS) e Andrew File System (AFS).
Ainda está faltando o sistema de entrada/saída.
fonte: Livro Arquitetura de sistemas operacionais 4ª edição de Francis Berenger Machado e Luiz Paulo Maia
Nenhum comentário:
Postar um comentário