Sistemas de legado são um eufemismo para aquelas "velharias" de hardware e de software com que somos forçados a conviver no dia-a-dia da informática. Todo mundo que trabalha em empresa conhece "aquele" computador escondido num canto, que roda Windows 95, 3.1 ou MS-DOS, por conta de um aplicativo essencial que não pode parar, nem tem atualização disponível.
Os mainframes convivem e lidam com este problema desde os anos 60, usando técnicas de virtualização, onde o mainframe novo simula perfeitamente o ambiente do antigo, permitindo que os aplicativos antigos também continuem rodando. Para a microinformática, o legado tornou-se um problema apenas mais recentemente, pois foi necessário que os PCs existissem durante quase 30 anos para que eles formassem um legado de aplicativos críticos à missão.
Além disso, reescrever software está ficando cada vez mais caro, em contraponto ao hardware que está cada vez mais barato. Não tanto o custo absoluto, que provavelmente até caiu, mas sim o custo relativo, o "rombo no bolso de quem paga". Lembremos que hoje qualquer microempresa possui uma rede de computadores. Ela pode arcar uma vez com o custo inicial de implantação de um sistema, mas não duas.
O legado é ruim pois atrasa a evolução tecnológica, roubando recursos que de outra forma seriam investidos em coisas novas. Também tende a perpeturar o uso de tecnologias obsoletas, inclusive de hardware.
Duas ferramentas poderosas nos auxiliam no tratamento dos legados: virtualização e emulação (simulação). Elas permitem que o hardware evolua de forma mais ou menos desvinculada do software.
Virtualização é criar um ambiente de trabalho "falso" dentro de um ambiente "real". Apesar de falso, o ambiente virtual hóspede imita necessariamente as características do anfitrião. Por exemplo, se o anfitrião é um Pentium, o ambiente virtual do hóspede também tem de ser um Pentium; nem mais, nem menos.
A virtualização é sempre assistida pelo hardware. Esse recurso existe desde os mainframes. Não é útil apenas para legados, mas também para testar coisas novas. Também tem ganhado atenção como ferramenta de segurança, ao confinar serviços sensíveis em uma "caixa de areia".
O simples fato do Windows rodar programas MS-DOS é uma espécie de virtualização, pois cada sessão DOS é um processador de 16 bits virtual e isolado dos demais que possa haver.
A estratégia da virtualização é deixar o máximo possível do software do hóspede rodar usando a CPU do anfitrião. Apenas quando o hóspede tenta fazer alguma coisa "perigosa", como acessar um disco ou a rede, é que o anfitrião precisa assumir o controle.
Emulação, ou simulação, é a recriação de um ambiente de trabalho sem qualquer relação necessária com o ambiente-anfitriâo, e sem auxílio de hardware. Cada instrução de processador do ambiente-hóspede é individualmente simulada pelo emulador.
A princípio, a simulação é mais complexa que a virtualização; mas na prática é mais fácil desenvolver um simulador, e de fato existem muito mais softwares de simulação que de virtualização. Quase todo computador e videogame antigo (ATARI, Sinclair, MSX etc. etc.) possue um simulador correspondente para ser rodado no PC. Aliás, curiosamente, os softwares para computadores de 8 bits costumavam ser desenvolvidos em simuladores que rodavam em mainframes.
Entre simulação e virtualização, existem muitos desafios compartilhados pelas duas técnicas. Por exemplo, tanto um virtualizador quanto um simulador têm de simular alguns dispositivos do computador, proporcionando ao hóspede a ilusão de que ele está rodando num computador de verdade, mas ao mesmo tempo não deixá-lo fazer besteira.
A princípio, deve parecer óbvio que um hóspede virtualizado terá desempenho muito melhor que um hóspede simulado, pois a virtualização usa a CPU diretamente na maior parte do tempo. Porém a diferença é menor do que poderia-se supor. A simulação dos dispositivos "rouba" muito do desempenho máximo teórico de uma máquina virtualizada. Por outro lado, algumas técnicas de compilação just-in-time emprestam desempenho surpreendente a alguns simuladores.
Uma técnica largamente utilizada para melhorar o desempenho das máquinas virtuais é a paravirtualização. Poderíamos chamá-la também de semivirtualização, ou virtualização pragmática, ou virtualização do homem pobre. Consiste na instalação de drivers de dispositivo especiais no hóspede, que comunicam-se diretamente com o anfitrião. Isto alivia o anfitrião da tarefa de simular tais dispositivos.
Ou seja, na paravirtualização o hóspede "sabe" que é um hóspede, existe uma relação aberta entre ele e o anfitrião. Embora argumente-se que é uma virtualização menos pura, menos segura etc. é realmente a mais utilizada na prática pois entrega um desempenho muito bom. Quem usa o VMWare, sabe quanto melhora o desempenho após a instalação do VMWare Tools.
A ubiqüidade da plataforma Intel/IBM-PC torna-a um alvo constantemente abordado em virtualização e emulação. A virtualização permite criar diversas máquinas virtuais, talvez rodando sistemas operacionais diferentes, na mesma máquina física. A emulação permite que um usuário de Macintosh rode aquele programa essencial no Linux ou no Windows sem precisar possuir um PC só para isso.
Uma utilidade menos óbvia da virtualização e da emulação é o desenvolvimento de software. Os jogos de 8 bits eram desenvolvidos em computadores grandes pois isso tornava fácil acompanhar o funcionamento instrução por instrução, bem como salvar a RAM em disco, simular execução acelerada etc. etc. Desenvolver diretamente na plataforma-alvo era praticamente impossível; os loucos que tentavam isso invariavelmente acabavam construindo hardware especial ou mudando o circuito do computador para auxiliar na tarefa.
Mas isso é passado. Há muito tempo os microcomputadores são uma plataforma auto-suficiente e de baixo custo para desenvolvimento. E agora chegamos num ponto que um micro pode simular a si mesmo com velocidade suficiente para uso normal. As ferramentas de desenvolvimento podem subir mais um degrau de qualidade e complexidade.
Segue uma lista parcial de ferramentas de virtualização/emulação.
WINE
O WINE permite que sejam carregados no Linux os executáveis no formato PE (os .EXE e .DLL do Windows). Além disso, emula um grande número de APIs do Windows, traduzindo as chamadas para POSIX ou APIs de bibliotecas do Linux.
O executável Windows em si roda diretamente sobre a CPU, é um processo como qualquer outro. Deste modo, a velocidade de execução é idêntica à nativa. A tradução das APIs não impõe, em tese, grande overhead. Como Windows é voltado para Intel, e não há emulação de CPU, o WINE não funciona em arquiteturas não-Intel.
O grande problema do WINE é que o número de APIs do Windows é muito grande. E cada uma tem suas próprias particularidades não documentadas, bugs etc. Por conta disso, o WINE não roda boa parte dos programas Windows existentes. Opções como VMWare acabam sendo menos frustrantes.
Apareceram alguns subprodutos interessantes do esforço do WINE. Reprodutores de mídia como MPlayer e Kaffeine conseguem carregar DLLs de filmes do Windows, usando versões modificadas do carregador do Wine. Infelizmente, ainda não é algo fácil de adaptar em qualquer programa.
Os esforços recentes do Wine foram mais na direção de permitir a compilação em Linux de programas Windows, o que a mim parece tempo perdido. Teria sido mais vantajoso generalizar o carregador PE, para que programas Linux pudessem acessar rotinas em DLLs binárias, cujos fontes são fechados e às vezes nem existem mais.
User-mode Linux
É um kernel do Linux preparado para rodar como um processo normal, dentro de um sistema-anfitrião Linux. O UML não virtualiza um sistema inteiro, apenas as chamadas de sistema e alguns periféricos comumente acessados pelos processos.
Como os processos que rodam sob Linux, ou sob o User-mode Linux, são por definição bem-comportados (não podem lidar diretamente com o hardware, só podem requisitar serviços ao kernel), é relativamente fácil virtualizar um ambiente para eles.
Como esse tipo de virtualização não envolve emular CPU nem hardware, a velocidade é bastante boa, embora inferior a outras alternativas. O consumo de memória de cada sessão virtual é proporcional ao demandado pelos processos rodando ali dentro (os emuladores vistos mais adiante alocam toda a RAM virtual logo no início da sessão).
A velocidade e praticidade do UML permite o uso do mesmo como ferramenta de segurança. Isolando-se um software servidor num Linux virtual, torna praticamente impossível a um invasor tomar conta do sistema inteiro, mesmo que ele consiga permissões de root ali dentro. Esquemas mais simples como chroot são quebráveis se o invasor torna-se superusuário.
No presente momento da tecnologia, o User Mode Linux tem sido mais usado como ferramenta de desenvolvimento do próprio kernel do que como opção de virtualização para o consumidor final. Os motivos alegados são: velocidade relativamente baixa e dificuldade de uso.
VMWare
O VMware virtualiza a CPU e emula o hardware do IBM-PC, desde a BIOS até os dispositivos tradicionais como disquete. Desta forma, uma sessão VMWare pode fazer tudo que um PC normal faria. O uso mais comum é rodar um sistema operacional dentro de outro (digamos, rodar Windows XP dentro de um Linux).
Como o VMWare não emula a CPU, o código do sistema-hóspede roda diretamente sobre a CPU real, em velocidade nativa. A mágica do VMWare começa quando alguma instrução "privilegiada" é invocada. Neste ponto, o VMWare assume, e cria a ilusão de que tudo correu bem. É também neste ponto que ocorre a inevitável perda de performance.
O desempenho de um ambiente virtual VMWare melhora muito com a instalação das ferramentas VMWare (VMWare Tools) dentro do sistema hospedeiro. Ele instala drivers otimizados de vídeo, clock etc., dispositivos que normalmente consomem muita CPU para serem simulados, e com os drivers especiais passam a comportar-se melhor. Note que esta é a exata definição de paravirtualização. Assim, a instalação do VMWare Tools converte um ambiente virtual num paravirtual.
Muito já se falou sobre as dificuldades de virtualização em x86, dado que algumas instruções x86 são sensíveis (ou seja, podem alterar o estado do computador ou de algum dispositivo) porém não causam um "trap". Tais instruções "malditas" poderiam ser utilizadas pelo hóspede para "quebrar a jaula" e ganhar acesso direto ao hardware do anfitrião.
O VMWare utiliza técnicas complexas e patenteadas para contornar o problema das instruções malditas. Este é um dos motivos pelos quais o VMWare pergunta qual é o sistema operacional a ser rodado pelo hóspede, pois dependendo do hóspede a técnica mais adequada é diferente.
Os chips Intel mais modernos têm a extensão VT-X que resolve de uma vez o problema das "instruções malditas". Porém o VT-X não isenta o VMWare de simular os dispositivos, portanto não traz ganho de desempenho, ao contrário do que muita gente esperava. O VT-X aumenta a segurança e precisão da máquina virtual, além de torná-la mais simples, mas ganho sensível de desempenho continua exigindo a instalação do VMWare Tools.
VirtualBox
Este produto é semelhante ao VMWare porém foi desenvolvido pela Sun, possui versão freeware, e também tem parte do seu código-fonte aberto. Possui versões para Windows, Linux e Mac.
É uma opção interessante para o usuário casual de máqiunas virtuais, se não deseja arcar com o custo de uma licença do VMWare. Porém ainda é um produto com menos recursos (por exemplo, não tem nada equivalente ao VMWare Tools).
Xen
Ao lado do VMWare, o Xen é o produto com mais popularidade dentre os citados neste artigo. Tem bom desempenho, é oferecido em todas as grandes distribuições Linux, e é utilizado por inúmeros serviços de hosting (aluguel de servidores) como o http://rimuhosting.com.
O Xen é um ambiente de paravirtualização, ou seja, sempre exige que o hospedeiro seja uma versão modificada de um sistema operacional, de modo a comportar-se bem no ambiente virtual. Devido a isto, o ambiente Xen mais comum é Linux tanto no lado anfitrião como no hospedeiro, visto que o kernel do Linux tem código-fonte aberto. Apesar disto, o Xen é um projeto separado do Linux e seu código-fonte não está integrado no kernel Linux padrão (embora seja fácil obter o patch e aplicar).
O Xen é também quase inteiramente devotado a ambiente x86, pois baseia-se no fato do x86 ter quatro níveis de segurança. A maioria dos processadores de uso geral tem apenas 2 níveis, e mesmo os sistemas que rodam em x86 só costumam utilizar os níveis 0 (kernel) e 3 (usuário). O Xen exige que o hospedeiro rode no nível 1 (intermediário), o que evita inteiramente os problemas com as instruções "malditas" que o VMWare tem tanto trabalho para tratar, sem depender de usar os chips mais modernos que resolveram este problema mediante extensões à arquitetura.
Os kernels Linux destinados a rodar sob Xen também trazem alguns drivers próprios para ambiente virtual, de modo a melhorar o desempenho, de forma muito semelhante ao VMWare Tools.
Por último, o Xen tem atraído a atenção de diversos fabricantes, inclusive Microsoft, que talvez inclua esta tecnologia no Longhorn Server. É um feito bastante notável este do Xen, obter audiência comercial sem deixar de ser um projeto aberto.
KVM
O grande sucesso de produtos como VMWare e Xen, e o relativo fracasso do User Mode Linux, levou à criação de um novo projeto para virtualização no Linux, denominado KVM. O KVM depende da presença de um chip com a extensão VT-X, o que simplifica seu funcionamento interno, por não ter de lidar com as "instruções malditas" do x86.
O KVM usa uma versão modificada do QEMU para simular os dispositivos, evitando assim refazer um trabalho penoso, e integrando esforços como o excelente projeto QEMU (falaremos dele mais abaixo).
MOL - Mac on Linux
Semelhante a VMWare e Plex86, mas para PowerPC. Roda apenas dentro do Linux e cria um ambiente para rodar o Mac OS 9 ou 10. Na verdade, mais útil seria um LOM (Linux on Mac); talvez um dia o MOL seja portado para Mac OS X e possa também desempenhar esse papel.
A migração da Apple para os chips Intel em detrimento do PowerPC diminuiu a importância deste projeto, pois no mundo Intel já existiam diversos produtos de virtualização, e o MOL depende dos recursos de virtualização do PowerPC, com que apenas os chips Intel mais recentes estão em pé de igualdade.
DOSEMU
O DOSEMU tem praticamente a mesma filosofia do VMWare, porém é um software livre, e cria ambientes virtuais de apenas 16 bits (80286 ou anteriores). Seu objetivo é permitir a carga de sistemas de legado (geralmente MS-DOS) dentro do Linux. Não é possível carregar programas de 32 bits dentro do DOSEMU. (Parece que o Windows 3.1, de 16 bits em modo protegido, chegava a carregar.)
O DOSEMU fornece os serviços da BIOS, e também emula alguns dispositivos de hardware do IBM PC, inclusive placa de som e vídeo VGA. A velocidade dos programas neste ambiente é bastante boa, pois os programas rodam diretamente sobre a CPU. Apenas instruções ilegais e privilegiadas repassam o controle ao DOSEMU. O suporte a programas "sérios" é bastante bom. O suporte a jogos é sofrível (tendem a não funcionar, ou funcionar de forma errática).
Apesar do nome, o DOSEMU não substitui o MS-DOS; é necessária uma licença de DOS para se fazer algo útil. A implementação gratuita do DOS, o FreeDOS, é insuficiente para muitas aplicações sérias. Por suas características, O DOSEMU só funciona em Linux/Intel.
Valgrind
O Valgrind é uma ferramenta de depuração, que lança mão do recurso extremo de emular uma CPU Intel. O código x86 é traduzido para um formato intermediário, semelhante a SPARC RISC, e este então é executado por um interpretador.
Como o objetivo do Valgrind é depuração, seu emulador x86 tem várias limitações, bem como características "anormais" para um emulador de CPU. Só funciona em Linux/x86; só serve para depurar executáveis Linux/x86. O executável não pode ter certos tipos de otimização, nem usar algumas técnicas de baixo nível. Todas as chamadas de sistema relacionadas a memória, como malloc(), são monitoradas de modo a pegar vazamentos, overflows etc. o que em tese escapa à competência de um emulador.
O emulador do Valgrind chega ao requinte de simular cache L1 e L2, o que permite identificar mau uso do cache por parte da aplicação. O interpretador de código intermediário é quase um processador RISC, chega a fazer até "register renaming" para atingir melhor performance. Ainda assim, o programa instrumentado executa em 1/40 da velocidade normal, e pode ocupar muitas vezes mais memória.
Bochs
O Bochs emula especificamente o IBM-PC/Intel. Talvez o mais "puro" de todos os emuladores, pois implementa todos os aspectos da CPU e da arquitetura em C++, e executa os programas x86 instrução por instrução. Absolutamente nenhum atalho é usado para tentar aumentar a performance.
Figura: Windows XP rodando dentro do Bochs, inclusive com emulação de placa de rede e acesso à Internet. O Windows foi utilizado como principal cobaia por ser um sistema não-UNIX, de código-fonte fechado e que só roda em IBM PC, exatamente o oposto do sistema-anfitrião.
Essa filosofia de design tem como ponto forte a portabilidade. Há screenshots do Bochs rodando Windows em Macs e até em iPaqs. Também é possível usar dentro dele qualquer coisa que rode em IBM-PC. Por outro lado, torna a simulação extremamente lenta (1/300 da velocidade nativa). A simples instalação de um sistema operacional pode levar um dia inteiro, ou mais.
A lentidão torna o Bochs praticamente inútil para uso contínuo. Pode ser útil eventualmente para rodar um programa velho uma última vez. Percebo o Bochs mais como uma ferramenta de simulação. Daqui a 40 anos, quando (assim esperamos) IBM-PC for uma lembrança distante, os velhos e os hobbyistas brincarão com o Bochs, assim como hoje brincamos com emuladores de Atari e Sinclair.
A configuração não é difícil, embora pouco chata. O ponto mais delicado foi gerar uma imagem de disco rígido e configurar os parâmetros CHS; é uma herança maldita do ambiente IBM-PC, que *ainda* causa incômodos quando é preciso transplantar um disco rígido real. A dica é usar no máximo 15 cabeças e 63 setores por trilha. O número de cilindros pode ser maior que 1024 se o sistema operacional usado ali dentro for 32 bits.
Também é necessário ajustar manualmente parâmetros como a estimativa de MIPS emuladas, refresh VGA etc. Maus ajustes farão o relógio avançar muito rapidamente, ou muito lentamente. O valor de MIPS tem de ser alto (10 milhões ou acima) para que o Windows XP rode, mesmo que na realidade seu sistema não consiga emular nessa velocidade.
A máquina emulada tem barramento PCI, mas os periféricos são todos ISA. A placa de rede é NE 2000 ISA, mal suportada pelos sistemas mais recentes (mas ainda funciona, com algum esforço). Os pacotes de rede saem diretamente pela placa de rede real, com MAC forjado. É bastante prático, pois conversa com a rede real, até consegue pegar IP via DHCP; mas tem a desvantagem de não poder comunicar-se justamente com o anfitrião. Para suprir isso, pode-se optar pela emulação de rede baseada em TUN/TAP.
DOSBox
O DOSBox é semelhante ao Bochs porém emula apenas o suficiente da CPU Intel e do PC para satisfazer programas MS-DOS. Seu foco principal é permitir a execução de jogos velhos para DOS, embora em tese qualquer outro programa DOS possa ser executado dentro do mesmo.
Também é um software muito portável, e usa a biblioteca SDL. Estranhamente, apresentou o melhor resultado ao ser executado num Macintosh com Mac OS X. O jogo rodou melhor do que no modo MS-DOS de um Windows 95 real!
Uma grande vantagem do DOSBox sobre o Bochs é a facilidade de uso. Não é necessário criar imagens de disco, nem instalar um sistema operacional. O DOSBox vem com uma mini-imagem de disco e um DOS reduzido embutidos. É possível acessar diretórios do sistema anfitrião "montando-os" como drives do DOS dentro do emulador.
Num teste de compilação de programa MS-DOS, o DOSBox mostrou ser mais rápido que o Bochs, embora mais lento que o QEmu, visto mais abaixo. A performance superior é conseguida pelo uso pesadíssimo de inlining no código, o que o torna mais "feio" que o do Bochs.
Deve-se tomar cuidado ao usar o DOSBox para qualquer coisa séria, pois ele deliberadamente não foi feito para isto, embora tenha funcionado bem nos testes que fiz. Mas para jogos, o DOSBox é perfeito e altamente recomendável, até mesmo dentro do Windows.
QEmu
Apesar da filosofia ser basicamente a mesma do Bochs, o QEmu consegue uma performance melhor através de um processo de "compilação" das instruções da CPU emulada, transformando-as num formato intermediário de interpretação rápida (técnica utilizada também pelo Valgrind).
A compilação é lenta, mas o resultado é armazenado num cache, o que dilui o custo de compilação se o mesmo código é executado várias vezes. O desempenho do QEmu fica em torno de 1/20 a 1/40 do sistema-anfitrião. Nesta velocidade, o sistema emulado ainda é bastante responsivo (depende bastante do aplicativo).
Finalmente, o QEmu pode ser utilizado para gerar imagens de disco compatíveis com o VMWare. Isto cria a possibilidade de se criar uma máquina virtual usando-se o QEmu, e depois continuar rodando-a no VMWare Player, que é gratuito e tem desempenho melhor.
Figura: Windows XP rodando dentro do QEmu, inclusive acessando a Internet. O anfitrião é o Mac OS X.
Outra grande vantagem do QEmu sobre o Bochs é estar preparado para emular vários processadores e arquiteturas. No presente momento, há três emulações em estado mais maduro: Intel, PowerPC e ARM. Apenas dispositivos Intel e Macintosh são emulados.
O QEmu não precisa ser usado para simular a máquina inteira; ele também é capaz de rodar em "user-mode", emular apenas a CPU e traduzir as chamadas de sistema. Nenhum programa em user mode tem acesso direto aos dispositivos, o que evita a necessidade de emulá-los. Isto pode ser usado para rodar programas compilados para outras arquiteturas, de forma quase transparente.
Por enquanto, este recurso funciona apenas no Linux. O SDK da plataforma Maemo usa o QEmu desta maneira: executáveis compilados para ARM podem ser rodados normalmente, como se fossem nativos, e usando os dispositivos do computador. O que facilita tremendamente a depuração dos programas antes de sua instalação no Internet Tablet.
O QEmu tem um módulo opcional para Linux/Intel, infelizmente comercial e de código fechado, denominado KQEmu. Ele basicamente converte o ambiente QEmu de emulado para virtualizado, com ganhos de desempenho. Segundo quem já usou, o KQEmu funciona bem, mas seu público é pequeno, pois as soluções de paravirtualização (incluindo VMWare com VMWare Tools instalado) apresentam melhor desepenho.
Por último, o QEmu está sendo usado pelo projeto KVM do Linux para emulação de dispositivos; a virtualização é suprida pelo KVM ao invés do KQEmu.
O QEmu é um projeto muito interessante e que parece ter muito futuro, pois tem encontrado aplicações nas mais diferentes áreas, desde SDK até virtualização.
Virtual PC para Macintosh
O Virtual PC para Mac (produto que hoje pertence à Microsoft) simula/emula um computador i386 num Mac PowerPC. Conceitualmente semelhante ao QEmu, é extremamente bem-feito e bastante rápido. Sua interface lembra a do VMWare, porém funciona ainda melhor.
Com a migração da linha Macintosh para x86, a tendência é o uso de virtualização ao invés de emulação também nesta plataforma, o que é uma pena pois o Virtual PC é talvez o melhor ambiente virtual que já usei.