Archive for August, 2010

O que ler para escrever drivers para Windows

27 de August de 2010

Uma pergunta que sempre me fazem é sobre quais livros é necessário se ler para que se possa desenvolver drivers para Windows. Este é um assunto que eu julgava muito óbvio para se ter um post a respeito, mas com o tempo fui percebendo que este assunto não é tão óbvio para os que estão partindo do zero. Para alguns, escrever drivers é algo inalcançável, que por mais que eles leiam ou tentem aprender, nunca será informação suficiente para começar a meter a mão na massa. Para outros, escrever drivers não é algo assim tão complicado, que da mesma forma que ele aprendeu a escrever aplicações com Visual Basic, alguns cliques seriam mais que suficientes para gerar o driver que ele precisa. Na tentativa de dar uma ideia do caminho e das dificuldades a serem enfrentadas nesta nova empreitada, vou listar alguns livros que considero ser um bom caminho a seguir para se escrever drivers.

Não ensinam isso na faculdade

Entre as tantas vezes que essa pergunta me foi feita, uma vez me perguntaram se isso é ensinado no curso de Engenharia de Computação, que era o curso que eu fazia na época. Não sei se todos aqui sabem, mas Engenharia de Computação é um curso que fica entre a Ciência da Computação e a Engenharia Eletrônica. Tentando reunir os principais assuntos de ambas as graduações, o curso não dá tanta ênfase em software nem em eletrônica. Apesar de estudar hardware, microprocessadores, linguagem C e sistemas operacionais, não chegamos nem perto do assunto drivers. Sabemos que eles existem e qual sua função, mas nada que chegue nem perto do exemplo mais simples desse blog.

Pô Fernando, como driver é software, então o curso de Ciência da Computação deve ensinar drivers.

Na verdade, os assuntos vistos em Ciência da Computação tratam de soluções mais alto nível, com mais detalhes em algoritmos específicos para problemas complexos. O fato é que esse curso fica mais distante do desenvolvimento de software básico. No mestrado isso fica ainda mais raro na área de software.

Driver é software de baixo nível, mas não exagere

Tenho um amigo que sempre gostou de estudar tudo nos mínimos detalhes. Tudo bem se a pessoa é um apaixonado por um determinado assunto e quer entendê-lo completamente, mas se o objetivo é escrever drivers, creio que seja melhor estudar apenas o necessário para um início rápido, e depois ir se aprofundando em cada assunto conforme a necessidade. Já vi algumas pessoas dizerem que antes de estudar a linguagem C, gostariam de estudar o completamente a linguagem assembly, ou mesmo começar a estudar o datasheet do processador Intel para ter o completo domínio sobre o assunto. Calma lá gente!

Eu aprendi a programar a linguagem C durante meu colegial técnico, eu não conheço as principais referências sobre o assunto, mas o livro que li é simples e, com relação à linguagem C, é abrangente o suficiente para programar. Por isso recomendo o livro Treinamento em Linguagem C. Você não vai precisar comprar verdadeiras bíblias sobre o assunto, que discutem qual a melhor forma de se compilar um determinado algoritmo.

A grande maioria dos drivers que vi nestes quase 10 anos de experiência em Kernel são escritos em C, e não em C++. A linguagem C é transparente e confiável. Não estou dizendo que não se deve confiar no C++, mas que com o tempo você olha para o código em linguagem C e consegue imaginar como seria o assembly gerado por ele. Isso ajuda bastante quando você precisa depurar sistemas onde os fontes não batem perfeitamente com a versão que você tem, ou mesmo na tentativa de entender situações onde não se tem o fonte. O C++ tem suas armadilhas com sobrecarga de operadores, templates e classes. Olhando para o fonte fica difícil imaginar o que realmente vai acontecer quando aquela linha for executada. Eu mesmo já desenvolvi drivers em C++ e já dei curso numa empresa onde Walter Oney deixou seus fontes de um driver todo em C++. Acho que é uma escolha pessoal, mas o fato é que você não precisa estudar C++ para escrever drivers.

Também já ouvi dizer “Primeiro vou aprender C++ completamente para depois começar a estudar o Kernel”. Acho que não preciso dizer que isso é completamente desnecessário. Sem falar que ainda não sei se é humanamente possível aprender C++ completamente.

Preciso ler Charles Petzold?

No curso que ofereço sobre desenvolvimento de drivers, um dos pré-requisitos é API básica do Windows. Quando digo básica, estou me referindo à manipulação de objetos de sistema, tais como arquivos, eventos, threads, processos, memória virtual e coisas do tipo. Não queria adentrar no universo sobre loop de mensagens, MFC, WTL e inúmeros conceitos de User-Mode que não serão utilizados em Kernel.

Um excelente livro sobre a arquitetura interna do sistema é descrita com muitos detalhes no livro Windows Internals 5th Edition. O único problema é que o livro tem mais de mil páginas e isso é um verdadeiro pé no freio para quem está empolgadão para sair escrevendo drivers. Uma alternativa viável é a temporária substituição desse livro pelo Inside Windows NT 2nd Editon. Um livro tem a metade do tamanho do Windows Internals e que traz os conceitos mais importantes sobre o sistema e que ainda são empregados no Windows 7. Quando você estiver mais a vontade, então poderá ler o Windows Internals, e quem sabe, até tirar uma certificação sobre o assunto.

Modelo Legacy

Depois de entender um pouco sobre a arquitetura do Windows, você já poderá começar a estudar o assunto chave. Mas para isso, você deverá escolher que tipo de driver você pretente desenvolver. O modelo mais antigo é o Legacy, que apesar de ter iniciado no Windows NT 3.51, ainda roda sobre o Windows 7. Este modelo não faz interações com o Plug-And-Play Manager, mas ainda é o modelo empregado no desenvolvimento de File Systems até hoje. Todas as regras usadas no modelo Legacy são também utilizadas no modelo WDM. Dessa forma, estudar o modelo Legacy é uma ótima introdução para estudar WDM ou drivers File System. O livro que recomendo para desenvolvimento Legacy é o Windows NT Device Driver Development. Estudar o modelo Legacy dá a oportunidade de o leitor se aprofundar em conceitos básicos e essenciais no desenvolvimento em Kernel Mode. Por ser um modelo mais simples, o cérebro do leitor consegue absorver com mais qualidade questões como: manipulação de IRPs, memória virtual, níveis de execução de um thread, mecânicas de sincronismo, objetos do sistema e por aí vai.

O leitor que estudar o modelo Legacy estará bem mais preparado para lidar como modelo WDM, que possui regras próprias que serão aplicadas utilizando os conceitos já adquiridos no modelo Legacy. O mesmo se pode dizer com relação ao desenvolvimento de drivers de File System. Apesar de os drivers de File System serem desenvolvidos em Legacy, não significa que ao aprender o modelo Legacy, aprende-se File Systems automagicamente. Este também é um assunto que requer um estudo dedicado.

Windows Driver Model (WDM)

Se o seu modelo alvo é WDM, então um bom livro para começar é o Windows 2000 Device Driver Book. Isso porque o grande problema dos livros de desenvolvimento de drivers é que muita teoria é necessária para se fazer um driver. No modelo WDM a coisa fica ainda mais carregada. Este não é o melhor livro de WDM que conheço, e já vi comentários em listas de discussão dizendo que este livro é conhecido pelos seus erros. O fato é que ele faz uma apresentação simplificada, e o melhor de tudo é que o autor cria um driver básico no início do livro e depois vai colocando mais conceitos em prática.  Com isso o leitor vai escrever um driver de exemplo antes de morrer louco com tanta teoria.

Depois de ter uma base em WDM, então você já estará pronto para ler um livro de gente grande, e não estou me referindo às revistas de nudez. O livro Programming the Windows Driver Model 2nd Edition é realmente muito bom. Eu mesmo já o li umas três vezes, mas como eu comentei antes, muitas páginas são necessárias para que o leitor possa começar a ver as coisas como um todo. Toda essa teoria cansa e confunde um leitor que está começando no assunto.

Drivers de File System

Se você é um dos poucos seres vivos desse planeta que precisam desenvolver ou dar suporte a drivers de File System, então estudar o modelo Legacy foi tranquilo. Alguns me perguntam: “O que tem de tão complicado em escrever drivers de File System?” O problema é que além dos conceitos do modelo Legacy, você precisa lidar com os próprios conceitos utilizados na integração dos drivers de File System com outros componentes do sistema. Estou falando dos seus inseparáveis amigos Memory Manager e Cache Manager. Várias estruturas e regras são impostas pelo sistema para que este componente possa cumprir seu papel de forma estável e eficiente. A falta de livros sobre o assunto adiciona alguma adrenalina ao processo de aprendizado. O livro Windows NT File Systems Internals é o único livro que trata do assunto para Windows. Espera-se que a OSR, empresa que atualmente detém os direitos deste livro, possa lançar uma versão atualizada dele, mas como o público alvo é restrito, talvez não haja incentivo bastante para a concretização disso.

Escrever drivers de File System é complicado e pode-se até imaginar que esse é o tipo de driver mais complicado que existe de se escrever, mas segundo a OSR e outras autoridades no assunto, essa posiçãp de driver mais complexo é ocupada pelos filtros de File System. Isso porque além de ter de conhecer as regras que drivers que File System precisam seguir, os filtros ainda não recebem todas as notificações que um o próprio driver recebe. Escrever esse tipo de filtro é estar entre duas caixas pretas que conversam com alta intensidade e intimidade, e ainda agregar valor a esse serviço. Quando fiz meu curso de Drivers de File System na OSR, Tony Mason disse que as coisas ficam realmente interessantes com a chegada do NTFS transacional.

Diante de tanta dificuldade, a Microsoft criou a classe de drivers chamada MiniFilters, que é uma espécie de Miniport driver para filtros de File System. Infelizmente ainda não existem livros que trate deste assunto. Você vai ter que encarar esse tópico no site do MSDN. O detalhe aqui é que minifilter drivers são módulos carregados pelo Filter Manager, que do ponto de vista do sistema, é mais um filtro de File System Legacy. Desta forma, conhecer o modelo Legacy é uma mão na roda na hora de depurar isso tudo.

Windows Driver Foundation (WDF)

Que o modelo WDM é complexo e trabalhoso, acho que todos concordamos. A fim de evitar tanta complexidade na hora de escrever drivers, a Microsoft criou um novo modelo que se apoia no WDM para implementar todos os comportamentos padrão de um driver por default. Isso significa que você pode escrever um driver de dispositivo e deixar que o framework faça a maior parte do trabalho com relação ao plug-and-play, gerenciamento de energia e inúmeros conceitos que são iguais para a grande maioria dos drivers. Caso você queira um comportamento especial em uma determinada situação, basta registrar a rotina de callback e ser feliz (ou não). O WDF traz dois frameworks, o Kernel-Mode Driver Framework (KMDF) e o User-Mode Driver Framework (UMDF). Desenvolver drivers em KMDF traz algumas poucas restrições em relação a WDM, mas vale a pena escrever um driver novo em WDF. Drivers em User-Mode trazem maiores restrições, principalmente ao barramento que seu dispositivo está e quão rápido o driver precisa ser. O livro Developing Drivers with the Windows Driver Foundation ainda é o único que trata deste assunto. Mais uma vez, muita teoria é apresentada até que um exemplo prático apareça. Outra característica interessante sobre este livro é que ambos os frameworks  são apresentados simultaneamente. Assim, você aprende a desenvolver drivers em KMDF e UMDF ao mesmo tempo. Dependendo do leitor, isso deve até dar um barato.

Se o que você quer mesmo é desenvolver driver em User-Mode, então vamos repensar a questão do C++. Como um driver UMDF deve ser implementado em COM, alguns recursos do C++ agora são requisitos básico para um desenvolvimento confortável. Mais uma vez vou recomendar um livro da Viviane, o Treinamento em Liguagem C++, que sob meu ponto de vista é suficiente para escrever drivers com relação à linguagem. Depois você pode se tornar um mestre ninja com Boost, STL e outras coisas que eu nem imagino.

Depois do C++, uma boa dose de COM vai bem. O livro que meu amigo Strauss me empresou, que foi direto ao ponto de forma clara e simples é o Essential COM do Don Box.

Toda essa base teórica lhe dará bagagem para que você possa escolher um tipo de driver e se aprofundar nele. Mesmo dentro do assunto Kernel, ainda existem inúmeras especialidades de drivers. Não pense que você poderá aprender este assunto completamente antes de sair desenvolvendo, então escolha logo o seu livro e coloque a mão na massa.

Até mais! 😉