Sistema Operacional Windows
Eng. Nsungu Filipe Kamukotelo
Engenheiro de Computação, Automação Industrial e Comercial
Técnico em Informática
Material auxiliar a disciplina de Sistemas Operacionais Windows, para o curso técnico em Informática do Colégio Uberaba.
Professor: Nsungu Filipe Kamukotelo
Sistema Operacional é um programa que atua como um intermediário entre o usuário (seja ele um usuário "real" ou aplicativo) e o hardware do computador. O Sistema Operacional cria uma camada de abstração entre o usuário e o hardware facilitando a vida do usuário e também possui rotinas (bibliotecas) que gerencia todo o seu hardware. Um Sistema Operacional pode ser definido como um gerenciador dos recursos que compõem o computador (processador, memória, I/O, arquivos, etc.). Os problemas centrais que o Sistema Operacional deve resolver são: o compartilhamento ordenado, a proteção dos recursos (do kernel) a serem usados pelas aplicações do usuário e o inter-faceamento entre este e a máquina.
2) O QUE É UM KERNEL?
O Kernel é o software que fornece serviços básicos para todas as outras partes de um SO. De forma mais detalhada, o Núcleo é um conjunto de rotinas que oferecem serviços aos usuários do sistema e suas aplicações, bem como a outras rotinas do próprio SO. Um núcleo pode ser contrastado com um interpretador de comandos, conhecido como shell nos sistemas UNIX, o qual não é parte do SO mas que desempenha um relevante papel interagindo com comandos do usuário. Dentre as principais funções do Núcleo estão: - tratamento de interrupções; - gerenciamento de processos (criação e destruição de processos; sincronização e comunicação entre processos, ...); - gerenciamento de memória; - gerenciamento do sistema de arquivos; - operações de E/S. Os serviços do Núcleo são solicitados por outras partes do SO ou por aplicações de usuários, por meio de um conjunto especificado de interfaces de programa (rotinas) conhecidas como Chamadas ao Sistema (System Calls).
Sem o Kernel a cada programa novo que se criasse seria necessário que o programador se preocupasse em escrever as funções de entrada/saída, de impressão, entre outras, em baixo nível, causando uma duplicação de trabalho e uma perda enorme de tempo. Como o kernel já fornece a interface para que os programas possam acessar os recursos do sistema de um nível mais alto e de forma transparente, fica resolvido o problema da duplicação do trabalho.Quando há periféricos ou elementos de um sistema computacional que o kernel não cobre, então se faz necessário escrever a interface para eles, os chamados drivers. Geralmente, os kernels oferecem uma função para se executar chamadas de sistema, como por exemplo a ioctl() do Linux. Valendo-se dessa função, podem-se escrever rotinas para qualquer periférico. As responsabilidades do kernel consistem, genericamente, em abstrair interfaces de hardware diversas e gerir os recursos do computador, permitindo que os programas vulgares utilizem estes recursos concorrentemente de forma segura e padronizada, fornecendo a estes uma interface unificada para os diversos componentes do sistema computacional. O kernel deve também gerir a entrada e saída, de modo a assegurar que apenas um programa acede a determinado dispositivo a dada altura. Finalmente, o kernel deve disponibilizar aos programas ordinários, executados em espaço do usuário, uma interface uniforme para aceder aos seus serviços.
3) A IMPORTÂNCIA DO KERNEL NO GERENCIAMENTO E ADMINISTRAÇÃO DO S.O.
Imagine o Kernel como o cérebro e o coração de um sistema operacional. Kernel de um sistema operacional é entendido como o núcleo deste ou, numa tradução literal, cerne. Ele sozinho não serve para nada, mas sem ele o resto do corpo também não vai muito longe.
3.1) CHAMADAS DE SISTEMAS
As chamadas ao Sistemas são um mecanismo que tem por objetivo proteger o Núcleo do sistema e de acessar os seus serviços. Quando uma aplicação ou um programa deseja utilizar algum serviço do Sistema Operacional, realiza a chamada por meio de uma Rotina( procedimento de biblioteca) e essa rotina acessa a System Calls que retorna o dado(objeto, instrução) requerida.
Para melhor entendermos, vamos usar de exemplo a System Calls Read( já que quase todos os livros de S.O usam esse exemplo.):para podermos acessar a System Calls Read é necessário fazer uma chamada através da rotina da biblioteca, que por ocasião tem o mesmo nome Read.E quem faz essa chamada a biblioteca é o programa ou o usuário. Que no caso se o programa é escrito em C ficaria assim: contador = read (arquivo,buffer,nbytes)
A System Calls após receber a chamada da biblioteca, vai no lugar alocado e retorna o resultado de nbytes do arquivo ao usuário.
Para melhor proteção do núcleo do S.O, existe dois níveis de acesso: um que pode entrar e no Kernel e interagir com ele, tem o poder de comprometer o sistema pois atuam diretamente no hardware. Mas só o S.O, por segurança, tem acesso a esse modo e acesso total de instrução do processador(modo de acesso privilegiado), e outro não privilegiado que não fornece nenhum tipo de perigo pois tem acesso a um número reduzido de instrução(modo usuário).
Existe também um interpretador de comando que é extremamente útil chamado de Shell.Este programa é uma interface primária entre o usuário e o S.O, ele e o núcleo são programas separados que se comunicam através de um conjunto de System Calls . Nele o usuário digita um comando e o Shell comunica-se com o núcleo e pede que crie um processo filho. O processo filho executará o comando através de uma System Calls . O Shell esperará que o processo filho termine para que possa novamente voltar a estar ativo.Quando o processo filho termina ele através de outra System Calls avisa o núcleo, que por sua vez avisa o Shell pra que volte a se ativar.
È importante verificar que o Shell é um programa comum de usuário que não necessita de muitas capacidades para que possa interagir com o programa.
Este programa Shell não vem nativo no S.O
Processo é o conceito central em qualquer sistema operacional, uma abstração de um programa em execução, ou seja, o programa é o código e o processo é a execução. Todos os computadores modernos podem fazer varias coisas ao mesmo tempo, em quanto executa um programa do usuário, ele pode estar lendo os dados de um disco e também enviando algo para ser impresso. Na realidade ele esta executando vários processos, saltando um a um tão rápido que nos da a falsa impressão que estão sendo executados todos ao mesmo tempo, é o que chamamos de processos seqüenciais.
Quando o sistema operacional é carregado ele aciona vários processos, alguns em primeiro plano, que são os que interagem com o usuário, e outros em segundo plano, que são aqueles que estão prontos para serem usados a qualquer momento, como por exemplo, um programa para aceitar mensagens eletrônicas, ele fica inativo a maior parte do dia, mais é acionado ao momento que chega uma mensagem. Novos processos são criados de acordo com a necessidade do sistema. O processo em execução emitirá chamadas ao sistema para criar novos processos para ajudar em seu trabalho, esses processos criados chamamos de processos filhos. Na maioria das vezes o processo termina porque já fez seu trabalho, contudo existem algumas condições como: saída normal (voluntária), saída por erro (voluntária), erro fatal (involuntário) e cancelamento por um outro processo (involuntário).
Em alguns sistemas existe uma hierarquia de processos, quando o processo pai cria um processo filho e esse cria outros processos eles ficam de certa maneira associados, isso é observado no Unix, já o Windows não apresenta nenhum conceito de hierarquia de processos, todos são iguais, a única diferença é que o pai quando criado é dado um identificador especial (chamado handle).
Existem três estados dos processos, ele pode estar em execução (usando realmente a CPU naquele instante), pronto (executável; temporariamente parado para dar lugar a outro processo), bloqueado (incapaz de executar enquanto um evento externo não ocorrer). Os dos primeiros processos são similares já que eles vão executar, o segundo só que aguarda uma CPU disponível pra ele, já o terceiro é diferente dos demais, pois o processo não pode executar mesmo que a CPU não tenha nada pra fazer.
3.3) THREADS
Um processo tem duas partes, ativa (fluxo de controle) e passiva (espaço de endereçamento), um thread consiste somente do fluxo de controle, é chamado também de processo leve ou diet. É muito mais fácil e rápido criar threads que processos, muitas vezes os processos usam dados compartilhados, e usar vários threads no mesmo espaço de endereçamento é mais eficiente e mais rápido.
Sendo uma linha de execução a thread pode dividir a si mesma em duas ou mais tarefas que podem ser executadas simultaneamente. O suporte técnico é fornecido pelo próprio sistema operacional (SO), no caso da Kernel-Level Thread (KLT), ou implementada através de uma biblioteca de uma determinada linguagem, no caso da User-Level Thread (ULT). Uma thread permite que o usuário de programa, por exemplo, utilize uma funcionalidade do ambiente enquanto outras threads realizam outros cálculos e operações. Os sistemas que suportam apenas uma única thread de execução são chamados de monothread e os sistemas que suportam múltiplas threads são chamados de multithread.
Para a maioria dos casos as threads não são criadas e executadas eternamente, depois de terminado seu trabalho, a thread termina, e as threads filho também terminam, já que as suas tarefas atribuídas se completaram. Isso é importante porque os filhos compartilham recursos com o pai, e se o pai termina os filhos não tem sua funcionalidade completa já que utilizam algumas variáveis do pai.
3.4) MEMÓRIA
Dois métodos gerais de gerenciamento de memória podem ser usados, dependendo (em parte) dos recursos do hardware disponível, a estratégia mais simples denominada troca de processos, consiste em trazer totalmente cada processo para a memória, executa-lo durante algum certo tempo, depois devolve-lo ao disco. Outra estratégia seria a memória virtual, que permite que programas possam ser executados mesmo que estejam apenas parcialmente carregados na memória principal.
Memória virtual é uma extensão da memória Ram, é a junção da memória principal com a secundaria, quanto menos memória tiver o computador mais ele necessitara da virtual. A idéia básica por traz desse conceito é que o tamanho total do programa, ou seja, seu código mais seus dados e a pilha, podem exceder na quantidade de memória física disponível para ele. O sistema operacional mantém as partes ativas do programa na memória e o restante no disco. Como por exemplo, um programa de 16MB que pode ser executado com apenas 4MB, mantendo os 4MB ativo na memória a cada instante, com partes do programa sendo dinamicamente carregadas na memória ou removidas dela de acordo com a necessidade.
A memória virtual também é possível em um sistema com multiprogramação, com pedaços e partes de diferentes programas simultaneamente na memória. Se um programa estiver esperando por outra parte de si próprio ser carregada na memória, ele estará conseqüentemente esperando por E/S, e não estará apto a ser executado, de modo que a CPU poderá ser entregue a outro processo.
3.5) DISPOSITIVOS DE E/S
Uma das principais funções do sistema operacional é gerenciar os dispositivos de entrada e saída (E/S), cuja transferência de dados entre o mundo externo e a memória é possibilitada através do uso desses dispositivos. Eles são conectados ao conjunto memória e processador por portas de E/S de dados, através das quais ocorre a transferência.
Basicamente os dispositivos de E/S podem ser divididos em duas categorias:
• Dispositivos de blocos – a transferência de dados é executada usando-se o método de acesso direto à memória (DMA). O hardware deve estar equipado com uma unidade de controle própria, que será responsável por coordenar a transferência dos dados entre posições específicas da memória e a porta de E/S de dados.
• Dispositivos de caractere – envia ou recebe um fluxo de caracteres. Para cada palavra lida, por exemplo, é necessário que seja executada pelo processador, uma instrução de leitura da porta e outra destinada a fazer com que o processador armazene a palavra na memória
Um dispositivo é conectado ao computador através de um componente de hardware denominado interface. Essa por sua vez é interconectada aos barramentos internos do comutador.
Para cuidar das diversidades de operações de cada periférico, as interfaces empregam no seu projeto um outro componente, o controlador, ou seja, um processador projetado especificamente para realizar uma função, como por exemplo, controlar um disco rígido.
A função básica de um controlador é implementar um conjunto de comandos para o seu dispositivo. O controlador vai traduzir cada ordem colocada no registrador de comando em uma seqüência específica de acionamentos eletrônicos, elétricos e mecânicos que irão realizar a operação solicitada. Mas cada tipo de periférico necessita de um controlador diferente.
Os dispositivos de entrada permitem ao usuário do computador introduzir dados, comandos e programas na CPU. O dispositivo mais comum é o teclado, utilizado na interação direta dos usuários com o computador. O princípio de operação do teclado é simples: gerar um símbolo para cada tecla pressionada. Ele pode ser visto com uma matriz de x linhas e Y colunas nas quais entram em contato quando uma tecla é pressionada. O teclado identifica a linha e a coluna associadas a essa tecla e gera um código denominado scan code (código de varredura) o qual é colocado no registrador de dados da interface do teclado. Outros dispositivos de entrada são as canetas óticas, que transmitem informações gráficas da mesa digitalizadora até o computador. O joystick é o mouse, que converte o movimento físico em movimento dentro de uma tela de computador.
Já os dispositivos de saída permitem ao usuário ver o resultados dos cálculos ou das manipulações dos dados do computador, fazendo uma comunicação no sentido do computador para o usuário.
O monitor é um dos dispositivos de saída de um computador que serve de interface ao usuário, na medida em que permite a visualização interação dos dados disponíveis. A impressora é um periférico que, quando conectado a um computador ou uma rede tem a função de dispositivo de saída imprimindo textos gráficos ou qualquer outro resultado de uma aplicação.
A interação entre a CPU e a interface (controlador), para realizar operações de E/S, pode acontecer de três maneiras diferentes: “E/S programada”, “via interrupções” e acesso direto à memória (DMA)”.
Essa técnica é usada quando não há sistema de interrupção (nos computadores antigos era assim, hoje a técnica só é usada em máquinas simples) Com esta técnica, toda interação entre CPU e o controlador é de responsabilidade do programador. O ciclo de funcionamento é baseado no envio de um comando ao controlar e na espera de sua realização. Por exemplo, o processador envia um comando de leitura ao ccontrolador e, em seguida, fica testando continuamente (em busy loop) o registrador de estado para verificar se o dado solicitado já está disponível. Em caso afirmativo, o proicessador efetua a leitura.
O problema desse método é que as operações de E/S são muitos lentas em comparação com as operações de cálculo. Utilizar continuamente o processador para verificar o andamento de uma operação de E/S representa um desperdício muito grande de tempo de cálculo.
3.5.2) COMUNICAÇÃO VIA INTERRUPÇÃO
Nessa situação, o processador é responsável – via – software apenas por iniciar uma operação de E/S enviando comandos à interface. Após, o processador passa a executar outra tarefa, e o controlador, a operação de E/S. Quando a operação termina, o controlador interrompe o processador, provocando a execução do tratador de interrupção, o qual irá acionar o driver do dispositivo.
3.5.3) ACESSO DIRETO À MEMÓRIA
A técnica de DMA baseia-se no emprego de um hardware especial, o controlador de DMA, para realizar a transferência de dados entre um dispositivo e a memória. Para tanto, o controlador de DMA possui a capacidade de acessar diretamente a memória, sendo então conectado fisicamente ao barramento de dados e de endereços do computador. O controlador de DMA possui internamente uma série de registradores utilizados pela CPU par programar a transferência de dados. Existe um par de registradores para o armazenamento dos endereços fonte e destino da transferência, um registrador que determina quantos bytes devem ser transferidos, um registrador de comando e um de estado. Após acionar o DMA, o processador pode se dedicar a outra tarefa. No término da transferência, o controlador de DMA sinaliza o processador através de uma interrupção de hardware.
A técnica de DMA é mais eficiente que as discutidas anteriormente quando a operação de E/S envolve a leitura (ou escrita) de muitos dados como uma leitura de disco ou a recepção de uma mensagem em uma rede local.
4) TIPOS DE KERNEIS
4.1) KERNEIS MONOLÍTICOS
São mais simples de se fazer e mais da metade dos grandes sistemas usam sua arquitetura. Mesmo com essas e tantas outras qualidades, os kerneis monolíticos tem seus problemas, e por isso se procura outros meios de se criar um kernel, dentre os mais famosos, se destaca o microkernel. Abaixo vai uma pequena lista de problemas dos kerneis monolíticos em geral:
Escrever para o "espaço do sistema" é difícil, já que você não pode usar a maioria das bibliotecas existentes, como a GlibC ou a libC5;
É complexo "debugar" (É extremamente difícil de se usar um debugger em nível de fonte, como o GDB);
Graças às duas primeiras desvantagens, o kernel se torna mais suscetível a bugs;
Reiniciar o computador é necessário freqüentemente (principalmente quando é necessário atualizar o kernel ou adicionar novas funções ao mesmo);
Bugs tendem a ser mais danosos, já que como todas as funções do kernel têm todos os privilégios, um bug em uma função é capaz de afetar áreas, mesmo que sem nenhuma relação direta.
Apesar disso, os SOs Monolíticos ainda conseguem atrair a atenção de desenvolvedores devido a uma complexidade menor do que Sistemas que possuem um microkernel. Tanto que o Linux hoje é uma realidade, sendo um SO bastante usado em servidores em empresas e ambientes acadêmicos.
4.2) MICROKERNEL
É um termo usado para caracterizar o sistema cujas funcionalidades do sistema saíram do kernel e foram para servidores, que se comunicam com um núcleo mínimo, usando o mínimo possível o "espaço do sistema" (nesse local o programa tem acesso à todas as instruções e a todo o hardware) e deixando o máximo de recursos rodando no "espaço do usuário" (no espaço do usuário, o software sofre algumas restrições, não podendo acessar alguns hardwares, nem tem acesso a todas as instruções). A maioria dos microkerneis de hoje são mono-servidores, ou seja, possuem apenas um programa no espaço do usuário fazendo todas as funções do kernel. Isso dá um pouco mais de segurança, já que o código não tem acesso direto ao hardware e permite que o mesmo seja portado para outras arquiteturas mais facilmente, mesmo assim isso não faz com que eles não sejam muito diferentes dos kerneis monolíticos atuais. Os Sistemas que possuem um microkernel, possuem casos de sucesso como é o exemplo do sistema QNX, usado em sistemas de braços de robôs nos Ônibus Espaciais. Alguns desenvolvedores afirmam que o microkernel podem ser mais rápidos e mais fáceis de atualizar e modificar que os sistemas de Kernel monolítico como Linux. Porém, uma outra corrente de desenvolvedores incluindo naturalmente o Linus Torvalds, argumentam que apesar de a princípio um microkernel ser mais simples (já que o Kernel inclui apenas os componentes mais básicos, o restante são todos módulos separados), pois lidar com a troca de dados entre os vários componentes é muito mais complicado do que simplesmente agrupar todos num kernel monolítico. No seu livro "Just For Fun" (Só por Prazer, editora Campus) o Linus dedica várias passagens a defender esta idéia. Chegando classificar a idéia de um microkernel como "uma estupidez".
4.3) KERNEL HÍBRIDO
É um kernel compacto, com apenas as funções principais e alguns serviços não essenciais, que se comunica com módulos "servidores", por exemplo o serviço de impressão. Se o serviço de impressão dá erro o SO continua em pé, pois são separados. O desempenho é mais contido pois o Kernel tem que se comunicar com os "servidores" via mensagens, ou seja, são outros processos.
4.4) KERNEL SPACE
É o modo protegido, onde rodam os serviços/servidores/módulos essenciais. No caso dos Microkernels eles são o mínimo possível, no caso dos monolíticos, vários serviços. Qualquer problema no kernel space pode derrubar o sistema, por isso os defensores dos micro-kernéis acreditam que uma abordagem simples no kernel aumenta a estabilidade e confiabilidade do sistema, já que qualquer serviço problemático pode ser desativado, reinicializado, substituído ou atualizado sem precisar rebootar o sistema.
Por outro lado, o fato de poucos serviços estarem dentro do kernel, normalmente gera uma latência (lag, delay, etc) que era a crítica principal aos micro-kernéis.
4.5) SISTEMAS OPERACIONAIS E SEUS TIPOS DE KERNEL
Kernel Monolítico: BSD; Linux; MS-DOS e derivados, incluindo Windows 95, Windows 98 e Windows ME; Solaris.
Microkernel: Hurd; Minix; QNX.
Kernel Híbrido: Windows NT; Windows XP. MacOS.
5) FUNCIONAMENTO DO KERNEL
Em relação à sua capacidade de processamento, o kernel pode ser classificado em:
5.1) MONOTAREFA (MONOPROGRAMÁVEIS)
Permite a realização de apenas uma tarefa de cada vez. Um dos mais famosos sistemas operacionais monotarefa é o MS-DOS. Nesses sistemas, enquanto o programa aguarda a ocorrência de um evento qualquer, o processador ficará ocioso (“idle”); a memória ficará subutilizada, caso o programa não a ocupe totalmente e os periféricos também ficarão ociosos se não utilizados. Os processos são executados em seqüência e um só inicia após o término do anterior.
5.2) MULTITAREFA (MULTIPROGRAMÁVEIS)
Se caracterizam por permitir que vários programas (tarefas) residam simultaneamente na memória e concorram pelo uso dos recursos disponíveis (apenas um programa detém, num determinado instante, o controle da CPU). São muito mais complexos e eficientes que os sistemas monotarefa. Nesses sistemas, enquanto uma tarefa aguarda a ocorrência de um evento externo a CPU, esta pode atender outra tarefa qualquer, que esteja em condições de ser executada. O sistema operacional se encarrega de gerenciar o acesso concorrente das diversas tarefas aos diversos recursos, de forma ordenada e protegida.
5.2.1) MULTIPROCESSAMENTO (MULTIPROGRAMAÇÃO)
O multiprocessamento pode ser obtido pela configuração de múltiplos processadores que compartilham de uma mesma memória primária (fortemente acoplados) ou de múltiplos computadores independentes do tipo sistemas em rede e sistemas distribuídos (fracamente acoplados), onde cada um tem seus próprios recursos. Os sistemas multiprocessados permitem que vários programas sejam executados em paralelo (granularidade grossa), ou que um programa tenha duas ou mais de suas instruções executadas em paralelo (granularidade fina).
Existem dois tipos de kernel multitarefa:
5.2.2) MULTITAREFA PREEMPTIVA
Nesse sistema há uma “democratização” dentro do processador. O kernel mantém em memória um registro de todos os processos em execução. A esse registro dá-se o nome de árvore de processos, em virtude da estrutura de dados interna ser geralmente uma árvore. Entre outros atributos, essa “árvore” inclui uma informação prioridade (chamada “nice” nos sistemas Unix-like e simplesmente “Priority” nos Windows NT), com a qual o kernel calcula o tempo de CPU que deve dar a cada processo; quando esse tempo acaba, o kernel tira o controle da CPU do processo e o fornece ao processo que vem a seguir na fila. Quando a fila acaba, o kernel volta o controle da CPU ao primeiro processo, fechando assim o ciclo.
5.2.3) MULTITAREFA DE COOPERAÇÃO.
Não há muita diferença comparada ao outro sistema. O que difere é que neste caso, é o uso ou não da proteção de memória. Atualmente a maioria os sistemas utiliza a multitarefa de antecipação. Em certos casos, o kernel não é antecipável, obrigando a utilização desse método para permitir a multitarefa enquanto o processo executa uma chamada de sistema.
6) BIBLIOGRAFIA
Apostila da Universidade de Brás Cubas – Sistemas Operacionais . Consulta em 20 de fevereiro de 2007;
www.guiadohardware.com.br - O Sistema Linux. Consulta em 25 de fevereiro de 2007;
www.guiadohardware.com.br - Kernel. Consulta em 25 de fevereiro de 2007;
www.wikipédia.com.br - Kernel. Consulta em 28 de Fevereiro de 2007;