UNIX, o pai dos sistemas operacionais modernos

Lançado pela primeira vez em 1969, é conhecido até hoje como um dos sistemas operacionais mais importantes da história.

Filipe Chagas
Programadores Ajudando Programadores

--

Dennis Ritchie e Ken Thompson sentados em frente a um computador PDP-11. Crédito da foto: dmr (fonte: http://thetamnews.org/opinion/dennis-ritchie-computer-scientist-dies-at-70/ )

Sistemas operacionais têm por objetivo estabelecer uma camada de abstração entre hardware e software, tirando o encargo do programador de trabalhar diretamente com as especificidades da arquitetura do computador em questão. Eles tornam os computadores mais fáceis de operar, tanto para os programadores como para os usuários.

O sistema operacional UNIX possui recursos interessantes implementados de maneira relativamente simples. Nele, foi implementada de forma bem sucedida a operação com múltiplos usuários e múltiplos processos simultâneos. Também possui uma arquitetura modular, permitindo que componentes de software sejam adicionados e removidos dinamicamente em sua integralidade, eliminando a necessidade de recompilar o código fonte do sistema inteiro sempre que um novo módulo precisa ser incluído. Além disso, ele pode ser adaptado para diferentes computadores de forma relativamente fácil, por ser programado em linguagem C.

Em seus primeiros lançamentos, UNIX era um projeto de código aberto. Ele foi estudado, modificado e reescrito por muitos grupos de desenvolvedores que criaram uma grande família de sistemas operacionais UNIX-Like. A maioria dos sistemas operacionais modernos beberam, de alguma forma, da fonte do UNIX. Vale a pena, para qualquer interessado em tecnologia da informação, conhecer um pouco da história deste antigo e revolucionário projeto de software. Segue adiante, neste artigo, alguns detalhes sobre o contexto histórico e as características do UNIX.

Os primeiros sistemas operacionais eram totalmente feitos em linguagens de montagem (Assembly)

Exemplo de código assembly para pdp-7 (fonte: https://github.com/DoctorWkt/pdp7-unix)

Os primeiros sistemas operacionais eram, geralmente, desenvolvidos utilizando linguagens de montagem (geralmente chamadas pelo nome da família de linguagens que estas integram: “Assembly”). Estas linguagens de programação são, basicamente, notações legíveis para as instruções das suas respectivas arquiteturas de computadores. Na prática, uma instrução consiste de uma combinação de bits que, quando é disposta na unidade de controle do processador, induz uma determinada atividade no circuito eletrônico do computador. Cada arquitetura de computador tem seu próprio conjunto de instruções e, portanto, tem sua própria linguagem de montagem.

Quando as linguagens de montagem são utilizadas para construir programas muito complexos, fazem com que o desenvolvimento destes demandem demasiado tempo e esforço por parte dos programadores. Além do mais, há uma série de necessidades que elas, sozinhas, não são capazes de saciar. Um exemplo de necessidade que as linguagens de montagem não suprem é a da portabilidade. Cada arquitetura de computadores possui sua própria linguagem de montagem, com sua própria sintaxe. Se, por exemplo, houver a necessidade de elaborar um programa que funcione em várias arquiteturas diferentes, caso as linguagens de montagem das respectivas arquiteturas sejam utilizadas no desenvolvimento, este programa terá um código-fonte único para cada uma das arquiteturas, e os respectivos códigos serão diferentes em sintaxe e lógica. Outro exemplo de carência das linguagens de montagem está relacionada ao baixo nível de abstração destas, que dificulta a interpretação dos algoritmos e a identificação de erros lógicos em aplicações mais elaboradas, e isto se dá pela extrema complexidade que os códigos-fonte tomam conforme o programa é desenvolvido.

CTSS e MULTICS, as duas principais descendências do UNIX

Os computadores, muitas vezes, precisam suprir uma demanda de vários usuários utilizando-os simultaneamente e executando várias tarefas ao mesmo tempo. O que possibilita que múltiplos usuários e múltiplos processos sejam executados “simultaneamente” em um único processador é uma técnica chamada time-sharing.

Nos sistemas operacionais de time-sharing, a execução de instruções no processador é revezada entre os processos. Em uma situação onde há, por exemplo, dois processos sendo executados “ao mesmo tempo” pelo mesmo processador, o sistema operacional de time-sharing fica comutando a execução destes dois processos: ele escolhe um processo para ser executado e, depois de algumas frações de segundo, interrompe a execução deste processo para colocar outro processo em execução. Esta troca de processos é feita periodicamente. Ela é acionada por um hardware temporizador (que normalmente é um bloco funcional do chipset) através de uma IRQ (acrônimo de interrupt request, do inglês, “requisição de interrupção”). Quando a IRQ é acionada pelo temporizador, o processador interrompe a execução do programa corrente para executar uma rotina do sistema operacional, que neste caso é a rotina de troca de processos. Esta troca abrupta de processos feita através de interrupções de hardware é denominada preempção. Sistemas operacionais de time-sharing possuem escalonamento preemptivo.

O primeiro sistema operacional a implementar time-sharing foi o CTSS (compatible time-sharing system), desenvolvido no MIT. O funcionamento do CTSS, equipando um computador IBM 7094, foi demonstrado pela primeira vez em 1961.

Após o desenvolvimento do CTSS, o MIT, em conjunto com as empresas Bell Labs e General Electric, tentou criar um sistema operacional mais ambicioso, o qual foi denominado MULTICS (Multiplexed information and computing service). Este sistema tinha por objetivo equipar um enorme computador capaz de suportar centenas de usuários conectados. Os idealizadores do projeto estavam interessados em criar um sistema operacional que fosse capaz de dar suporte a concessionárias de computação: empresas especializadas em distribuir, de forma compartilhada, o tempo de processamento de um único grande computador para vários usuários conectados remotamente.

O projeto MULTICS foi relativamente bem-sucedido. As empresas Bell Labs e General Electric abandonaram o projeto um suas fases iniciais, porém, com muito esforço dos desenvolvedores, o MIT conseguiu dar sucesso e comercializar o MULTICS. Mesmo assim, este sistema não cumpria com as expectativas de seus desenvolvedores, pois ainda que o fosse muito otimizado, os computadores tinham pouco poder de processamento para uma demanda muito alta.

O início do desenvolvimento do UNIX

Ken Thompson (à esquerda) e Dennis Ritchie (à direita), os criadores do UNIX

Algum tempo depois, o cientista Ken Thompson, da Bell Labs, que havia trabalhado no desenvolvimento do MULTICS até a empresa abandonar o projeto, começou a escrever um novo sistema operacional baseado no MULTICS, utilizando um computador PDP-7. Este novo sistema era mais simples que o antigo MULTICS, e recebeu o nome UNIX.

Foto de um computador PDP-7, tirada em 2005 por Tore Sinding Bekkedal, na Noruega. (https://commons.wikimedia.org/wiki/File:Pdp7-oslo-2005.jpeg)

O projeto de Ken Thompson despertou interesse em seu colega de trabalho Dennis Ritchie, o qual passou a participar do desenvolvimento.

A criação da Linguagem C e a transcrição do UNIX.

Capa do livro The C Programming Language, escrito pelos próprios criadores da linguagem

O código-fonte do UNIX, até então desenvolvido em linguagem de montagem, era demasiadamente reescrito, pois para não ficar obsoleto, precisava ser constantemente adaptado para novos modelos dos computadores PDP. A fim de sanar este problema, Ken Thompson reescreveu o UNIX em uma linguagem de programação que ele mesmo havia criado, chamada B. Esta tentativa de dar portabilidade ao sistema UNIX não foi bem sucedida por conta dos problemas e limitações que a linguagem B possuía.

Em uma nova tentativa de dar portabilidade ao UNIX, Dennis Ritchie desenvolveu, baseando-se na linguagem B, uma nova linguagem de programação chamada C. Esta tinha melhorias em relação a antecessora B.

Diferente de um algoritmo escrito em linguagem de montagem, um algoritmo escrito em C não requer tanto trabalho para ser adaptado de uma arquitetura de computadores a outra, já que a linguagem C não possui variações sintáticas ou lógicas para cada arquitetura. Além disso, a linguagem C é, sintaticamente e estruturalmente, muito mais abstrata do que as linguagens de montagem, tornando mais fácil o desenvolvimento e a interpretação dos algoritmos.

Após o desenvolvimento do primeiro compilador para a linguagem C, o UNIX foi em boa parte reescrito, da linguagem de montagem para C. A partir de então, o UNIX passou a ser um sistema portátil. Era possível fazê-lo funcionar em qualquer sistema computacional para o qual houvesse um compilador C, e isso foi um dos fatores preponderantes para que o UNIX se tornasse uma grande revolução no meio da computação.

As principais características do UNIX

Diferenças de organização do MULTICS para o UNIX

Uma das diferenças mais notáveis do MULTICS para o UNIX está no modo como estes são organizados. No MULTICS, as funcionalidades eram separadas em anéis de proteção, que eram basicamente camadas, cada uma delas com um nível de privilégio diferente sobre o controle do hardware. Apenas as funcionalidades do anel 0 eram executadas com privilégio total. Em todos os anéis “superiores”, as funcionalidades do sistema eram executadas com menos privilégios. O objetivo desta organização era fazer com que a menor quantidade possível de funcionalidades fossem executadas em modo supervisor. O sistema de arquivos, por exemplo, era executado no anel 1 ao invés do anel 0.

O UNIX, entretanto, possui uma tradicional organização monolítica. A maior parte das funcionalidades do sistema operacional, como o sistema de arquivos e os drivers de dispositivos, são executadas “dentro” do próprio kernel, em modo privilegiado.

Operação multiusuário

Assim como o MULTICS, o UNIX permite que vários usuários estejam utilizando simultaneamente um mesmo computador, sem que a atividade de um usuário interfira na do outro.

Processamento simultâneo

O UNIX permite que o usuário execute várias tarefas simultaneamente, sem que precise interromper uma atividade para dar início a outra.

Desenho modular

O UNIX possui uma arquitetura modular. Ele é estruturado de modo a permitir que o usuário o adapte às suas necessidades removendo ou adicionando componentes sem comprometer o seu funcionamento. É graças à isso que os sistemas UNIX-Like são utilizados atualmente nas mais diversas aplicações, desde sistemas embarcados simples até grandes servidores de internet.

Portabilidade

Esta é, provavelmente, uma das características do UNIX que mais foi inovadora. O sistema UNIX pode ser adaptado para os mais diversos sistemas computacionais sem muito esforço, por conta da utilização da linguagem C.

Canalizações

Este recurso do sistema UNIX permite que os processos troquem informações através de pipes. As operações de leitura e escrita dos pipes são realizadas com a utilização de file descriptors e chamadas de sistema read e write.

Tudo é arquivo

No UNIX, todas as operações de entrada e saída do sistema são feitas com o uso de file descriptors e das chamadas de sistema read e write, as mesmas que são usadas para ler e escrever informações em arquivos.

Sistemas UNIX-Like

Em suas primeiras versões, o código-fonte do UNIX era distribuído livremente, permitindo que várias instituições contribuíssem com seu desenvolvimento. Entretanto, após alguns anos de desenvolvimento, o UNIX tornou-se comercial e deixou de ser Open-Source. A partir de então, foram desenvolvidos vários sistemas operacionais livres e similares ao UNIX, os quais são chamados de “sistemas UNIX-Like”, tais como o BSD e os sistemas Linux-based.

BSD

Ainda na época em que o Unix era um projeto de código aberto, o código fonte da versão 6 do software foi adquirido pela Universidade da Califórnia, em Berkeley. Com a ajuda dos financiamentos da ARPA (Advanced Research Projects Agency, do inglês, “Agência de Projetos de Pesquisas Avançadas”), do Departamento de Defesa dos Estados Unidos, foi desenvolvido dentro da Universidade de Berkeley o sistema operacional BSD (acrônimo de Berkeley Software Distribution), baseado no código fonte do UNIX. O código binário, assim como o código fonte do BSD, era distribuído livremente sob a licença BSD, uma licença pública muito permissiva.

Atualmente existem diversas variações do BSD, como o FreeBSD, OpenBSD e o NetBSD. Os atuais sistemas operacionais da empresa Apple, OS X (utilizado nos desktops e notebooks vendidos pela empresa) e IOS (utilizado nos Iphones), são parcialmente baseados no BSD.

Screenshot do FreeBSD funcionando em uma maquina virtual

MINIX

Screenshot do Minix 3 com interface gráfica

O MINIX é um sistema operacional UNIX-Like. Foi desenvolvido pelo professor Andrew S. Tanenbaum para fins educacionais. O código fonte do sistema é utilizado como material de apoio do livro “Sistemas Operacionais - projeto e implementação”, escrito pelo próprio Andrew S. Tanenbaum. O nome MINIX é um acrônimo de “Mini UNIX”. Ele destina-se a computadores pessoais, especialmente os IBM PCs.

Capa da terceira edição do livro Sistemas Operacionais — Projeto e Implementação, de Andrew S. Tanenbaum
Andrew S. Tanenbaum em uma apresentação na linux.conf.au, em 2007

O código fonte do MINIX é relativamente simples. Ele é classificado como um sistema de micro-kernel por ter um kernel reduzido, que serve apenas para atividades mais básicas, como o escalonamento dos processos e o gerenciamento da memória principal. Todos os drivers e sistemas de arquivos são deamons, que são executados “acima do kernel”, como programas de usuário. Em contraste aos sistemas de micro-kernel, existem os sistemas de kernel monolítico, nos quais os drivers e sistemas de arquivos são executados como parte do kernel. Tanenbaum defende que sistemas de micro-kernel são mais robustos e seguros do que sistemas de kernel monolítico.

GNU/Linux

À esquerda, o símbolo do projeto GNU. À direito, o pinguim Tux, símbolo do Linux.

Em 1989, o estudante finlandês Linus Torvalds resolveu criar seu próprio kernel de sistema operacional baseado no MINIX, o Linux. Inicialmente, Linus não tinha pretensão de fazer do Linux um grande projeto. Porém, o Linux despertou muito interesse na comunidade de usuários do MINIX (em especial aqueles que estavam insatisfeitos com a resistência de Tanenbaum a aprimoramentos no MINIX), pois o projeto de Linus não tinha fins educacionais e podia ser aprimorado sem preocupação com didática.

Linus Torvalds na LinuxCon Europe 2014, em Düsseldorf

Tanenbaum muitas vezes recebia, pela internet, pedidos de usuários para que novos recursos e aprimoramentos fossem adicionados ao MINIX. A fim de manter o código fonte do MINIX simples e fácil de compreender, Tanenbaum quase sempre recusava os pedidos, o que gerava uma certa insatisfação na comunidade de usuários de seu sistema.

Logo o Linux passou a ser desenvolvido por muitas pessoas do mundo todo, ganhando muitos recursos e tornando-se um poderoso software. Posteriormente, o kernel Linux tornou-se parte do projeto GNU, de Richard Stallman, cujo objetivo era criar um sistema operacional completo e totalmente livre, distribuído sob a licença GPL (que apesar de ser uma licença de software livre, tem suas restrições). A integração do kernel Linux ao projeto GNU deu origem ao sistema operacional GNU/Linux, o qual é base para uma grande família de sistemas operacionais. Entre eles, podemos citar as distribuições Debian, Slackware, Arch, Red Hat, Ubuntu, Fedora, entre muitas outras. O popular sistema operacional de dispositivos móveis Android, da Google, também é baseado no kernel Linux.

Richard Stallman na Espanha, no Parque Tecnológico Walqa, em Março de 2011

Em contraste ao MINIX, os sistemas operacionais baseados no Linux são classificados como de kernel monolítico, pois uma parte significativa de seus recursos estão concentrados no kernel Linux.

Referências

TANENBAUM, Andrew S. Sistemas Operacionais Modernos. 3ª Edição. São Paulo: PEARSON, novembro 2010.

L. STUART, Brian. Princípios de Sistemas Operacionais: Projetos e Aplicações. Tradução: All Tasks. São Paulo: Cengage Learning, 2011. ISBN 978–85–221–0733–9.

THOMAS, Rebeca; YETES, Jean. UNIX TOTAL. São Paulo: McGraw-Hill, 1989.

GROFF, James R.; WEINBERG, Paul N. Sistema Operacional Unix: Um guia conceitual. São Paulo: EBRAS, 1986.

--

--