1 4 – Estrutura do Sistema Operacional 4.1 - Kernel O kernel é o núcleo do sistema operacional, sendo responsável direto por controlar tudo ao seu redor. Desde os dispositivos usuais, como unidades de disco, portas de comunicação, dispositivos lógicos e de hardware até interpretadores de comandos, etc. Figura 4.1 – Kernel Esse kernel é formado por um conjunto de rotinas que oferecem serviços aos usuários, às aplicações e ao próprio sistema. É o kernel que faz a comunicação diretamente com o hardware. Todos os outros componentes do sistema operacional fazem a comunicação com o Kernel e este faz a interface entre os aplicativos e o hardware. 2 Figura 4.2 – Máquina de níveis com o Kernel Enfim, sabendo utilizar o kernel de um sistema da melhor forma possível, pode-se obter resultados impressionantes. Porém, essa vantagem pode se virar contra o usuário e se tornar um tormento, se por ventura, o kernel estiver sobrecarregado, ou com suportes incorretos implementados a determinado dispositivo. Se você já é usuário de Linux, já sabe que otimizar e recompilar o kernel é uma tarefa usual nesse mundo do código fonte aberto. Os maiores problemas dos sistemas operacionais proprietários, de código fonte fechado, são que o kernel desses sistemas tem suporte a diversos periféricos e dispositivos de hardware que, provavelmente, você jamais irá vê-las ou ainda nem saberá que existem ou existiram tais dispositivos. Tendo um kernel que suporte exatamente todo o sistema e as funções que se quer utilizar nele, economizará relevantemente o consumo de recursos de memória do sistema, e como recurso não é algo que certamente se tem sobrando, é sempre bom garantir a performance máxima do sistema em questão. 3 O sistema operacional é executado de forma independente uma parte da outra, a partir do momento que o kernel está carregado na memória todas as outras partes são executadas de acordo com eventos. As principais funções do kernel são: - tratamento de interrupções e exceções; - criação e eliminação de processos; - sincronização e comunicação entre processos; - escalonamento e controle de processos; - gerencia de memória; - gerencia de sistema de arquivos; - gerencia de dispositivos de E/S. 4.2 – Modos de Acesso O kernel é a parte mais importante do sistema operacional e, portanto, deve ser muito bem protegido, evitando que os usuários e seus aplicativos o acessem diretamente. Por isso, existem certas instruções que não podem ser executadas diretamente, pois sua utilização indevida poderia comprometer todo o sistema, danificando o kernel. Essas instruções podem (e devem!) ser executadas única e exclusivamente pelo sistema operacional e não diretamente pelos aplicativos. Essas instruções são chamadas de instruções privilegiadas, pois podem comprometer o sistema se forem usadas incorretamente. Para que alguma aplicação possa executar essas instruções, os processadores implementam os chamados modos de acesso. Existem dois modos de acesso: o modo usuário (user mode) e o modo kernel (root mode ou administrator mode). Quando uma aplicação está em modo usuário, essa aplicação pode somente executar instruções não privilegiadas, enquanto que em modo kernel, as aplicações podem executar qualquer tipo de instrução. O modo de acesso de uma aplicação é determinado por um conjunto de bits, que fica no registrador de status. Sempre que uma instrução vai ser 4 executada, é feita uma verificação desse registrador para ver se a instrução pode ou não ser executada. A melhor maneira de evitar que aplicações executem em modo kernel é garantir que somente o sistema operacional terá esse tipo de acesso e sempre que uma aplicação necessitar executar alguma instrução, é feita uma chamada a uma rotina do sistema que altera o modo de acesso de modo usuário para modo kernel e, ao término da operação, retorna para modo usuário. 4.3 – System Calls As system calls ou chamadas de sistema são uma porta de entrada para o acesso ao kernel e seus serviços. Sempre que alguma aplicação ou usuário necessita de algum serviço do kernel, é feita uma chamada a uma de suas rotinas através de uma system call. Através de parâmetros fornecidos na system call, a solicitação é processada e uma resposta é retornada à aplicação juntamente com um estado de conclusão indicando se ocorreu tudo bem ou não. Para cada serviço disponível existe uma system call associada e cada sistema operacional tem suas próprias system calls, com nomes, parâmetros e formas de ativação específicas. Foi criado o padrão POSIX (Portable Operating System Interface for Unix) que permitia que qualquer aplicação desenvolvida seguindo este padrão pudesse ser executada em qualquer outro sistema operacional que utilizasse o padrão POSIX. 4.4 – Arquitetura Monolítica A arquitetura monolítica é semelhante a uma aplicação formada por vários módulos que são compilados separadamente e depois linkados formando um grande e único programa executável. O sistema operacional MS-DOS e as primeiras versões do Unix eram baseados nessa arquitetura. 5 4.5 – Arquitetura de Camadas Na arquitetura de camadas, o sistema é dividido em níveis sobrepostos. Cada camada oferece um conjunto de funções que podem ser utilizados apenas pelas camadas superiores. A vantagem da estruturação de camadas é isolar as funções do sistema operacional, facilitando a sua manutenção e depuração, além de criar uma estrutura hierárquica de níveis de acesso, protegendo as camadas de mais baixo nível. Atualmente, os sistemas operacionais utilizam o modelo de duas camadas, onde existem os modos de acesso usuário e kernel. 4.6 – Máquina Virtual Um sistema computacional é formado por níveis, sendo o hardware o nível mais baixo e o sistema operacional o nível imediatamente acima. Uma máquina virtual ou Virtual Machine(VM) consiste em criar um nível intermediário entre o hardware o sistema operacional e este nível é chamado de gerencia de máquinas virtuais, também conhecido como Hypervisor. Este nível cria diversas máquinas independentes, onde cada máquina oferece uma cópia virtual do hardware, incluindo modos de acesso, interrupções, etc. Cada máquina virtual é independente das demais e é possível que cada uma tenha o seu sistema operacional e aplicações. Nesse modelo, cada máquina virtual é independente, e isso permite uma grande segurança para todo o sistema, pois caso ocorra algum problema em alguma máquina virtual, não acarretará problemas para as outras e nem para o sistema como um todo. Um exemplo da utilização de máquina virtual ocorre na linguagem Java, criada pela Sun Microsystems. Para que uma aplicação Java seja executada, é 6 necessária uma máquina virtual Java (Java Virtual Machine - JVM). Qualquer sistema operacional em qualquer arquitetura de hardware pode executar uma aplicação Java sem recompilar o código, basta que cada sistema tenha uma Máquina Virtual Java. Figura 4.3 – Máquina de Níveis – Máquina Virtual 4.7 – Virtualização A técnica de virtualização é a técnica que consiste em simular, por software um sistema computacional completo, com processador, memória principal, memória secundária e dispositivos de entrada/saída. Diante disso, podemos executar vários sistemas operacionais dentro de um mesmo computador físico. A virtualização pode ser implementada através de softwares que implementam este conceito, tais como o VMWare ESX, o Microsoft Hyper-V e o Citrix Xen Server, ferramentas essas para servidores e também o Microsoft Virtual PC, Virtual Box e VMWare Workstation. 7 Figura 4.4 - Virtualização A camada de software responsável por criar uma cópia do hardware virtual é chamada de hypervisor. O computador físico que executa o software que implementa a virtualização é chamado de host ou hospedeiro, enquanto as máquinas virtuais que executam neste computador físico são chamadas de guest ou convidadas. Além disso, para se obter um bom desempenho é fundamental que tanto o hardware como o sistema operacional em si tenham suporte a virtualização, o que garante o bom funcionamento de todo o sistema, permitindo que algumas camadas sejam “transpassadas” no conceito da máquina de níveis. O uso mais comum da técnica de virtualização é em servidores, onde várias máquinas físicas com seus hardwares e sistemas operacionais distintos são consolidados e então convertidos em computadores virtuais, reduzindo o número de computadores físicos gerando economia de energia elétrica, espaço físico e licenças de softwares (quando for o caso). Outro uso que vem ganhando força é a técnica de VDI (Virtual Desktop Infrastructure) ou Virtualização de Desktops, onde o os desktops ou estações de trabalho dos usuários são convertidos em máquinas virtuais, podendo estas serem carregadas a partir de qualquer estação da rede ou mesmo da internet. 8 A seguir temos alguns exemplos de virtualização Figura 4.5 – Hyper-V Figura 4.6 – VirtualBox 9 Figura 4.7 – VMWare ESXi 4.8 – Arquitetura Microkernel Nos sistemas operacionais modernos, a tendência é tornar o kernel do sistema o mais simples possível. E para que isto seja possível, ao invés do kernel oferecer todos os serviços do sistema, como leitura/gravação de arquivos, esses serviços são oferecidos na forma de processos, onde cada processo é 10 responsável por um serviço de sistema e o kernel fica responsável apenas em gerenciar esses processos. Nesta arquitetura, sempre que alguma aplicação, seja desenvolvida pelo próprio usuário, seja o próprio sistema operacional, necessita de algum serviço, como a leitura da memória, por exemplo, ela faz a solicitação ao processo responsável por aquele serviço. A aplicação que solicita o serviço é chamada de cliente e o processo responsável por atender a solicitação é chamado de servidor. Quando uma aplicação necessita algum serviço, ela faz uma solicitação ao processo responsável, este por sua vez, envia uma mensagem de retorno à aplicação. A grande vantagem de se utilizar esse tipo de arquitetura, além do kernel ser menor e mais simples, é que os processos que são responsáveis pelos serviços executam em modo usuário, e não mais em modo kernel, evitando assim problemas de acesso privilegiado, deixando esse acesso somente ao kernel. Assim, se ocorrer algum problema com o processo responsável por um serviço, apenas aquele serviço ficará indisponível, e o sistema continuará a funcionar normalmente. Como desvantagem deste modelo, temos o problema de desempenho, pois devido à necessidade de mudança de modo de acesso constante entre os clientes e os servidores. Outro problema é que certas funções do sistema operacional exigem acesso direto ao hardware. 4.9 – Projeto do Sistema Operacional Para se construir um sistema operacional deve estar atento a inúmeros fatores, como confiabilidade, portabilidade, manutenibilidade, flexibilidade e desempenho. Precisamos estar atentos também a arquitetura de hardware que pretendemos utilizar e o tipo de sistema operacional. Os primeiros sistemas operacionais foram desenvolvidos inteiramente em assembly e o código possuía cerca de um milhão de instruções. Com a evolução dos sistemas, as linhas de código chegaram perto dos 20 milhões. Nos sistemas 11 operacionais atuais, o número de linhas de código pode chegar a cerca de 40 milhões, como no caso do Microsoft Windows 2000, sendo grande parte do código escrito em linguagens de alto nível, no caso C/C++. A vantagem de se desenvolver sistemas operacionais em linguagens de alto nível é a portabilidade, ou seja, o sistema pode ser facilmente modificado para poder ser executado em outra arquitetura de hardware. Uma desvantagem dessa implementação é a perca de desempenho, visto que, o assembly por ser uma linguagem de máquina é muito mais rápido e leve.