O documento descreve os conceitos básicos de sistemas operacionais, incluindo: 1) O papel do sistema operacional em controlar o acesso aos recursos compartilhados entre usuários e programas; 2) Os serviços prestados pelo sistema operacional como execução de programas, armazenamento de arquivos e acesso a periféricos; 3) A organização do sistema operacional em kernel e programas de sistema.
3. 1.1 Conceito básico
Em torno de um computador existem usuários com problemas
para serem resolvidos, por programas específicos.
Para um melhor aproveitamento do hardware, vários usuários
compartilham simultaneamente o computador.
Os programas podem apresentar necessidades conflitantes, pois
disputam os recursos do equipamento.
Exemplo: disco, memória, impressora.
4. 1.1 Conceito básico
O S.O. é uma camada de software colocada entre o hardware e os programas que
executam tarefas para os usuários.
É responsável pelo acesso aos periféricos; sempre que um programa necessita de
algum tipo de operação de entrada e saída.
Como todos os acessos aos periféricos são feitos através do sistema operacional,
ele pode controlar qual programa está acessando qual recurso.
É possível, então, obter uma distribuição justa e eficiente de recursos.
6. 1.2 Objetivos do sistema operacional
O sistema operacional procura tornar a utilização do computador, ao mesmo
temo, mais eficiente e mais conveniente.
Maior eficiência significa mais trabalho obtido no mesmo hardware, através da
distribuição de seus recursos entre os programas. Exemplo: espaço na memória,
tempo de processador, impressora, espaço em disco, etc.
Maior conveniência significa diminuir o tempo necessário para a construção dos
programas, escondendo-se do programador detalhes do hardware. Exemplo:
tipos de interface, acesso a periféricos, etc.
7. 1.2.1 Tipos de serviços
Execução de programas: o sistema operacional recebe o nome do
arquivo, aloca memória para o programa, copia o conteúdo para a
memória principal e inicia sua execução.
Armazenamento de arquivos: permite a criação, escrita, leitura e
exclusão de arquivos, além de operações como renomear, obter o
tamanho, data de criação e outras informações a seu respeito.
Acesso a periféricos: alocação, leitura, escrita e liberação, além de
obtenção e alteração de informações a seu respeito.
8. 1.2.1 Tipos de serviços
À medida que diversos usuários compartilham o computador,
passa a ser interessante saber quanto de mais recurso cada
usuário necessita.
Pode-se utilizar essa informação para calcular o valor a ser
cobrado pelo uso do computador.
Na busca de um melhor aproveitamento do hardware, diversos
usuários podem compartilhar um computador.
Cabe ao sistema operacional garantir que cada usuário possa
trabalhar sem sofrer interferência danosa dos demais.
9. 1.3 S.O. na visão do usuário
A arquitetura de um sistema operacional corresponde à imagem
que o usuário tem do sistema, a forma como ele percebe o sistema.
Essa imagem é definida pela interface através da qual o usuário
acessa os serviços do sistema operacional.
Essa interface, assim como a imagem, é formada pelas chamadas
de sistemas e pelos programas de sistema.
10. 1.3.1 Chamadas de sistema
Os programas solicitam serviços ao sistema operacional através das chamadas de
sistema.
Elas são semelhantes às chamadas de sub-rotinas, contudo enquanto estas são
transferências para procedimentos normais do programa, as chamadas de
sistema transferem a execução para o sistema operacional.
Através de parâmetros, o programa informa exatamente o que necessita e o
retorno da chamada de sistema, assim como retorno de uma sub-rotina, faz com
que a execução do programa seja retomada a partir da instrução que segue a
chamada. Exemplo: abertura de um arquivo.
11. 1.3.1 Chamadas de sistema
A parte do sistema operacional responsável por implementar as chamadas de
sistema é normalmente chamada de núcleo ou kernel.
Os principais componentes do kernel são a gerência de processador, a gerência
de memória, o sistema de arquivos e a gerência de entrada e saída.
Muitos sistemas operacionais são implementados em camadas, primeiro um
componente de software chamado micronúcleo ou microkernel implementa os
serviços mais básicos associados a sistemas operacionais. Em cima do microkernel,
usando seus serviços, o kernel propriamente dito implementa os demais serviços.
12. 1.3.1 Chamadas de sistema
Figura 1.2: Organização do sistema em kernel e microkernel
13. 1.3.2 Programas de sistema
Os programas de sistema, alguma vezes chamados de utilitários, são programas
normais executados fora do kernel do sistema operacional.
Esses programas implementam tarefas básicas para a utilização do sistema e
muitas vezes são confundidos com o próprio sistema operacional.
Como implementam tarefas essenciais para a utilização do computador, são, em
geral, distribuídos pelo próprio fornecedor do sistema operacional.
Exemplos são os utilitários para manipulação de arquivos: programas para listar
arquivo, imprimir, copiar, renomear, listar conteúdo de diretório, entre outros.
14. 1.3.2 Programas de sistema
O mais importante programa de sistema é o interpretador de
comandos.
Sua tarefa é receber comandos do usuário e executá-los.
Para isso ele recebe as linhas tecladas pelo usuário, analisa seu
conteúdo e executa o comando teclado.
A execução do comando, na maioria das vezes, vai exigir uma ou
mais chamadas de sistema.
Exemplo: listagem de diretório
15. 1.3.2 Programas de sistema
Os mesmos conceitos sobre o interpretador de comandos é igualmente válido
para a situação em que o sistema operacional oferece uma interface gráfica de
usuário (GUI - graphical user interface).
A única diferença está na comodidade para o usuário, que passa a usar ícones,
menus e mouse no lugar de digitar comandos textuais.
Programadores utilizam principalmente editores de texto e compiladores.
Usuários finais utilizam aplicativos e ferramentas de apoio. O sistema operacional
propriamente dito fica escondido, longe da percepção do usuário comum.
16. 1.4 S.O. na visão de projeto
Na visão de projeto, o mais importante é como o sistema está
organizado internamente. A organização de um sistema
operacional corresponde à forma como ele implementa os vários
serviços.
Dois tipos de eventos ativam o sistema operacional: uma chamada
de sistema ou uma interrupção de periférico.
É possível que a chamada de sistema envolva o acesso a um
periférico. Nesse caso, o programa deverá esperar até que o
periférico conclua a operação solicitada.
17. 1.4 S.O. na visão de projeto
Em função das chamadas de sistema, o sistema operacional envia comandos para
os controladores dos periféricos.
O controlador deve informar ao sistema operacional quando a operação estiver
concluída.
Isso é feito por intermédio de uma interrupção, quando o processador para o que
está fazendo e passa a executar uma rotina específica do sistema operacional.
Como a interrupção do periférico avisa o término de alguma operação de entrada
e saída, possivelmente uma chamada de sistema foi concluída. Nesse caso, um
programa à espera de resposta poderá ser liberado.
18. 1.5 Histórico de sistemas operacionais
Na década de 1940 não existia sistema operacional.
O programador também é o operador do computador.
Um programa tem total controle sobre a máquina, e acessa diretamente os
periféricos.
No máximo, existe uma biblioteca com rotinas de entrada e saída já programadas.
Começou-se a utilizar operadores profissionais, assim o programador não mais
opera o computador durante a execução de seu programa. Ele entrega ao
operador o seu job.
19. 1.5 Histórico de sistemas operacionais
Entretanto, o tempo de preparação para a execução de um job
continua grande. É necessário retirar as fitas magnéticas, cartões
de listagem do job que terminou e preparar o próximo.
Para diminuir esse tempo entre jobs, eles passam a ser agrupados
em lotes. Em um mesmo lote, ou batch, são colocados jobs com
necessidades semelhantes.
Essa é a origem do termo sistema em batch.
Um mesmo job pode exigir a execução de vários programas. Cada
uma dessas etapas é chamada de step.
20. 1.5 Histórico de sistemas operacionais
Na década de 1950 surgiram os primeiros monitores residentes. O monitor
residente é um tipo de programa que fica o tempo todo na memória. Quando um
programa em execução termina, ele avisa o monitor que então, carrega
automaticamente o próximo programa e inicia a execução dele.
O monitor residente também é o local indicado para as rotinas de acesso aos
periféricos, e são utilizadas por todos os programas. Desta forma as aplicações
não precisam mais acessar diretamente os periféricos, apenas chamar a rotina
apropriada dentro do monitor.
Esse é o início da ideia de chamada de sistema.
21. 1.5 Histórico de sistemas operacionais
Na década de 1960 surgiu o conceito de multiprogramação.
Em geral, periféricos são dispositivos eletromecânicos e
trabalham na faixa de milissegundo. Ao mesmo tempo, o
processador é um dispositivo eletrônico, que trabalha na faixa de
microssegundo. Por exemplo, enquanto é feito um único acesso à
leitora de cartões, poderiam ser executadas 10.000 instruções de
máquina ou mais.
A solução imaginada foi manter diversos programas na memória
principal ao mesmo tempo. Quando um dos programas está
esperando a conclusão da entrada ou saída, outro programa inicia
sua execução.
22. 1.5 Histórico de sistemas operacionais
Duas inovações de hardware possibilitaram o desenvolvimento da
multiprogramação.
Interrupções: quando um comando é enviado para um periférico,
imediatamente o sistema operacional inicia a execução de outro
programa. É através de uma interrupção que o periférico avisa o
sistema operacional quando o acesso tiver sido concluído. Pode-se
fazer com que o processador fique em um laço, consultando a
interface do periférico, até que a operação esteja concluída.
23. 1.5 Histórico de sistemas operacionais
Discos magnéticos: vários jobs são lidos de cartão perfurado ou
fita magnética para o disco. Como o disco permite acesso direto a
qualquer posição, é possível ler parte do primeiro job e do
segundo job. À medida que, em sua função de execução, um job
solicita a leitura de mais dados, eles são buscados no disco.
Com a utilização de disco magnético, não havia mais a necessidade
de reunir jobs semelhantes em lotes. O termo batch passou então
a designar um sistema no qual não existe interação entre o
usuário e a execução do programa. Mais modernamente o termo
batch foi substituído por "execução em background".
24. 1.5 Histórico de sistemas operacionais
Na década de 1970 ocorreu a disseminação de sistemas
timesharing. Em um ambiente com multiprogramação, diversos
programas dividem o tempo do processador.
Em um ambiente de timesharing, além da multipogramação, cada
usuário possui um terminal onde ele interage com o programa em
execução tendo a sensação de possuir o computador apenas para
seus programas.
25. 1.5 Histórico de sistemas operacionais
Na década de 1980 houve uma enorme disponibilidade de
microcomputadores.
No início, os sistemas operacionais para microcomputadores eram
bastante simples, lembrando até o velho monitor residente.
À medida que o hardware dessas máquinas foi melhorado, o
mesmo aconteceu com o sistema operacional.
26. 1.5 Histórico de sistemas operacionais
A maioria das aplicações comerciais é hoje construída em torno
de bancos de dados. Ainda que a maioria dos sistemas
gerenciadores de bancos de dados sejam implementados fora do
sistema operacional, este deve oferecer algum suporte.
Em um sistema operacional distribuído, vários computadores
estão interconectados por meio de uma rede de comunicação de
algum tipo. É possível, a partir de um dos computadores, acessar
recursos em outros.
27. 1.5 Histórico de sistemas operacionais
Os sistemas operacionais de tempo real, são usados no suporte às aplicações
submetidas a requisitos de natureza temporal. Nesses sistemas, os resultados
devem estar corretos e não somente do ponto de vista lógico, mas também
devem ser gerados no momento correto. Exemplo: lavadoras de roupa, tráfego
aéreo.
À medida que são desenvolvidos computadores com diversos processadores,
passa a ser necessário rever aspectos básicos dos sistemas operacionals. Por
exemplo, agora existe um paralelismo real a ser aproveitado. diversos
programas podem ser executados realmente em paralelo, mas nem todos os
processadores possuem acesso a toda a memória.
28. Bibliografia
OLIVEIRA, R. S. de; CARISSIMI, A. da S. e TOSCANI, S.S. Sistemas
Operacionais. Porto Alegre. Bookman, 2008.
30. 2.1 Mecanismo básico
Em um sistema multiprogramado diversos programas são
mantidos na memória ao mesmo tempo.
A maioria dos programas não precisa de toda a memória do
computador. Muitos programas ocupam uma pequena parcela da
memória principal disponível.
Sem multiprogramação, a memória não ocupada por um programa
ficaria sem utilização.
Com vários programas na memória, esse recurso é mais bem
aproveitado.
32. 2.2 O conceito de processo
Em sistemas operacionais é conveniente diferenciar um programa de sua
execução. Por exemplo, o mesmo programa pode estar sendo executado por
vários usuários ao mesmo tempo.
Na maioria das vezes, um processo é definido como "um programa em
execução".
Um programa é uma sequência de instruções e é passivo dentro do sistema, não
alterando o próprio estado.
O processo é um elemento ativo que altera o seu estado, à medida que executa
um programa. É o processo que faz chamadas de sistema ao executar programas.
33. 2.3 Ciclos de um processo
Processos são criados e destruídos, porém o momento e a forma
com que isso ocorre depende do sistema operacional.
Algum sistemas trabalham com um número fixo de processo,
sendo criados na inicialização do sistema e destruídos quando o
mesmo é desligado.
Outra forma é sua associação com uma sessão de trabalho,
criando processos no momento do acesso do usuário ao sistema e
destruindo-os quando é executada o final da sessão.
34. 2.3 Ciclos de um processo
A forma mais flexível de operação é permitir que os processos
possam ser criados livremente, através de chamadas do sistema.
Além da chamada de sistema "cria processo", serão necessárias
chamadas para "autodestruição do processo"e também para a
"eliminação de outro processo".
A maioria dos processos de um sistema executa programas do
usuário. Entretando alguns podem realizar tarefas de sistemas.
São processos do sistema (daemon).
35. 2.3 Ciclos de um processo
Por exemplo, para evitar conflitos na utilização da impressora, muitos sistemas
trabalham com uma técnica chamada spooling.
Para imprimir um arquivo, o processo de usuário deve colocá-lo em um diretório
especial. Um processo do sistema copia os arquivos desse diretório para a
impressora.
Dessa forma, um processo de usuário nunca precisa esperar a impressora ficar
livre, uma vez que ele não envia os dados para a impressora, mas sim para o disco.
O processo que envia os dados para a impressora não está associado a nenhum
usuário.
36. 2.3 Ciclos de um processo
Após ter sido criado, o processo passa a ocupar o processador. Em determinados
momentos, ele deixa de fazer isso para realizar uma operação de E/S.
Os momentos em que um processo deseja ocupar o processador, são chamados
de ciclos de processador.
Quando o processo está esperando por uma operação de E/S, ele está em
um ciclo de E/S.
A chamada de sistema é o evento que termina o ciclo de processador em
andamento e inicia um ciclo de E/S.
A conclusão da chamada de sistema faz o caminho inverso.
37. 2.3 Ciclos de um processo
Um processo que utiliza muito processador é chamado de cpu-bound.
O seu tempo de execução é definido principalmente pelo
tempo dos seus ciclos de processador.
Por outro lado, um processo que utiliza muita E/S é chamado de
i/o-bound (input/output-bound). Nesse caso, o tempo de execução
é definido principalmente pela duração das operações de E/S.
Não existe uma quantificação precisa para essas definições.
38. 2.4 Relacionamento entre processos
Alguns sistemas suportam o conceito de grupos de processos.
Se processos são criados através de chamada de sistema, pode-se
considerar como pertencentes ao mesmo grupo todos os
processos criados pelo mesmo processo.
O conceito de grupo permite que operações possam ser aplicadas
sobre todo um conjunto de processos, e não apenas sobre
processos individuais.
Por exemplo, os processos pertencentes a um mesmo grupo
podem compartilhar os mesmos direitos perante o sistema.
39. 2.4 Relacionamento entre processos
Em muitos sistemas os processos são criados por outros
processos, pelas chamadas de sistema. Nesse caso, é possível
definir uma hierarquia de processos.
O processo que faz a chamada de sistema é chamado de processo
pai, enquanto o processo criado é chamado de processo filho.
Um mesmo processo pai pode estar associado a vários processos
filhos. Os processos filhos, por sua vez, podem criar outros
processos.
41. 2.4 Relacionamento entre processos
À medida que processos são criados e destruídos, nodos são
acrescentados ou removidos da árvore, respectivamente.
O sistema pode definir, por exemplo, o que fazer quando um processo
com filhos é destruído. Pode-se definir que, quando um processo é
destruído, todos os processos que derivam dele também são destruídos.
Outra solução é manter o nodo que representa o processo destruído, até
que todos os seus descendentes também terminem.
Uma terceira solução é vincular os processos que são filhos do processo
destruído com o processo pai daquele, isto é, com o "processo avô" deles.
42. 2.5 Estados de um processo
Em máquinas multiprocessadoras existem diversos
processadores. Nesse caso, diversos processos executam ao
mesmo tempo. Porém, essa não é a situação mais comum.
Vamos supor que existe um único processador no computador.
Nesse caso é necessário manter uma fila com os processos aptos a
ganhar o processador.
Essa fila é chamada "fila de aptos" (ready queue).
43. 2.5 Estados de um processo
A figura 2.3 ilustra essa situação.
O processo 1 ocupa o processador, enquanto os processos 2 e 3 esperam na fila
de aptos.
Os processos na fila do processador estão em estado de apto (ready).
Um único processo ocupa o processador a cada instante.
O processo que ocupa o processador está no estado executando (running).
Na figura, o processo 1 está no estado executando, enquanto os processos 2 e 3
estão no estado apto.
44. 2.5 Estados de um processo
Figura 2.3: Fila de processos esperando pelo processador
45. 2.5 Estados de um processo
A figura 2.4 mostra o diagrama de estados de um processo.
No estado executando, um processo pode fazer chamadas de
sistema.
Até a chamada de sistema ser atendida, o processo não pode
continuar sua execução. Ele fica bloqueado e só volta a disputar o
processador após a conclusão da chamada.
Enquanto espera pelo término da chamada de sistema, o processo
está no estado bloqueado (blocked).
46. 2.5 Estados de um processo
Figura 2.4: Diagrama de estados de um processo
47. 2.5 Estados de um processo
A mudança de estado de qualquer processo é iniciada por um evento. Esse evento
aciona o sistema operacional, que, então, altera o estado de um ou mais
processos.
A transição de estado executando para bloqueado é feita através de uma
chamada de sistema.
Ele fica bloqueado até o atendimento e, com isso, o processador fica livre. O
sistema operacional então seleciona um processo na fila de aptos para receber o
processador e altera seu estado para executando.
O módulo do sistema operacional que faz essa seleção é chamado escalonador
(scheduler).
48. 2.5 Estados de um processo
Algumas chamadas de sistema são muito rápidas. Por exemplo, a
leitura da hora atual.
Não existe acesso a periférico, mas apenas consulta à variáveis do
próprio sistema operacional.
Nesse caso, o processo não precisa voltar para a fila de aptos: ele
simplesmente retorna para a execução após a conclusão de
chamada, o que implica um caminho do estado bloqueado para o
estado executando.
49. 2.5 Estados de um processo
Muitos sistemas procuram evitar que um único processo
monopolize a ocupação do processador.
E um processo está há muito tempo no processador, ele volta para
o fim da fila de aptos.
Um novo processo da fila de aptos ganha o processador e assim
cada processo tem a chance de executar um pouco.
Esse mecanismo cria um caminho entre o estado executando e o
estado apto (a figura 2.5 mostra o grafo de estados dos processos
com esses novos caminhos).
50. 2.5 Estados de um processo
Figura 2.5: Novo diagrama de estados de um processo
51. 2.6 Gerência de filas
O tempo de acesso a um periférico é muito grande se comparado
aos tempos de processador.
Se houver mais de uma solicitação for para o mesmo periférico,
não é possível enviar o comando imediatamente, pois a maioria dos
controladores de periféricos não suporta dois comandos
simultâneos.
O segundo processo terá que esperar o periférico ficar livre.
De qualquer maneira, o processador ficou livre; um terceiro
processo será retirado da fila de aptos e passará a ocupar o
processador.
52. 2.6 Gerência de filas
Quando uma solicitação é feita, é preciso verificar a fila do
periférico.
Se ela estiver vazia, o periférico está livre. O pedido é inserido
na fila, e o comando é enviado para o controlador.
Caso contrário, o periférico está ocupado e o pedido é
inserido na fila, mas nada é enviado ao controlador.
53. 2.6 Gerência de filas
A figura 2.6 ilustra um momento específico dentro do sistema.
● O processo 1 está executando. Na fila de aptos, esperando pelo
processador, estão os processos 2 e 3.
● A impressora está livre.
● Existe um acesso em andamento na unidade de disco 0, feito pelo processo
4.
● O processo 5 também solicitou um acesso à unidade 0, mas deve esperar a
conclusão do pedido em andamento.
● Os processos 4 e 5 estão bloqueados, ou seja, não disputam processador.
● A unidade de disco 1 está sendo acessada em função de um pedido do
processo 6.
54. 2.6 Gerência de filas
Figura 2.6: Filas do sistema operacional
55. 2.7 Mecanismo de interrupções
O mecanismo de interrupções é um recurso comum dos
processadores de qualquer porte. Ele permite que um controlador
de periférico chame a atenção do processador.
Analogia entre as interrupções de hardware e o telefone.
Uma interrupção sempre sinaliza a ocorrência de algum evento.
Quando ela acontece, desvia a execução da posição atual de
programa para uma rotina específica.
Essa rotina, responsável por atender a interrupção, é chamada
de tratador de interrupção.
56. 2.7 Mecanismo de interrupções
Para que a execução do programa interrompido não seja comprometida pela
interrupção, é necessário que nenhum registrador seja alterado.
Alguns processadores salvam automaticamente todos os registradores quando
ocorre uma interrupção; outros, salvam apenas alguns, cabendo à rotina que
atende à interrupção salvar os demais registradores.
O local mais indicado é a pilha de execução. É usual o processador dispor de uma
instrução tipo retorno de interrupção que repõe o conteúdo original dos
registradores e faz o processador retomar a execução do programa interrompido.
57. 2.7 Mecanismo de interrupções
A função básica de um controlador de periférico é conectar o dispositivo em
questão com o processador.
Através do barramento, o processador é capaz de realizar operações do tipo "lê
dados", "escreve dados", "reinicializa", "lê status" e "escreve comando".
O controlador é responsável por traduzir essas operações em uma sequência de
acionamentos eletrônicos, elétricos e mecânicos capazes de realizar a operação
solicitada.
Para isso, o controlador deve saber como o periférico funciona. Daí resulta que
cada tipo de periférico necessita de um controlador diferente.
58. 2.7 Mecanismo de interrupções
A figura 2.7 mostra o diagrama de tempo resultante quando
interrupções são empregadas para implementar E/S.
Após enviar o comando para o controlador, o processador segue a
execução do programa.
Quando a operação é concluída, o controlador gera uma
interrupção.
O processador, então, lê os resultados do controlador.
59. 2.7 Mecanismo de interrupções
Figura 2.7: Linha de tempo quando interrupção é usada para implementar E/S
60. 2.7 Mecanismo de interrupções
A forma mais simples de identificar a origem de uma interrupção é
associar a cada controlador um tipo diferente de interrupção.
Dessa forma, o controlador não somente interrompe o
processador, mas também informa qual o tipo de interrupção.
A maioria dos processadores admite diversos tipos de
interrupções. Cada tipo de interrupção é identificado por um
número. Por exemplo, de 0 (zero) a 255.
61. 2.7 Mecanismo de interrupções
Existem momentos em que um programa não pode ser interrompido. Por
exemplo, o programa pode estar alterando variáveis que também são acessadas
pelo tratador de interrupções.
A solução para esse problema é desligar o mecanismo de interrupções
temporariamente, enquanto o programa realiza uma tarefa crítica que não pode
ser interrompida.
Os processadores normalmente possuem instruções para habilitar e desabilitar
interrupções.
Enquanto as interrupções estiverem desabilitadas, elas são ignoradas pelo
processador. Elas não são perdidas, apenas ficam pendentes.
62. 2.7 Mecanismo de interrupções
É comum a existência de uma relação de prioridades entre os
diferentes tipos de interrupções.
Vamos supor que um dado processador atribui prioridade
decrescente do tipo 0 até o tipo 255. Nesse caso, quando ocorre
uma interrupção tipo 10, o processador automaticamente
desabilita interrupções dos tipos 10 a 255 até que o atendimento
da interrupção tipo 10 tenha sido concluído.
Caso ocorra, durante esse intervalo de tempo, uma interrupção do
tipo 5, ela é imediatamente reconhecida pelo processador. Assim,
o tratador de interrupção tipo 10 é interrompido e o tratador de
interrupções tipo 5 ativado.
63. 2.7 Mecanismo de interrupções
Figura 2.8: Ativação em cascata de tratadores de interrupção
64. 2.7 Mecanismo de interrupções
O endereço de um tratador de interrupção é chamado de vetor de
interrupção que "aponta" para a rotina de atendimento da mesma.
Em geral, existe uma tabela na memória com todos os vetores de
interrupção, ou seja, com os endereços das rotinas responsáveis
por tratar os respectivos tipos de interrupção.
A ocorrência de uma interrupção dispara no processador
uma sequência de atendimento.
Toda a sequência é executada pelo hardware, comandada pela
unidade de controle do processador.
65. 2.7 Mecanismo de interrupções
Figura 2.9: Tabela dos vetores de interrupção
66. 2.7 Mecanismo de interrupções
Interrupções de software (traps) são causadas pela execução de
uma instrução específica para isso, tendo como parâmetro o
número da interrupção que deve ser ativada.
O uso mais comum para interrupções de software é a
implementação das chamadas de sistema, por meio das quais os
programas de usuário solicitam serviços ao sistema operacional.
O endereço armazenado nas tabelas de vetores de interrupção
deve mudar conforme a versão do sistema operacional, que na sua
inicialização fica encarregado de colocar os endereços certos na
tabela.
67. 2.7 Mecanismo de interrupções
As interrupções por erro, ou interrupções de exceção
acontecem quando o processador detecta algum tipo de
erro na execução do programa, como por exemplo, uma
divisão por zero ou o acesso a uma posição de memória que
na verdade não existe.
O procedimento de atendimento a essa classe de
interrupção é igual ao descrito anteriormente.
68. 2.8 Proteção entre processos
Na multiprogramação, diversos processos compartilham o
computador.
É necessário que o sistema operacional ofereça proteção aos
processos e garanta a utilização correta do sistema. Por
exemplo, um processo de usuário não pode formatar o disco.
Também não se pode permitir que um processo entre em um
laço infinito e, com isso, monopolize a utilização do
processador.
69. 2.8.1 Modos de operação do processador
O sistema operacional é responsável por implementar uma proteção
apropriada para o sistema e para isso, é necessário o auxílio do processador
(hardware).
A forma usual é definir dois modos de operação:
1. Modo usuário: algumas instruções não podem ser executadas.
2. Modo supervisor: não existem restrições, e qualquer instrução pode ser
executada. Essas instruções são chamadas privilegiadas.
Se um processo de usuário tentar executar uma instrução privilegiada,
o hardware automaticamente gera uma interrupção e aciona o sistema
operacional que poderá abortar o processo.
70. 2.8.2 Proteção dos periféricos
Para proteger os periféricos, as instruções de E/S são tornadas privilegiadas.
A única forma de o processo de usuário realizar uma operação de E/S é
através de uma chamada de sistema.
Muitas arquiteturas oferecem uma instrução chamada de interrupção de
software ou trap, que quando executada, apresenta um efeito semelhante
ao de uma interrupção por hardware, a única diferença sendo o fato de ter
sido causada pelo software e não por um evento externo vinculado
ao hardware.
As interrupções geradas por software também chaveiam o processador para
o modo supervisor.
71. 2.8.2 Proteção de periféricos
Figura 2.10: Modos de operação do processador
72. 2.8.3 Proteção da memória
Para implementar a proteção de memória, o sistema operacional também
necessita de auxílio da arquitetura.
Sempre que o sistema operacional vai disparar um processo de usuário, ele
carrega nos registradores de limite os valores relativos ao processo que vai
executar.
Ele coloca no registrador limite inferior o endereço do primeiro byte pertencente
à área de trabalho do processo e no registrador limite superior é colocado o
endereço do último byte válido para a sua área.
A cada acesso à memória, o hardware de proteção compara o endereço gerado
pelo processador com o conteúdo dos dois registradores limite e se estiver fora
da área do usuário, é gerada uma interrupção.
73. 2.8.3 Proteção da memória
Figura 2.11: Proteção de memória com registradores de limite
74. 2.8.3 Proteção da memória
Algumas arquiteturas fazem o acesso aos periféricos através de posições
específicas da memória. Essa técnica é chamada de E/S mapeada na
memória.
Nesse caso, a proteção da memória também implementa a proteção dos
periféricos. Basta colocar os endereços dos periféricos fora dos limites da
área do processo. O processo não será capaz de acessar o periférico sem
gerar uma interrupção.
Obviamente, o acesso aos registradores de limite deve ser feito através
de instruções privilegiadas. Somente o sistema operacional pode alterar
o seu conteúdo.
75. 2.8.3 Proteção da memória
Para evitar que um único processo de usuário monopolize a utilização do
processador, é empregado um temporizador (timer), que é um relógio
de tempo real, implementado pelo hardware, que gera interrupções de
tempos em tempos.
As interrupções do temporizador ativam o sistema operacional que então
verifica se o processo executado já está há muito tempo com o
processador.
Nesse caso, o sistema pode abortar o processo por exceder o limite de
tempo de execução.
O controle do temporizador deve ser feito através de instruções
privilegiadas.
76. 2.8.3 Proteção da memória
Figura 2.12: Hardware para verificação dos endereços
77. 2.8.3 Proteção da memória
Muitas arquiteturas não definem apenas dois modos de operação,
mas vários.
Em cada modo de operação, também chamado de nível de
proteção, algumas operações não são permitidas.
Quanto mais confiável o software, mais direitos ele recebe.
Com auxílio do hardware e um sistema operacional sem falhas, é
possível construir sistemas seguros, ou seja, sistemas nos quais não
ocorram interferências danosas entre usuários.
78. Bibliografia
OLIVEIRA, R. S. de; CARISSIMI, A. da S. e TOSCANI, S.S.
Sistemas Operacionais. Porto Alegre. Bookman, 2008.
80. 3. Programação concorrente
Um programa que é executado por apenas um processo é chamado de
programa sequencial. Nesse caso, existem somente um fluxo de
controle durante a execução.
Um programa concorrente é executado simultaneamente por diversos
processos que cooperam entre si, isso é, trocam informações, o que
significa trocar dados ou realizar algum tipo de sincronização. É
necessária a existência de interação entre processos para que o
programa seja considerado concorrente.
O termo "programação concorrente" vem do inglês concurrent
programming, onde concurrent significa "acontecendo ao mesmo tempo"
ou concomitantemente.
81. 3.1 Motivação
Um programa concorrente pode apresentar todos os tipos de erros que
normalmente aparecem em programas sequenciais. Além disso, existem
os erros associados com as interações entre os processos.
Mesmo com todas as suas complexidades inerentes, existem muitas
áreas nas quais a programação concorrente é útil.
Considere um programa que deve ler registros de um arquivo, colocar
em um formato apropriado e então enviar para uma impressora física.
84. 3.1.1 Programa sequencial
Inicialmente, o processo envia um comando para a leitura do arquivo e
fica bloqueado, o disco então é acionado para realizar a operação de
leitura.
Uma vez concluída a leitura, o processo realiza a formatação e inicia
a transferência dos dados para a impressora.
Observe o diagrama da figura 3.2, o disco e a impressora nunca
trabalham simultaneamente, embora não exista nenhuma limitação de
natureza eletrônica. O programa sequencial é que não consegue ocupar
ambos.
87. 3.1.2 Programa concorrente
O programa concorrente é mais eficiente, pois consegue manter o disco e a
impressora trabalhando simultaneamente.
O tempo total para realizar a impressão do arquivo é menor quando a solução
concorrente é empregada.
Se o processo Leitor for sempre mais rápido, o buffer ficará cheio, e então o
processo Leitor terá que esperar até que o processo impressor retire algo do
buffer.
Por outro lado, se o processo impressor for sempre mais rápido, eventualmente
o buffer ficará vazio e ele terá que esperar pelo processo leitor.
88. 3.2 Paralelismo
Na verdade, a maior motivação para a programação concorrente é a engenharia
de software.
Aplicações inerentemente paralelas são mais facilmente construídas se
programação concorrente é utilizada.
Estão enquadrados nesse grupo, aplicações envolvendo protocolos de
comunicação, aplicações de supervisão e controle industrial, e como era de se
esperar, a própria construção de um sistema operacional.
89. 3.2 Paralelismo
A figura 3.5 ilustra uma rede local na qual existem diversos computadores
pessoais utilizados pelos usuários e existe um computador dedicado ao papel
de servidor de impressão na rede.
O programa "servidor de impressão" deve: receber mensagens pela rede;
escrever em disco os pedaços de arquivos recebidos; enviar mensagens pela
rede contendo, por exemplo, resposta às consultas sobre seu estado; ler
arquivos previamente recebidos; enviar dados para a impressora.
Todas essas atividades devem ser realizadas simultaneamente.
91. 3.2 Paralelismo
A figura 3.6 mostra uma das possíveis soluções para a organização interna do
programa concorrente "servidor de impressão".
Cada círculo representa um processo.
Cada flecha representa a passagem de dados de um processo para o outro.
Essa passagem de dados pode ser feita, por exemplo, através de variáveis que
são compartilhadas pelos processos envolvidos na comunicação.
93. 3.2 Especificação do paralelismo
É poissível especificar paralelimos através de comandos:
● create_process: permite a criação de um segundo fluxo de execução,
paralelo àquele que executou o comando.
● exit: o fluxo de controle que o executa é imediatamente terminado.
● wait_process: permite que um fluxo de execução espere outro fluxo
terminar.
94. 3.2 Especificação do paralelismo
Figura 3.7: Exemplo contendo os comandos create_process, exit e wait_process
95. 3.2 Especificação do paralelismo
É importante observar que processos paralelos podem executar em qualquer
ordem. Algumas possíveis saídas:
Alo do pai
Alo do filho
Alo do filho
Filho 1 morreu
Filho 2 morreu
Alo do pai
Alo do filho
Filho 1 morreu
Alo do filho
Filho 2 morreu
96. 3.2 Especificação do paralelismo
Figura 3.8: Diagrama de tempo associada com o programa da figura 3.7
97. 3.2 Especificação do paralelismo
Figura 3.9: Diagrama de tempo associada com o programa da figura 3.7
98. 3.2 Especificação do paralelismo
Figura 3.10: Grafo de precedência para o programa da figura 3.7
99. 3.2 Especificação do paralelismo
Muitas vezes são usados grafos de precedência para representar o paralelismo
existente em um programa. No grafo de precedência, os nodos representam
trechos de código e os arcos representam relações de precedência.
Um arco no nodo X para o nodo Y representa que o código associado com Y
somente poderá ser executado após o término do código associado com X.
Vamos supor agora que o programador deseje que, necessariamente, o
processo do filho 1 termine para então o processo filho 2 iniciar.
101. 3.2 Especificação do paralelismo
Uma forma mais estruturada de especificar paralelismo em programas
concorrentes é conseguida com o uso dos comandos Parbegin e Parend.
Enquanto o par Begin-End delimita um conjunto de comandos que serão
executados sequencialmente, o par Parbegin-Parend delimita um conjunto de
comandos que serão executados em paralelo.
O comando que segue ao Parend somente será executado quando todos os
fluxos de controle criados na execução do Parbegin-Parend tiverem terminado.
102. 3.2 Especificação do paralelismo
Os comandos Parbegin-Parend definem uma nova estrutura de controle para a
linguagem. Nos exemplos, a sintaxe da linguagem C foi estendida com a inclusão
desse novo comando.
Também é possível usar uma versão menos elegante para o comando Parbegin
que, entretanto, mantém sua funcionalidade.
Dessa vez, Parbegin aparece como uma função de biblioteca cujos parâmetros
são os nomes das funções a serem disparadas em paralelo.
103. 3.2 Especificação do paralelismo
Figura 3.12: Exemplo contendo os comandos Parbegin e Parend
104. 3.3 Problema da seção crítica
Uma forma de implementar a passagem de dados de um processo para o outro
são variáveis compartilhadas pelos processos envolvidos na comunicação. A
passagem acontece quando um processo escreve em uma variável que será lida
por outro processo.
A quantidade exata de memória compartilhada entre os processos pode variar
conforme o programa. Processos podem compartilhar todo o seu espaço de
endereçamento, apenas um segmento de memória, algumas estruturas de
dados ou algumas variáveis.
O sistema operacional arranja para que os processos acessem as mesmas
posições de memória.
105. 3.3 Problema de seção crítica
Figura 3.13: Compartilhamento de memória
106. 3.3 Problema da seção crítica
Não é possível eliminar as variáveis compartilhadas de um programa concorrente
quando elas são o mecanismo de comunicação entre os processos.
A solução está em controlar o acesso dos processos e suas variáveis
compartilhadas, de modo a garantir que um processo não acesse uma estrutura
de dados enquanto essa estiver sendo utilizada por outro processo.
A parte do código de um processo que acessa uma estrutura de dados
compartilhada é chamada de seção crítica.
107. 3.3 Problema da seção crítica
Uma solução para o problema da seção crítica estará correta quando apresentar
as seguintes propriedades:
● Existe exclusividade mútua entre os processos com referência na execução
das respectivas seções críticas.
● Quando um processo P deseja entrar na seção crítica e nenhum outro
processo está executando a sua seção crítica, o processo P não é impedido de
entrar.
● Nenhum processo pode ter seu ingresso na seção crítica postergado
indefinidamente, ou seja, ficar esperando para sempre.
● Não depender da velocidade relativa da execução dos processos, nem da
quantidade de processadores (cores) existentes.
108. 3.4 Mecanismos básicos de exclusão mútua
Tipicamente, uma solução para o problema da seção crítica tem a forma de um
mecanismo que controla o acesso dos processos ao código da seção crítica.
Através de primitivas específicas alocadas imediatamente antes (entrada) e
imediatamente depois (saída) da seção crítica, esse mecanismo age de maneira a
obter-se as quatro propriedades citadas anteriormente (ou, pelo menos, a
maioria delas).
109. 3.4.1 Soluções em software puro
Dentro da categoria dos protocolos de software puro, os mais famosos são os
algoritmos de Dekker e de Peterson.
Nessas soluções os processos executam um determinado algoritmo na entrada
e outro na saída da seção critica.
Tais algoritmos não incluem nenhuma chamada ao sistema operacional, nem o
emprego de instruções privilegiadas.
110. 3.4.1 Soluções em software puro
Figura 3.18: Protocolo de software puro: solução de Peterson
111. 3.4.1 Soluções em software puro
A variável flag é um array com duas posições, cada uma indica quando o
respectivo processo deseja entrar na seção crítica (valor 1 indica "quero entrar").
A variável turn contem o número do processo com a preferência no momento.
O processo P0 poderá entrar na seção crítica quando P1 não deseja entrar na
seção crítica ou quando a preferência no momento é para P0.
Embora o algoritmo apresentado funcione apenas para dois processos, ele pode
ser extendido para o caso de muitos processos.
112. 3.4.1 Soluções em software puro
Soluções em software puro não são muito empregados na pratica por duas
razões:
1. são bastante complexas, o que dificulta a depuração dos problemas;
2. apresentam a propriedade chamada busy-waiting, quando um processo
aguarda em um laço a sinalização de um evento.
113. 3.4.2 Desabilitação de interrupções
Através desta solução simples, toda vez que um processo vai acessar variáveis
compartilhadas antes ele desabilita interrupções.
Dessa forma, ele pode acessar as variáveis com a certeza de que nenhum outro
processo vai ganhar o processador, dado que as interrupções (timer, disco, etc.)
que deflagram o escalonador.
No final da seção crítica, ele torna a habilitar as interrupções.
Esse esquema é efetivamente usado nas aplicações que executam em sistemas
pequenos e dedicados, como sistemas embarcados (embedded systems).
114. 3.4.2 Desabilitação de interrupções
Desabilitar interrupções vai contra os mecanismos de proteção e não pode ser
considerado um método genérico para resolver o problema da seção crítica.
Essa é uma operação proibida para processos de usuário em sistemas de
propósito geral já que são instruções que só podem ser executadas em modo
privilegiado.
Desabilitar interrupções também diminui a eficiência do sistema à medida que
periféricos não são atendidos imediatamente durante as execuções de seções
críticas (interrupções ficam pendentes e são atendidas somente após a seção
crítica).
115. 3.4.3 Spin-lock
Essa solução é baseada em uma instrução de máquina chamada "test-and-set",
embora uma instrução do tipo "swap" ou "compare on store" possa ser usada
também.
A seção crítica será protegida por uma variável que ocupará a posição da
memória. Essa variável é normalmente chamada de lock (fechadura).
Quando lock contém "0", a seção crítica está livre. Quando lock contém "1", ela
está ocupada. A variável é inicializada com "0".
Antes de entrar na seção crítica, um processo precisa "fechar a porta",
colocando "1" em lock. Entretanto ele só pode fazer isso se "a porta estiver
aberta".
116. 3.5 Mutex
O nome mutex é derivado de "mutual exclusion" (exclusão mútua).
Uma variável mutex pode assumir apenas os valores livre e ocupado.
A operação lock é usada pelo processo para solicitar acesso à seção crítica
(entrada);
A operação unlock permite ao processo informar que não deseja mais usar a
seção crítica (saída).
117. 3.5.1 Implementação de mutex
No caso de computadores com um único processador, a solução mais comum é
desabilitar interrupções.
Para computadores com vários processadores, desabilitar interrupções não
basta.
Nesse caso, o spin-lock é usado, pois ele impede que um outro processo,
executando em outro processador, execute a operação lock ou unlock sobre o
mesmo mutex.
118. 3.6 Semáforos
Podemos sintetizar o funcionamento das operações P e V sobre um semáforo S
da seguinte forma:
P (S):
S.valor = S.valor - 1;
Se S.valor < 0
Então bloqueia o processo, insere em S.fila
V (S):
S.valor = S.valor + 1;
Se S.fila não está vazia
Então retira processo P de S.fila, acorda P
119. 3.6 Semáforos
Para que semáforos funcionem corretamente, é essencial que as operações P e
V sejam atômicas. Isso é, uma operação P ou V não pode ser interrompida no
meio e outra operação sobre o mesmo semáforo iniciada.
Semáforos tornam a proteção da seção crítica muito simples.
Para cada estrutura de dados compartilhada, deve ser criado um semáforo S
inicializado com o valor 1.
Todo processo, antes de acessar essa estrutura, deve executar um P(S), ou seja,
a operação P sobre o semáforo S associado com a estrutura de dados em
questão. Ao sair da seção crítica, o processo executa V(S).
120. Bibliografia
OLIVEIRA, R. S. de; CARISSIMI, A. da S. e TOSCANI, S.S.
Sistemas Operacionais. Porto Alegre. Bookman, 2008.
122. 4.1 Introdução
Historicamente, a memória principal sempre foi vista como um recurso escasso e
caro.
Uma das maiores preocupações dos projetistas foi desenvolver Sistemas
Operacionais que não ocupassem muito espaço de memória e, ao mesmo tempo,
otimizassem a utilização dos recursos computacionais.
Mesmo atualmente, com a redução de custo e consequente aumento da capacidade
da memória principal, seu gerenciamento é um dos fatores mais importantes no
projeto de Sistemas Operacionais.
Enquanto nos sistemas monoprogramáveis a gerência da memória não é muito
complexa, nos sistemas multiprogramáveis essa gerência se torna crítica, devido à
necessidade de se maximizar o número de usuários e aplicações utilizando
eficientemente o espaço da memória principal.
123. 4.1.1 Funções básicas
Em geral programas são armazenados em memórias secundárias, como
discos ou fitas, por ser um meio não-volátil, abundante e de baixo custo.
Como o processador somente executa instruções localizadas na memória
principal, o Sistema Operacional deve sempre transferir programas da
memória secundária para a memória principal antes deles serem executados.
Como o tempo de acesso à memória secundária é muito superior ao tempo de
acesso à memória principal, o Sistema Operacional deve buscar reduzir o
número de operações de E/S à memória secundária, para evitar problemas de
desempenho do sistema.
A gerência de memória deve tentar manter na memória principal o maior
número possível de processos residentes, permitindo maximizar o
compartilhamento do processador e demais recursos computacionais.
124. 4.1.1 Funções básicas
Mesmo na ausência de espaço livre, o sistema deve permitir que novos processos sejam
aceitos e executados. Isto é possível através da transferência temporária de processos
residentes na memória principal para a memória secundária, liberando espaço para novos
processos. Este mecanismo é conhecido como swapping.
Outra preocupação na gerência de memória é permitir a execução de programas que
sejam maiores que a memória física disponível, implementando técnicas como overlay
e memória virtual.
Em um ambiente de multiprogramação, o sistema operacional deve proteger as áreas de
memória ocupadas por cada processo, além da área onde reside o próprio sistema.
Caso um programa tente realizar algum acesso indevido à memória, o sistema de alguma
forma deve impedí-lo.
Apesar de a gerência de memória garantir a proteção de áreas da memória, mecanismos de
compartilhamento devem ser oferecidos para que diferentes processos possam trocar
dados de forma protegida.
126. 4.2.1 Alocação Contígua Simples
Foi implementada nos primeiros Sistemas Operacionais, porém ainda
está presente em alguns sistemas monoprogramáveis.
Nesse tipo de organização, a memória principal é subdividida em duas
áreas: uma para o sistema operacional e outra para o programa do
usuário.
Dessa forma, o programador deve desenvolver suas aplicações,
preocupado, apenas, em não ultrapassar o espaço de memória
disponível, ou seja, a diferença entre o tamanho total da memória
principal e área ocupada pelo Sistema Operacional.
128. 4.2.1 Alocação Contígua Simples
Esquema em que o usuário tem controle sobre toda a
memória principal, inclusive a área do Sistema Operacional.
Implementa controle de proteção do sistema através de
registrador que delimita a área do Sistema Operacional.
Fácil implementação e código reduzido, porém não utiliza os
recursos computacionais de forma eficiente, pois apenas um
usuário/aplicação pode dispor deste recurso.
129. 4.2.2 Técnica Overlay
Na alocação contígua simples, todos os programas estão
limitados ao tamanho da área de memória principal disponível
para o usuário.
Uma solução encontrada para o problema é dividir o programa
em módulos, de forma que seja possível a execução
independente de cada módulo, utilizando uma mesma área de
memória. Essa técnica é chamada de overlay.
131. 4.2.2 Técnica Overlay
A técnica de overlay utiliza uma área de memória comum, os os
módulos “não-carregados” poderão compartilhar esta área de
memória (área de overlay).
Sempre que um módulo “não-carregado” for referenciado
pelo módulo principal, o módulo será carregado da memória
secundária para a área de overlay.
No caso de uma referência a um módulo já carregado, a carga
não será realizada.
132. 4.2.2 Técnica Overlay
A definição das áreas de overlay é função do programador, através de
comandos específicos das linguagem de programação utilizada.
O tamanho da área de overlay é estabelecido a partir do tamanho
do maior módulo.
Esta técnica tem a vantagem de permitir ao programador expandir os
limites da memória principal, porém deve ser utilizada com cuidado,
pois pode trazer sérios problemas de desempenho, devido a
possibilidade de transferência excessiva dos módulos entre a memória
principal e a secundária.
133. 4.2.3 Alocação Contígua Particionada
Os Sistemas Operacionais evoluíram no sentido de proporcionar
melhor aproveitamento dos recursos disponíveis.
Nos sistemas monoprogramáveis, o processador permace grande
parte do tempo ocioso e a memória principal é subutilizada.
Os sistemas multiprogramáveis já são muito mais eficientes no uso
do processador, necessitando assim, que diversos programas estejam na
memória principal ao mesmo tempo e que novas formas de gerência da
memória sejam implementadas.
134. 4.2.4 Alocação Contígua Particionada Fixa
Nos primeiros sistemas multiprogramáveis, a memória era dividida
em pedaços de tamanho fixo, chamados partições.
O tamanho das partições, estabelecido na fase de inicialização do
sistema, era definido em função do tamanho dos programas
que executariam no ambiente.
Sempre que fossem necessárias alterações do tamanho de uma
partição, o sistema deveria ser reinicializado com a nova
configuração.
136. 4.2.4 Alocação Contígua Particionada Fixa
Inicialmente, os programas só podiam ser carregados e executados em
apenas uma partição específica, mesmo se outras estivessem disponíveis.
Esta limitação se devia aos compiladores e montadores, que geravam
apenas código absoluto.
No exemplo acima, supondo que os programas A e B estivessem sendo
executados, os programas C e E não poderiam ser processados na terceira
partição, mesmo esta estando livre.
A esse tipo de gerência chamou-se alocação particionada estática absoluta.
137. 4.2.4 Alocação Contígua Particionada Fixa
Com a evolução dos compiladores, montadores, ligadores e
carregadores, o código gerado deixou de ser absoluto e passou a
ser realocável.
No código realocável, todas as referências a endereços no
programa são relativas ao início do código e não a
endereços físicos de memória.
Desta forma, os programas puderam ser executados a partir de
qualquer partição.
139. 4.2.4 Alocação Contígua Particionada Fixa
Supondo que na partição 1 esteja o programa C, na partição 2 o
programa A e na partição 3 o programa B.
Caso os programas A e B terminassem, o programa E poderia ser
executado tanto na partição 2 quanto na partição 3.
Para manter o controle sobre as partições alocadas, a
gerência de memória mantém uma tabela com o endereço inicial
de cada partição, seu tamanho, e se está em uso ou não.
141. 4.2.4 Alocação Contígua Particionada Fixa
A esse tipo de gerência chamou-se alocação particionada estática
relocável.
Neste esquema de memória, a proteção baseia-se em dois
registradores, que indicam os limites (inferior e superior) da
partição onde o programa está sendo executado.
143. 4.2.4 Alocação Contígua Particionada Fixa
Tanto nos sistemas de alocação absoluta quanto nos de
alocação realocável, os programas, normalmente, não
preenchem totalmente as partições onde são carregados,
deixando área de memória livre.
Este problema é conhecido como fragmentação interna.
Exemplo de implementação: OS/MFT (Multiprogramming with
Fixed Number of Tasks) da IBM
144. 4.2.5 Alocação Contígua Particionada Dinâmica
Na alocação particionada dinâmica ou variável, foi eliminado o conceito de
partições de tamanho fixo.
Nesse esquema, cada programa utilizaria o espaço necessário, tornando essa
área sua partição.
Como cada programa utiliza apenas o espaço que necessita, o programa de
fragmentação interna não ocorre.
Um outro problema começará a ocorrer, conhecido como fragmentação externa.
Ele ocorre quando os programas forem terminando e deixando espaços
cada vez menores na memória, não permitindo o ingresso de novos programas.
146. 4.2.5 Alocação Contígua Particionada Dinâmica
Existem duas soluções para este problema.
O primeiro método indica que, conforme os programas
terminem, apenas os espaços livres adjacentes sejam reunidos,
produzindo áreas livres de tamanho maior.
148. 4.2.5 Alocação Contígua Particionada Dinâmica
A segunda solução envolve a relocação de todas as partições
ocupadas, eliminando todos os espaços entre elas e criando
uma única área livre contígua.
Para que esta solução possa ser implementada, é necessário que o
sistema tenha a capacidade de mover os diversos programas na
memória principal, ou seja, realizar a relocação dinâmica.
150. 4.2.5 Alocação Contígua Particionada Dinâmica
Esta técnica de gerenciamento é conhecida como alocação
particionada dinâmica com relocação.
Reduz em muito o problema da fragmentação, porém aumenta a
complexidade do algoritmo e o consumo de recursos do sistema
(processador e área de disco).
Exemplo de implementação: OS/MVT (Multiprogramming with
a Variable Number os Tasks) da IBM.
151. 4.2.6 Estratégias de Alocação de Partição
O Sistemas Operacionais implementam, basicamente, três
estratégias para determinar em qual área livre um programa
será carregado para execução.
A melhor estratégia depende de uma série de fatores, como
o tamanho dos programas a serem processados. Independente
do algoritmo utilizado, o sistema possui uma lista das áreas livres,
com o endereço e o tamanho de cada área.
153. 4.2.6 Estratégias de Alocação de Partição
Qual partição livre alocar a um processo que pede por um tamanho X ?
● FIRST-FIT: a primeira partição livre onde caibam X bytes é escolhida;
○ A procura pode começar sempre no início da lista, ou a partir do último
bloco alocado (“next-fit”).
● BEST-FIT: a partição livre de tamanho mais parecido com X bytes é
escolhida (sendo igual ou maior do que X);
○ Pode se aproveitar da ordenação da lista de área ivres.
○ Pode aumentar o problema de fragmentação.
● WORST-FIT: a maior a partição livre é escolhida;
○ Diminui o problema de fragmentação, pois deixa espaços livres maiores.
154. 4.2.6 Estratégias de Alocação de Partição
Exemplo de Uso das Estratégias de Alocação de Partição
157. 5.1 Introdução
Memória Virtual é uma ténica poderosa e sofisticada de gerência de memória, onde as memórias principal
e secudária são combinadas, dando ao usuário a ilusão de existir uma memória muito maior que a
capacidade real da memória principal.
O conceito desta técnica fundamenta-se em não vincular o endereçamento feito pelo programa aos
endereços físicos da memória principal. Desta forma, programas e suas estruturas de dados deixam de
estar limitados ao tamanho da memória física disponível, pois podem possuir endereços associados à
memória secundária.
Outra vantagem é permitir um número maior de processos compartilhando a memória principal,
utilizando de forma mais eficiente o processador. Também possibilita a minimização do problema da
fragmentação da memória principal.
A primeira implementação foi realizada no início da década de 1960, no sistema Atlas, desenvolvido na
Universidade de Manchester (Kilburn, 1962). Posteriormente, a IBM introduziria este conceito
comercialmente na família System/370 em 1972. Atualmente a maioria dos sistemas operacionais
utilizam-se desta técnica de gerenciamento, com exceção de alguns sistemas de supercomputadores.
158. 5.1 Introdução
Existe um forte relacionamento entre a gerência de memória virtual e a
arquitetura de hardware do sistema computacional. Por motivos de desempenho,
é comum que algumas funções da gerência de memória virtual sejam
implementadas diretamente no hardware.
Além disso, o código do sistema operacional deve levar em consideração várias
características específicas da arquitetura, especialmente o esquema de
endereçamento do processador.
A gerência de memória virtual, também conhecida como gerência de alocação
não-contígua, aborda três técnicas que permitem sua implementação: paginação,
segmentação e segmentação com paginação.
159. 5.1.1 Espaço de endereçamento virtual
O conceito de memória virtual se aproxima muito da idéia de um vetor, existente
nas linguagens de alto nível. Quando um programa faz referência a um elemento
do vetor, não há preocupação em saber a posição de memória daquele dado. O
compilador encarrega-se de gerar instruções que implementam esse mecanismo,
tornando-o totalmente transparente ao programador.
No caso da memória virtual, a abstração ocorre em relação aos endereços dos
programas e dados. Um programa no ambiente de memória virtual não faz
referência a endereços físicos de memória (endereços reais), mas apenas a
endereços virtuais. O momento da execução, o endereço virtual referenciado é
traduzido para um endereço físico, pois o processador manipula apenas posições
da memória principal. O mecanismo de tradução destes endereços é denominado
como mapeamento.
160. 5.1.1 Espaço de endereçamento virtual
Espaços de endereçamento virtual x real
161. 5.1.1 Espaço de endereçamento virtual
Programas podem fazer referência a endereços virtuais que estejam fora dos limites da
memória principal, não há mais a limitação do tamanho da memória física disponível.
A memória secundária é utilizada como extensão da memória principal.
Quando um programa é executado, apenas parte do seu código fica residente na memória
principal, permanecendo o restante na memória secundária até ser referenciado.
Possibilita aumentar o compartilhamento da memória principal entre muito processos.
No desenvolvimento das aplicações, os programadores não necessitam preocupar-se dos
endereços virtuais, uma vez que os compiladores e ligadores (linkers) se encarregam desta
tarefa.
162. 5.1.1 Espaço de endereçamento virtual
Espaço de endereçamento virtual
163. 5.1.2 Mapeamento
O processador apenas executa instruções e referencia dados residentes no espaço de endereçamento
real; portanto, deve existir um mecanismo que transforme os endereços virtuais em endereços reais.
Esse mecanismo, conhecido por mapeamento, permite traduzir um endereço localizado no espaço
virtual para um associado no espaço real. A consequencia deste mapeamento é que um programa não
necessita estar necessariamente alocado em endereços contíguos na memória principal para ser
executado.
Nos sistemas modernos, a tarefa de tradução de endereços virtuais é realizada pelo hardware
juntamente com o sistema operacional, de forma a não comprometer seu desempenho e torná-lo
totalmente transparente a usuários e aplicações. O dispositivo de hardware responsável por essa
tradução é conhecido como Unidade de Gerência de Memória (Memory Management Unit – MMU),
sendo acionado sempre que se faz referência a um endereço virtual. Depois de traduzido, o endereço
real pode ser utilizado pelo processador para o acesso à memória principal.
Como cada processo tem seu próprio endereçamento virtual, o mecanismo de tradução encarrega-se
de manter tabelas de mapeamento exclusivas para cada processo.
165. 5.1.2 Mapeamento
A tabela de mapeamento é uma estrutura de dados existente para cada
processo.
A troca de tabelas (de um processo para outro) é realizada através de
um registrador, que indica a posição inicial da tabela corrente.
Toda a vez que há uma mudança de contexto, o registrador é atualizado
com o endereço da nova tabela.
As tabelas mapeiam blocos de dados, cujo o tamanho determina o
número de entradas existentes nas tabelas de mapeamento.
167. 5.1.3 Alocação de Memória Virtual por Paginação
Técnica de gerência de memória onde o espaço de endereçamento virtual e o
espaço de endereçamento real são divididos em blocos de mesmo tamanho
chamados páginas. As páginas no espaço virtual são denominadas páginas
virtuais, enquanto que as páginas do espaço real são chamadas de páginas reais
ou frames.
Todo o mapeamento de endereço virtual em real é realizado através de tabelas
de páginas. Cada processo possui sua própria tabela de páginas e cada página
virtual do processo possui uma entrada na tabela, com informações de
mapeamento que permitem ao sistema localizar a página real correspondente.
168. 5.1.3 Alocação de Memória Virtual por Paginação
Alocação de Memória Virtual por Paginação
169. 5.1.3 Alocação de Memória Virtual por Paginação
Quando um programa é executado, páginas virtuais são transferidas da memória
secundária para a memória principal e colocadas nos frames.
Nesta técnica, o endereço virtual é formado pelo número da página virtual (NPV) e por um
deslocamento. O endereço físico é obtido combinando-se o endereço do frame, localizado
na tabela de páginas, com o deslocamento, contido no endereço virtual.
Além da informação sobre a localização da página virtual, a ETP possui outras informações,
como o bit de validade (valid bit) que indica se uma página está carregada na memória
principal. Se o bit for 0 (zero), indica que não a página não está carregada, mas se o valor for
1, a página está carregada na memória principal.
Caso a página referenciada não esteja na memória principal, dizemos que ocorreu um page
fault. Neste caso, o sistema transfere a página da memória secundária para a memória
principal, realizando uma operação de E/S conhecida como page in ou paginação.
170. 5.1.3 Alocação de Memória Virtual por Paginação
Tradução do Endereço Virtual
171. 5.1.4 Proteção e Compartilhamento de Memória
Em qualquer sistema multiprogramável, onde diversas aplicações compartilham
a memória principal, devem existir mecanismos para preservar as áreas de
memória do sistema operacional e dos diversos processos dos usuários.
Um primeiro nível de proteção é inerente ao próprio mecanismo de memória
virtual por paginação, onde cada processo tem a sua própria tabela de
mapeamento e a tradução dos endereços é realizada pelo sistema. Desta forma
um processo não pode acessar as áreas de memória de outros processos, a
menos que haja compartilhamento explícito de páginas entre os processos.
A proteção de acesso é realizada individualmente em cada página da memória
principal, utilizando-se as entradas das tabelas de mapeamento onde alguns bits
especificam os acessos permitidos.
173. 5.1.4 Proteção e Compartilhamento de Memória
● De forma resumida há dois tipos de acessos básicos realizado em uma
página: leitura e gravação. É possível a combinação destes acessos,
produzindo um mecanismo simples e eficiente.
Mecanismo de Proteção
174. 5.1.5 Alocação de Memória Virtual por Segmentação
É a técnica de gerência de memória onde o espaço de endereçamento virtual é
dividido em blocos de tamanhos diferentes chamados segmentos. Na técnica de
segmentação, um programa é dividido logicamente em sub-rotinas e estruturas
de dados, que são alocadas em segmentos na memória principal.
Há uma relação entre a lógica do programa e sua alocação na memória principal.
Normalmente a definição dos segmentos é realizada pelo compilador, a partir do
código fonte do programa, e cada segmento pode representar um procedimento,
função, vetor ou pilha.
O espaço de endereçamento virtual de um processo possui um número máximo
de segmentos que podem existir, onde cada segmento pode variar de tamanho
dentro de um limite. O tamanho do segmento pode ser alterado durante a
execução do programa.
176. 5.1.6 Alocação de Memória Virtual por Segmentação
com Paginação
É a técnica de gerência de memória onde o espaço de endereçamento é dividido em segmentos e, por sua
vez, cada segmento dividido em páginas. Esse esquema de gerência de memória tem o objetivo de
oferecer as vantagens tanto da técnica de paginação quanto da técnica de segmentação.
Nessa técnica, um endereço virtual é formado pelo número do segmento virtual (NSV), um número de
página virtual (NPV) e um deslocamento.
Através no NSV, obtém-se uma entrada na tabela de segmentos, que contém informações da tabela de
páginas do segmento. O NPV identifica unicamente a página virtual que contém o endereço, funcionando
como um índice na tabela de páginas. O deslocamento indica a posição do endereço virtual em relação ao
início da página na qual se encontra. O endereço físico é obtido, então, combinando-se o endereço do
frame, localizado na tabela de páginas, com o deslocamento, contido no endereço virtual.
Na visão do programador, sua aplicação continua sendo mapeada em segmentos de tamanhos diferentes,
em função das sub-rotinas e estruturas de dados definidas no programa. Por outro lado, o sistema trata
cada segmento como um conjunto de páginas de mesmo tamanho, mapeadas por uma tabela de páginas
associadas ao segmento. Dessa forma, um segmento não precisa estar contíguo na memória principal,
eliminando o problema da fragmentação externa encontrado na segmentação pura.
177. 5.1.6 Alocação de Memória Virtual por Segmentação
com Paginação
Segmentação com Paginação
178. 5.1.7 Swapping em Memória
A técnica de swapping permite aumentar o número de processos que compartilham a
memória principal e, consequentemente, o grau de multiprogramação do sistema.
Quando existem novos processos para serem executados e não há memória principal
livre suficiente para alocação, o sistema utiliza o swapping, selecionando um ou mais
processos para saírem da memória e oferecer espaço para novos processos. Depois de
escolhidos, o sistema retira os processos da memória principal para a memória
secundária (swap out), onde as páginas ou segmentos são gravados em um arquivo de
swap (swap file).
Com os processos salvos na memória secundária, os frames ou segmentos alocados
são liberados para novos processos. Porteriormente, os processos que forem retirados
da memória devem retornar para a memória principal (swap in) para serem novamente
executados.
179. 5.1.7 Swapping em Memória
Há várias políticas que podem ser aplicadas na escolha dos processos que devem ser
retirados da memória principal. Todas elas buscam os processos com menor chance de
serem executados em um futuro próximo, sendo que a maioria dos critérios de
escolha baseiam-se no estado do processo e na sua prioridade.
O swapping com base em estado seleciona, inicialmente, os processos com estado em
espera; porém se estes não forem suficientes ele também selecionará os em estado
de pronto com menor prioridade.
O arquivo de swap é compartilhado por todos os processos que estão em execução.
Cada processo tem uma área reservada no arquivo que é liberada quando o processo é
eliminado. Em alguns sistemas, o arquivo de swap é, na verdade, uma área em disco
reservada exclusivamente para esta função.
180. 5.1.8 Trashing
Pode ser definido como sendo a excessiva transferência de páginas/segmentos entre a
memória principal e a memória secundária. Esse problema está presente em sistemas que
implementam tanto paginação como segmentação.
Na memória virtual por paginação, o thrashing ocorre em dois níveis: no do próprio
processo e no do sistema. No nível do processo, a excessiva paginação ocorre devido ao
elevado número de page faults gerado pelo programa em execução. Esse problema faz com
que o processo passe mais tempo esperando por páginas que realmente sendo executado.
No nível de sistema ocorre quando existem mais processos competindo por memória
principal que espaço disponível. Neste caso, o ideal é reduzir o número de páginas de cada
processo na memória, poré isto leva ao thrashing do processo. Caso a redução não seja
suficiente, o sistema iniciará o swapping. Se este mecanismos for ao extremo, o sistema
passará mais tempo realizando swappings que atendendo aos processos.
181. 5.1.8 Trashing
Em sistema que implementam segmentação, o thrashing também ocorre em dois
níveis. No nível do processo, a transferência excessiva de segmentos é devida à
modularização extrema do programa. E no nível do sistema é semelhante ao da
paginação, com a ocorrência de swapping de processos para liberar memória para
os demais.
Independente das soluções apresentadas, se existirem mais processos para serem
executados que memória real disponível, a única solução é a expansão da
memória principal.
É importante ressaltar que este problema não ocorre apenas em sistema que
implementam memória virtual, mas também em sistemas com outros mecanismos
de gerência de memória.
184. 6.1 Fundamentos
Uma parte bastante importante dentro dos Sistemas
Operacionais é a dos mecanismos de Entradas e Saídas,
através do qual o sistema se comunica com o mundo
externo.
Este nível é composto por processos servidores de E/S
(gerentes de dispositivos e drivers) que também são
processos do S.O. e também competem pelos seus recursos.
185. 6.1 Fundamentos
Entrada é toda instrução de envio de dados ao mundo exterior e
Saída é toda instrução de recepção de dados dele. Essas
instruções, em geral compreendem duas etapas:
1. Saída:
○ comandos de ação do dispositivo.
○ comandos de atribuição de dados para a operação.
2. Entrada:
○ comandos de indicação de endereços dos dados.
○ comandos de verificação do estado do dispositivo.
186. 6.1 Fundamentos
Portanto as instruções de E/S são sempre do tipo:
○ Sai comando;
○ Sai dados;
○ Entra dados; e
○ Entra Estado do Dispositivo.
Toda operação do tipo E/S pode ser subdividida no tempo em 3 etapas distintas:
1. Início da E/S
2. Transferencia de dados
3. Finalização da operação
Em geral, existe um sistema de 'RETRAY' para o caso de finalizações sem
sucesso.
187. 6.2 Tipos de E/S
E/S com Polling (Interrogação): Implementa certo paralelismo
entre a UCP e os Dispositivos de E/S.
● O programa após iniciar uma operação de E/S num
dispositivo, continua executando outras tarefas (por
exemplo, outra operação de E/S num outro dispositivo) e
periodicamente testa o estado do dispositivo disparado para
verificar se ele já completou a operação.
● É programada pelo usuário, o programa fica dependente dos
aspectos físicos, além de não perder o controle da UCP. Além
disso, o programa depende as características do dispositivos e
perde a portabilidade.
188. 6.2 Tipos de E/S
E/S Assíncronas Com Interrupções: O programa inicia a
operação de E/S passando comando ao dispositivo e continua
outras tarefas em paralelo, até que o dispositivo encerre a
operação, gerando um sinal de interrupção para a UCP para que a
finalização da operação seja executada.
189. 6.2 Tipos de E/S
E/S Por Acesso Direto A Memória (DMA): É um mecanismo de E/S assíncrona
não programada onde um dispositivo controlador de acessos a memória do
sistema promove as operações de E/S diretamente, independente da
participação da UCP, disputando com ela as vias de dados e endereços, e
sinalização só no final da operação.
● Note que num mecanismo de interrupções sem DMA a cada operação, o
dispositivo gera um sinal para a UCP a fim de completar a operação.
● No sistema de DMA, a UCP comanda um acesso passando as instruções e o
endereço na memória do dado a ser transferido e o Controlador de DMA
faz toda a operação e somente avisa a UCP de sua execução, sem
necessidade de sua intervenção.
190. 6.2 Tipos de E/S
No uso de DMA, usa-se também a E/S programada para transferências de
comandos e endereços ao Controlador. Informações para o Controlador:
● End. Inicial do bloco de dados na memória onde se dará a operação.
● Sentido da transferência de dados (leitura ou escrita).
● Número de células de memória a serem transferidas.
OBS.: A memória só tem um porto de acesso (ponto de entrada) e um
mecanismo de arbitração incorporado ao hardware define que tem direito a
acessar, de acordo com sua prioridade. A prioridade maior é dada aos
Controladores de ADM e depois a UCP pois sua velocidade é muito maior
que a dos dispositivos. Este mecanismo é chamado Roubo de Ciclo ('cicle
stealing').
191. 6.2 Tipos de E/S
E/S por CANAIS
Característico de sistemas grandes, um Canal é um processador dedicado as
funções de E/S. Pode executar Programas de canal armazenados em certos
endereços da memória que a UCP passa como parâmetro ao processador de
canal.
● Nos IBM: Canais de E/S.
● Nos CDC cyber: PPU (Periferal Processor Unit)
Canais podem ser multiplexados por um mesmo processador de canal, de modo
a ter-se em andamento várias entradas ou saídas ocorrendo em paralelo,
controladas pelo mesmo processador de canal.
192. 6.2 Tipos de E/S
BUFFERS
No histórico dos S.O., vimos que a velocidade de processamento dependia no
início da velocidade dos periféricos, pois não havia até então paralelismo entre
eles e a UCP.
Além dos avanços no Hardware e nas formas de E/S, os sistemas mais recentes
implementam formas de E/S que fazem uso de BUFFERS que são meios de
armazenamento intermediários utilizados para suavizar as diferenças de
velocidade de produção e consumo de dados entre a UCP e os Dispositivos.
A estratégia de bufferização está baseada nos comandos de Sincronização entre
processos Produtor/consumidor, tratado no capítulo sobre sincronismo, através
das primitivas Wait e Signal do núcleo.
193. 6.3 Camadas
A gerência de dispositivos é parte do S.O. responsável por
ocultar das aplicações os detalhes de controle e operação
dos diversos dispositivos conectados ao sistema.
A própria gerência de dispositivos é normalmente
implementada em diversas camadas, de forma a
proporcionar uma melhor generalização das operações de
controle frente a constante evolução e mudança da
tecnologia de implementação do hardware dos
dispositivos.
194. 6.3 Camadas
● Assim, a maioria dos S.O.s implementa a gerência de
dispositivos em um esquema parecido com o abaixo
representado:
195. 6.3 Camadas
Biblioteca de E/S
Normalmente, as linguagens oferecem comando para manipular
os recursos de E/S, que são o primeiro nível de interação do
aplicativo com a gerência de E/S.
Esses comandos são independentes até mesmo do S.O.
Por exemplo, o usuário cria um arquivo em qualquer linguagem
através de um comando da própria linguagem que não o obriga a
saber nada sobre como será a formatação física do arquivo no
disco.
196. 6.3 Camadas
Biblioteca de E/S
O compilador da linguagem, por sua vez, traduz esses comandos em comando
Chamadas de Sistema, que são os comandos oferecidos pela camada mais de
cima da gerência de dispositivos e que, no desenho acima, chamamos biblioteca
de E/S. Cada System call da biblioteca possui parâmetros que são passados pelo
compilador da linguagem, naturalmente ainda independentemente da
implementação física, e resolvidos na fase de link do programa do usuário.
Além de esconder características de implementação, as Chamadas de Sistema
têm por objetivo oferecer um nível onde sejam implementadas rotinas que
afinal são comuns a várias linguagens e a diferentes aplicativos e que, portanto,
não precisam ser duplicadas nos diferentes aplicativos ou linguagens.
197. 6.3 Camadas
Sistemas de E/S
É a camada imediatamente abaixo na estrutura da Gerência de E/S e tem os
seguintes objetivos:
● Realizar operações comuns a dispositivos distintos, sem levar em
consideração aspectos específicos do dispositivo
● Fazer o mapeamento entre dispositivos lógicos e seus respectivos drivers
de dispositivos físicos
● Uniformizar unidades de informação (blocos, registros, bytes, etc.)
● Gerenciar a ocorrência de alguns tipos de erros
● Controlar o compartilhamento de recursos, impondo os sincronismos que
se fizerem necessários
● Controlar as prerrogativas de acesso dos usuários aos dispositivos
● Controlar a bufferização das informações com o objetivo de acelerar as
operações de E/S.
198. 6.3 Camadas
Drivers de Software
Os drivers de software, device drivers ou simplesmente drivers, manipulam um
só dispositivo ou, no máximo, uma família de dispositivos.
Normalmente os drivers são feitos em Assembly pelo próprio fabricante do
dispositivo e são fornecidos gratuitamente quando se compra o Hardware (ou
são disponibilizados da internet, por exemplo).
Suas funções são:
● Receber comandos genéricos e traduzí-los para comandos específicos do
dispositivo
● Manipular os registradores e demais elementos de hardware específicos do
controlador
199. 6.3 Camadas
Drivers de Software
Mapear unidades de um nível superior (como por exemplo
blocos) em unidades físicas do dispositivo (como por
exemplo, disco, trilhas, setores, etc.)
Gerar e manipular interrupções de operações feitas por
hardware dedicado (fim de transferência de um bloco de
dados ou erro de transferência de dados, por exemplo).
201. 6.3 Camadas
Controladoras
São placas de hardware que possuem registradores, memória local e as
vezes processadores dedicados a manipular um determinado
dispositivo.
Em geral bufferizam a informação recebida ou enviada ao dispositivo
por um barramento dedicado ou algum outro canal de comunicação e
transferem os dados para a memória principal geralmente através de
DMA.
Assim, a CPU fica livre para realizar outras operações enquanto está se
realizando a transferência de dados do/para o dispositivo.
202. 6.3 Camadas
Controladoras
Alguns padrões de controladoras utilizados atualmente são:
● IDE interface controladora de discos magnéticos e óticos mais utilizada nos
computadores pessoais. Possui um padrão mais antigo (PIO) e um mais
recente (ULTRA DMA)
● SCSI (Small Computer System Interface) – define padrões de Hardware e
software que permitem conectar diferentes dispositivos como discos
magnéticos, óticos, scanners, unidades de fita, etc.
● USB – interface de uso geral com protocolo de rede que permite conectar
virtualmente todos os dispositivos de uma máquina (inclusive teclado e
mouse) e que começa a se configurar como o provavel padrão de futuro.
203. 6.3 Camadas
Dispositivos
São os equipamentos propriamente ditos, como impressoras, discos, fitas,
teclados, scanners, vídeos, registradores gráficos, etc.
Podem ser divididos em estruturados e não estruturados. Estruturados são os
que transferem informações em blocos (estruturas) de tamanho fixo. A
transferência pode ser direta, como no caso dos discos onde se acessa
diretamente o endereço de um bloco ou seqüencial, como no caso das fitas, em
que é preciso percorrer seqüencialmente o meio de armazenamento.
Os não estruturados são os dispositivos em que os dados fluem em lotes de
tamanho indefinido, ou mesmo um a um, como é o caso dos teclados, mouse ou
impressoras.