Curso de Ciências da Computação 2. NÍVEL DE SISTEMA OPERACIONAL Nos períodos anteriores foram mostrados os níveis iniciais da organização de um computador, quando vimos em Circuitos Digitais os detalhes do Nível 0 (zero) de Lógica Digital. Logo após mostramos como um interpretador é executado no Nível de Microprogramação (Nível 1) e foi introduzido o conceito dos diversos níveis de linguagem existentes. No próximo Nível, mostramos como poderíamos executar programas escritos para o Nível de Máquina Convencional (Nível 2) através das dezenas de instruções extremamente simples existentes neste Nível 2. Em um computador microprogramável, portanto, as instruções do Nível de Máquina Convencional (Nível 2), tais como chamadas de procedimento, multiplicação e loop, não são executadas diretamente pelo Hardware, como sabemos. Em vez disso, elas são buscadas, analisadas e executadas como uma série de pequenos passos pelo microprograma. A máquina de Nível 2 pode ser programada por pessoas que não sabem absolutamente nada sobre a máquina de Nível 1 ou de seu interpretador. Até onde lhes interessa, a máquina de Nível 2 pode ser usada como se fosse o verdadeiro hardware. Tal como um interpretador executado pela máquina de Nível 1 pode interpretar programas escritos na linguagem de máquina de Nível 2, um interpretador executado pela máquina de Nível 2 pode interpretar programas escritos na linguagem de máquina de Nível 3. Devido a razões históricas, o interpretador executado pela máquina de Nível 2 que suporta a máquina de Nível 3 é chamado de Sistema Operacional, como mostrado na Fig. 2.1. Assim, o Nível 3 é chamado de "Nível de Máquina do Sistema Operacional". Fig. 2.1 – Os níveis 2 e 3 já são suportados por software. Disciplina: Projeto Lógico de Computadores (5º/6º Sem - 2013). Livro: Andrew S. Tanenbaum Página 1 de 9 Curso de Ciências da Computação Existe uma diferença significativa entre o modo em que o Nível de Máquina do Sistema Operacional é suportado e o modo em que o Nível de Máquina Convencional é suportado. Esta diferença se deve ao fato de que o Nível de máquina do sistema operacional evoluiu gradualmente a partir do Nível de Máquina Convencional. Muitas das instruções do Nível de Máquina do Sistema Operacional estão também presentes no Nível de Máquina Convencional. Chamaremos estas instruções de instruções "comuns" de Nível 3, porque elas incluem operações comuns, tais como operações aritméticas, booleanas, deslocamento, entre outras. Chamaremos as outras instruções de Nível 3 (aquelas que não estão presentes no Nível 2) de instruções NMSO, para enfatizar sua existência somente no Nível de Máquina do Sistema Operacional. Embora seja possível que o sistema operacional interprete todas as instruções de Nível 3, isto não seria eficiente nem necessário. As instruções comuns de Nível 3 podem ser interpretadas diretamente pelo microprograma. Esta situação e ilustrada pela Fig. 2.2(a) para o caso de um computador com uma única memória para armazenar todos os programas. Desde que somente instruções comuns estejam sendo executadas, o microprograma busca as instruções diretamente do programa do usuário, as examina e as executa. Fig. 2.2 – (a) Instruções comuns são interpretadas diretamente pelo microprograrna. (b) Instruções NMSO são interpretadas pelo sistema operacional, o qual e interpretado pelo rnicroprograrna. Porém, assim que uma instrução NMSO e encontrada, a situação muda. O microprograma para de interpretar o programa do usuário e começa a interpretar o sistema operacional. O sistema operacional examina então a instrução NMSO e a executa. Quando a instrução NMSO tiver sido executada, o sistema operacional executa certa instrução que faz com que o microprograma continue buscando e executando as instruções do programa do usuário. Naturalmente, se a próxima instrução do programa do usuário e também uma NMSO, o sistema operacional será novamente ativado. Este método de executar programas de Nível 3 significa que o computador esta funcionando parte do tempo como uma maquina de Nível 3 e parte como uma de Nível 2. Durante a execução de uma instrução NMSO, três programas estão sendo executados, um em cada maquina (virtual). Cada um tem seu próprio estado, incluindo seu próprio contador de programa. Conceitualmente, o contador de programa de Nível 3 aponta para a instrução NMSO (ou sua sucessora, dependendo de quando o contador de programa e avançado), o contador de programa Disciplina: Projeto Lógico de Computadores (5º/6º Sem - 2013). Livro: Andrew S. Tanenbaum Página 2 de 9 Curso de Ciências da Computação de Nível 2 aponta para aquela instrução do sistema operacional que esta sendo correntemente executada, e o contador de programa de Nível 1 diz ao hardware real que microinstrução deve ser executada. O sistema operacional será tratado como um único nível, para simplicidade - o que não significa que todos os sistemas operacionais sejam organizados como um único nível. Pelo contrario, alguns sistemas operacionais avançados são construídos como uma serie de varies níveis. Entretanto, o assunto de como projetar um sistema operacional esta além do escopo deste livro. Para maiores informações sobre sistemas operacionais, veja Tanenbaum (1987). Deve ser mencionado que muitos sistemas operacionais para grandes computadores são sistemas de multlprogramação, o que significa que, em vez de suportar uma única máquina virtual de Nível 3, o sistema operacional suporta varias máquinas virtuais de Nível 3 em paralelo. Se cada uma destas maquinas virtuais estiver Iigada a um terminal remoto, ele e chamado de sistema de tempo compartilhado (time-sharing). Formas híbridas, nas quais algumas maquinas virtuais são usadas em Iinha e outras não, são comuns. Uma parte substancial do sistema operacional e dedicada a gerencia de todas as máquinas virtuais, em vez de interpretar instruções NMSO. Podemos apenas prover a mais breve das introduções ao assunto de sistemas operacionais. Vamos focalizar três tópicos de importância. O primeiro e memória virtual, uma técnica provida por muitos sistemas operacionais para fazer parecer que a maquina tem mais memória do que realmente possui. O segundo e BrS de arquivos, um conceito de mais alto nível que as instruções de E/S que estudamos no semestre anterior. O terceiro e ultimo tópico e processamento paralelo como múltiplos processos podem ser executados simultaneamente no Nível 3. O conceito de processo e importante, e o descreveremos em detalhe mais tarde, nesta aula. Por enquanto, um processo pode ser imaginado como um programa em execução e todas as suas informações de estado (memória, registradores, contador de programa, status de E/S e assim por diante). 2.1. Memória virtual Nos primórdios da era dos computadores, memórias eram caras e pequenas. O IBM 650, o melhor computador científico da época (final da década de 1950), tinha apenas 2000 palavras de memória. Um dos primeiros compiladores de ALGOL 60 foi escrito para um computador com apenas 1024 palavras de memória. Um sistema antigo de tempo compartilhado executava razoavelmente bem em um PDP-l, com uma memória total de apenas 4096 palavras de 18 bits para o sistema operacional e os programas de usuários. Naqueles dias, o programador gastava muito tempo tentando espremer os programas na minúscula memória. Frequentemente, era necessário usar um algoritmo que executava muito mais lentamente que outro, sendo este algoritmo melhor simplesmente porque o melhor algoritmo era muito grande - isto e, um programa usando o melhor algoritmo não cabia na memória do computador. A solução tradicional para este problema foi o uso de memória secundaria, tal como um disco. O programador dividia o programa em uma serie de pedaços, chamados overlays, cada um dos quais caberia na memória. Para executar o programa, o primeiro overlay era trazido para a memória e executado por algum tempo. Quando ele acabava, ele lia o próximo overlay e o chamava, e assim por diante. O programador era responsável por quebrar o programa em overlays, decidindo onde cada overlay seria mantido na memória secundaria, providenciando o Disciplina: Projeto Lógico de Computadores (5º/6º Sem - 2013). Livro: Andrew S. Tanenbaum Página 3 de 9 Curso de Ciências da Computação transporte de overlays entre a memória principal e a secundaria, e geralmente gerenciando todo o processo de overlay sem qualquer ajuda do computador. Embora largamente utilizada por varies anos, esta técnica envolveu muito trabalho relacionado a gerencia de overlays. Em 1961, um grupo de pessoas em Manchester, Inglaterra, propôs um método para realizar o processo de overlay automaticamente, sem que o programador sequer soubesse o que estava acontecendo (Fotheringham, 1961). Este método, agora chamado memória virtual, tinha a vantagem obvia de liberar o programador de um monte de gerencia chata. Ele foi primeiro utilizado em uma serie de computadores durante os anos 60, a maioria associados a projetos de pesquisa de sistemas de computadores. Por volta do início da década de 1970, memória virtual se tornou disponível na maioria dos computadores. Agora, ate os microprocessadores, incluindo o 80386 e o 68030, possuem sistemas de memória virtual altamente sofisticados. 2.1.1. Paginação A ideia sugerida pelo grupo de Manchester era separar os conceitos de espaço de endereçamento e posições de memória. Considere um exemplo de um computador com um campo de endereço de 16 bits nas suas instruções e 4096 palavras de memória. Um programa, neste computador, pode endereçar 65536 palavras de memória. A razão e que existem 65536 (216) endereços de 16 bits. O número de palavras endereçáveis depende somente do número de bits em um endereço e, de forma alguma, esta relacionado com o número de palavras de memória realmente disponíveis. O espaço de endereçamento para este computador consiste nos números 0, 1, 2,... , 65535, porque este e o conjunto de endereços possíveis. Antes que a memória virtual fosse inventada, as pessoas faziam uma distinção entre os endereços abaixo de 4096 e aqueles iguais ou superiores a 4096. Embora raramente colocada em tantas palavras, estas duas partes eram consideradas como o espaço de endereçamento útil e o espaço de endereçamento útil, respectivamente (os endereços acima de 4095 eram úteis porque eles não correspondiam a endereços de memória real). As pessoas não faziam muita distinção entre espaço de endereçamento e endereços de memória real, porque o hardware reforçava a correspondência um-para-um entre eles. A ideia de separar o espaço de endereçamento dos endereços de memória e como se segue. A qualquer instante, 4096 palavras de memória podem ser acessadas diretamente, mas elas não precisam corresponder aos endereços o a 4095. Poderíamos, por exemplo, "dizer" ao computador que, de agora em diante, sempre que o endereço 4096 for referenciado, a palavra de memória o será utilizada. Sempre que o endereço 4097 for referenciado, a palavra de memória 1 será utilizada; sempre que o endereço 8191 for referenciado, a palavra de memória 4095 será utilizada; e assim por diante. Em outras palavras, definimos um mapeamento do espaço de endereçamento nos endereços de memória real, como mostrado na Fig. 2.3. Nos termos desta figura de mapeamento de endereços a partir do espaço de endereçamento para posições de memória real, uma maquina de 4K sem memória virtual simplesmente possui um mapeamento fixo entre os endereços o a 4095 e as 4096 palavras de memória. Uma questão interessante e: o que acontece se um programa desvia para um endereço entre 8192 e 12287? Disciplina: Projeto Lógico de Computadores (5º/6º Sem - 2013). Livro: Andrew S. Tanenbaum Página 4 de 9 Curso de Ciências da Computação Fig. 2.3 Mapeamento no qual os endereços de 4096 a 8191 são mapeados em endereços na memória principal de 0 a 4095. Em uma maquina sem memória virtual, o programa causaria uma interrupção de erro que imprimiria uma mensagem apropriadamente rude, tal como "Memória não-existente foi referenciada", e terminaria o programa. Em uma maquina com memória virtual, a seguinte sequencia de passos ocorreria: 1. 2. 3. 4. 0 conteúdo da memória principal seria salvo na memória secundaria. As palavras de 8192 a 12287 seriam localizadas na memória secundaria. As palavras de 8192 a 12287 seriam carregadas para a memória principal. 0 mapa de endereços seria mudado para mapear os endereços 8192 a 12287 nas posições de memória 0 a 4095. 5. A execução continuaria como se nada incomum tivesse acontecido. Esta técnica para overlay automático e chamada paginação, e as porções de programa lidos da memória secundaria são chamadas páginas. Uma forma mais sofisticada de mapear endereços a partir do espaço de endereçamento nos endereços de memória real também e possível. Para ênfase, vamos chamar os endereços que o programa pode referenciar de espaço de endereçamento virtual, e os endereços de memória real, ligados por fios, de espaço de endereçamento físico. Um mapa de memória relaciona endereços virtuais a endereços físicos, Presumimos que existe espaço suficiente na memória secundaria (disco) para armazenar todo o programa e seus dados. Programas são escritos como se houvesse memória principal suficiente para todo o espaço de endereçamento virtual, apesar de não ser este o caso. Programas podem carregar de, ou armazenar em, qualquer palavra no espaço de endereçamento virtual, sem considerar o fato de que não existe realmente memória física suficiente. De fato, o programador pode escrever programas sem nem ao menos saber que existe memória virtual. 0computador parece simplesmente possuir uma memória grande. Este ponto e crucial e será contrastado mais tarde com a segmentação, na qual o programador deve estar ciente da existência dos segmentos. Para enfatizar isto mais uma vez, a paginação da ao programador a ilusão de uma memória principal grande, continua e linear, com o mesmo tamanho do espaço de endereçamento, quando, na verdade, a memória principal disponível pode ser menor (ou maior) que o espaço de endereçamento. A simulação desta memória principal grande através de paginação não pode ser detectada pelo programa (exceto através de execução de testes de temporização): quando quer que um endereço seja Disciplina: Projeto Lógico de Computadores (5º/6º Sem - 2013). Livro: Andrew S. Tanenbaum Página 5 de 9 Curso de Ciências da Computação referenciado, a instrução ou dado apropriado parece estar presente. Como o programador pode programar como se não existisse paginação, o mecanismo de paginação e dito transparente. A ideia de que um programador pode usar uma característica não-existente sem se dar conta de como ela funciona não e nova para nós, afinal de contas. O conjunto de instruções de um computador de Nível 2 e não-existente no sentido de que nenhuma das instruções são primitivas de hardware, mas todas elas são, de fato, tratadas pelo software do Nível 1. Similarmente, o programador de Nível 3 pode usar a memória virtual sem se preocupar como ela funciona. Somente os escritores de sistemas operacionais precisam saber como ela funciona. 2.1.2. Implementação de paginação Um requisito essencial para uma memória virtual e uma memória secundaria para armazenar o programa completo. E conceitualmente mais simples pensar na copia do programa na memória secundaria como o original, e os pedaços trazidos para a memória principal a toda hora, como copias, em vez da maneira oposta. Naturalmente, e importante manter o original atualizado. Quando mudanças são feitas na copia da memória principal, elas devem também ser refletidas no original (eventualmente). o espaço de endereçamento virtual e dividido em uma serie de páginas de tamanhos iguais. Tamanhos de páginas variando de 512 a 4096 endereços por página são comuns atualmente. o tamanho da página e sempre uma potencia de 2. O espaço de endereçamento físico e dividido em pedaços de forma similar, cada pedaço sendo do mesmo tamanho que uma página, de modo que cada pedaço da memória principal e capaz de conter exatamente uma página. Estes pedaços de memória principal para onde as páginas não são chamados páginas físicas (page frames). Na Fig. 2.3, a memória principal contém apenas uma página física. Nos projetos práticos, ela conterá dezenas, centenas ou mesmo milhares em uma grande maquina. A Fig. 2.4 ilustra uma maneira possível de dividir um espaço de endereçamento de 64K. Fig. 2.4 (a) Um espaço de endereçamento de 64K dividido em 16 páginas de 4K cada. (b) Urna rnernória principal de 32K dividida em oito páginas físicas de 4K cada Disciplina: Projeto Lógico de Computadores (5º/6º Sem - 2013). Livro: Andrew S. Tanenbaum Página 6 de 9 Curso de Ciências da Computação A memória virtual da Fig. 2.4 seria implementada no Nível 2 através de uma tabela de páginas de 16 palavras. Quando o programa tentasse referenciar sua memória, fosse para buscar dados, armazenar dados, buscar instruções ou desviar, ele primeiro geraria um endereço de 16 bits correspondente a um endereço virtual entre 0 e 65535. Indexação, endereçamento indireto e todas as técnicas usuais podem ser usadas para gerar este endereço. Neste exemplo, um endereço de 16 bits e tornado como um número de página virtual de 4 bits e um endereço de 12 bits dentro da página selecionada, como mostrado na Fig. 2.5(a). Fig. 2.5 (a) Um endereço virtual que consiste em um número de 4 bits para página virtual e um offset de 12 bits. Nesta figura, o endereço de 16 bits e 12310, que e considerado como o endereço 22 da página 3. A relação entre páginas e endereços virtuais para este exemplo e mostrada na Fig. 2.5(b). Fig. 2.5 (b) Números de páginas e seus endereços virtuais. Se o endereço virtual 0 da página 3 esta no endereço físico 12288, o endereço virtual 22 deve estar no endereço físico 12310. Tendo descoberto que a página virtual 3 e necessária, o sistema operacional deve procurar onde a página virtual 3 esta localizada. Existem nove possibilidades: oito páginas físicas na memória principal, ou algum lugar na memória secundaria, porque nem todas as páginas virtuais podem estar na memória principal ao mesmo tempo. Para verificar qual destas nove possibilidades e verdade, o sistema operacional procura na tabela de páginas, que tem uma entrada para cada uma das 16 páginas virtuais. Disciplina: Projeto Lógico de Computadores (5º/6º Sem - 2013). Livro: Andrew S. Tanenbaum Página 7 de 9 Curso de Ciências da Computação Um uso típico deste mecanismo e sugerido na Fig. 2.6. No Nível 0, encontramos o núcleo do sistema operacional, que manipula E/S, gerencia de memória e outros assuntos críticos. No Nível 1 está presente o manipulador de chamadas de sistema. Programas de usuários podem chamar procedimentos deste nível para ter as chamadas de sistema tratadas, mas somente uma lista específica e protegida de procedimentos pode ser chamada. O Nível 2 contém procedimentos de biblioteca, possivelmente compartilhados entre os varies programas em execução. Programas de usuários podem chamar estes procedimentos e ler seus dados, mas não podem modifica-los. Finalmente, os programas de usuários são executados no Nível 3, que tem a menor proteção. Fig. 2.6 Proteção no SO. 2.2. Memória virtual no Pentium III. O Pentium II foi o primeiro a permitir o multiprocessamento de dois processadores. Sua conexão na placa-mãe era feita através do seu conector próprio, chamado de slot 1. O processador Pentium II combinava avanços tecnológicos com capacidade para melhorar o desempenho no ponto flutuante, em multimídia e em integração. Melhorava o desempenho dos aplicativos de áudio, vídeo e gráficos, bem como aumentar a velocidade de decodificação e compressão de dados. Os Clock's dos processadores Pentium II variavam de 233 a 400 MHz, sua frequência de barramento externo podia chegar a 66Mhz. Já o Pentium III, projetado para a Internet, tinha o clock variando de 500 MHz a 933 MHz, sua frequência de barramento externo poderia chegar a 133Mhz, ou seja, 1,06 GB/s, podendo acessar até 4GB de memória usando cachê. O processador Pentium III integrava a micro-arquitetura Execução Dinâmica P6. Além disso, o processador Intel Pentium III já oferecia extensões de Internet Streaming SIMD, 70 novas instruções possibilitando um avanço significativo em imagens, 3D, streaming de áudio e vídeo e reconhecimento de voz para uma melhor experiência na Internet. O cerne da memória virtual do Pentium III consiste em duas tabelas, a LDT (Local Descriptor Table, ou tabela de descritores locais) e a GDT (Global Descriptor Table, ou tabela de descritores globais). Cada programa possui sua própria LDT, mas existe uma única GDT, compartilhada por todos os programas no computador. A LDT descreve segmentos locais a cada programa, incluindo seu código, dados, pilha etc., enquanto a GOT descreve os segmentos do sistema, incluindo o próprio sistema operacional. Disciplina: Projeto Lógico de Computadores (5º/6º Sem - 2013). Livro: Andrew S. Tanenbaum Página 8 de 9 Curso de Ciências da Computação Para acessar um segmento, um programa 80386 primeiro carrega um seletor para aquele segmento em um dos seis registradores de segmento. Durante a execução, CS contém o seletor para o segmento de código, OS contém o seletor para o segmento de dados, e assim por diante. Cada seletor e um número de 16 bits, como mostrado na Fig. 2.4. Fig. 2.7 Um seletor do Pentium III. Um dos bits do seletor diz se o segmento e local ou global (isto e, se ele esta na LDT ou na GDT). Treze outros bits especificam o número da entrada na LDT ou GDT, de modo que estas tabelas estão restritas, cada uma, a 8K (2 13) descritores de segmentos. Os outros 2 bits se relacionam a Página como índice da tabela para encontrar a direção física “Marco de Página”. Cada programa em execução possui um diretório de páginas consistindo em 1024 entradas de 32 bits. Ele esta localizado em um endereço apontado por um registrador global. Cada entrada neste diretório aponta para uma tabela de páginas que também contém 1024 entradas de 32 bits. As entradas da tabela de páginas apontam para as páginas físicas. O esquema e mostrado na Fig. 2.8. Fig. 2.8 Mapeamento de um endereço linear em um endereço físico. Disciplina: Projeto Lógico de Computadores (5º/6º Sem - 2013). Livro: Andrew S. Tanenbaum Página 9 de 9