Neste livro vamos incorporar textos que explicam como desenvolver para o kernel Linux. O Dougsland tem texto de http://wiki.tchelinux.org/index.php?title=Kernel que pode encaixar bem aqui e com certeza vamos encontrar, traduzir e escrever mais.
Ao trabalhar com uma base de código fonte tão grande quanto o kernel, certamente é de grande valia ter ferramentas que ajudem a entender como as peças se encaixam. Essa página tem como objetivo fornecer indicações para as ferramentas mais comumente utilizadas para tornar as suas primeiras incursões nas terras do kernel tão produtivas quanto possível.
Talvez a ferramenta mais importante é um bom editor de texto. As escolhas mais populares emacs e qualquer clone do vi, vim são as opções mais amplamente utilizadas atualmente. Geralmente, os editores de texto escritos para programadores são programáveis e tem características tais como colorização de sintaxe, ocultação de texto, casamento de chaves, e integração fácil com ferramentas de gerenciamento de código fonte, tais como make(1), cvs(1), reformatação de texto, pesquisa em páginas de manual, e mais.
Uma vez que você tenha escolhido um editor particular, você irá precisar fazer o download da árvore de desenvolvimento (source tree) do kernel com a qual vc quer trabalhar. Existem diferentes possibilidades à disposição.
Gerenciamento do código fonte do Kernel com o git
Se você quiser obter a última versão do código fonte do kernel, você irá precisar do git. Você pode obtê-lo aqui.
Existem ótimos Guia para o GIT em inglês (aguarde, em breve versões em portugues):
Arquivos tar com o Kernel
A maneira alternativa, mais "clássica", para fazer o download da árvore do kernel é baixar um arquivo compactado diretamente do site http://kernel.org.
Agora você está pronto para editar o código fonte do kernel ou simplesmente navegar nele para aprender. Aonde começar? Uma vez que você comece a ler o código fonte você vai precisar várias vezes procurar a declaração ou definição dessa ou daquela estrutura de dados, macro ou função em particular. A opção mais básica é fazer isso usando uma combinação dos comandos `grep` (ou `egrep`) e
`find`;
find . -exec grep --with-filename minhafuncao '{}' \;
Uma outra maneira é:
find . -name '*.[chS]' | xargs egrep -n "minhaexpressaoregular";
Se você tiver o GNU grep (como virtualmente todas as distribuições de Linux tem) então você pode tirar vantagem da flag "recursiva":
egrep -r --include "*.[chS]" "minhaexpressaoregular" .
Acrescente "-w" à linha de comando para evitar pegar palavras nas quais sua busca seja uma substring.
O comando acima procura no diretório corrente [e em todos os subdiretórios] por arquivos que terminem em .c, .h ou .S, e executa o egrem em cada um deles procurando pelo padrão "minhaexpressaoregular". Você pode substituir "minhaexpressaoregular" por expressões regulares mais complexas ;).
A maneira mais utilizada de navegar no código do linux envolve utilizar o
ctags. Dentro da árvore do kernel execute:
make tags
Para os usuários do vim, após executar o comando acima, basta executar:
:set tags=/usr/src/linux/tags
Após especificar qual o arquivo de tags, no vim basta colocar o cursor sobre a
palavra/símbolo e pressionar Ctrl + ] para ir até a definição
e Ctrl + t para voltar ao ponto original.
Para ir diretamente para uma tag digite:
vim -t tag
:tag tag
Para mostrar as definições semelhantes digite no modo de comando
:ts
Para usuários do emacs, após executar o comando (note a caixa alta no nome TAGS)
make TAGS
M-x visit-tags-table
Para ir para uma definição dentro do emacs, mova o cursor até a palavra e digite:
M-.
C-u M-.
M-*
M-x tags-apropos
Ferramentas de Indexação para Navegação na Internet
Enquanto essa abordagem funciona, outras ferramentas permitem que você indexe toda a árvore do kernel para facilitar a navegação no código fonte. Isso facilita muito na hora de encontrar a localização das coisas no código e permite que você encontre rapidamente as declarações/definições de estruturas de dados desconhecidas.
Alguns sites pagam suas "obrigações" ao arquivar árvores do kernel indexadas:
Utilitários para Navegação
Eventualmente, você irá querer incorporar tais capacidades de navegação em seu editor favorito;
Ferramentas alternativas incluem: freescope, etags, e idutils que criam bancos de dados a serem usados ao pesquisar-se por símbolos C. Cada uma delas tem suas idiosincrasias e características. Algumas se integram melhor com seu editor de texto. (Procure especialmente por plugins para ajudar com a integração.) cgvg é uma outra opção, embora ele aparentemente não use um banco de dados para aumentar a velocidade nas buscas.
Navegue no conjunto de modificações aplicadas ao kernel: [N.T. Links para as árvores Git]
Ketchup é uma ferramenta para gerenciar os fontes do Kernel Linux. Essa pequena ferramenta pode checar a versão do kernel, buscar novos patches do kernel, tornando fácil o processo de checagem e aplicação de novas correções em seu sistema. O ketchup sincroniza o kernel local com o kernel.org.
Usando o Ketchup
Descobrindo a última versão do kernel da serie 2.6
ketchup -s 2.6
Agora da serie 2.4
ketchup -s 2.4
Checando a versão do kernel no Makefile dos fontes
ketchup -m
Atualizando pelo última versão
ketchup 2.6-tip
Encontrando uma url de uma determinada versão
ketchup -u 2.6
Atualizando uma versão em particular
ketchup 2.6.11-rc3
Mais informações: http://www.selenic.com/ketchup
O quilt é uma ferramenta para gerenciamento de pilhas de patches; é muito usado por desenvolvedores do kernel para manter e gerar patches para serem enviados.
Tem as seguintes vantagens:
A referência principal dele é esse How to suvive with many patches
Começando com uma árvore de arquivos qualquer, indique ao quilt o nome do patch que você quer criar:
$ quilt new quilt_tutorial1.patch Patch quilt_tutorial1.patch is now on top
Em seguida, você vai editar os arquivos que você quer que constem no patch. Duas maneiras de fazer isso
quilt edit arquivo1 #adiciona o arquivo e abre o $EDITOR para você editar o arquivo #ou quilt add arquivo1 #apenas adiciona o arquivo no patch, para ser editar em outro editor
Se o arquivo foi adicionado uma vez, não precisa ser adicionado novamente, para o mesmo patch.
Após terminar suas alterações, gere o patch usando quilt refresh
$ quilt refresh Refreshed patch quilt_tutorial1.patch
Isso atualiza o arquivo de patch conforme as últimas alterações presentes nos arquivos. Agora, o patch está disponível em patches/quilt_tutorial1.patch (Se houver diretórios patches em níveis de diretório superiores, ele coloca lá)
O quilt também cria um arquivo series (no diretório patches), que tem toda a lista de patches presente
Depois de ter criado um patch, e executado quilt refresh, pode ser criado um novo patch sobre o patch existente. Basta repetir o procedimento de criar um novo patch (quilt new, quilt edit, quilt refresh)
Por exemplo, ao se criar dois patches em sequencia, é assim que fica o arquivo series
quilt_tutorial1.patch quilt_tutorial2.patch
Uma das grandes vantagens do quilt é permitir voltar no histórico de patches, colocar e tirar patches com facilidade, bem como alterar patches passados (sem muita dor)
Para remover o último patch da série: quilt pop. Pode ser usado quantas vezes quiser (até o fim da pilha).
quilt pop Removing patch quilt_tutorial2.patch Restoring tmp/quilt/arquivo2 Now at patch quilt_tutorial1.patch
Se você examinar os arquivos agora, estarão no mesmo estado de antes, quando só havia o quilt_tutorial1.patch
Neste momento, usando quilt edit, e em seguida quilt refresh, você pode alterar o quilt_tutorial1.patch
Em seguida, quilt push para reaplicar os patches existentes na fila que foram 'poped'.
$ quilt push Applying patch quilt_tutorial2.patch patching file tmp/quilt/arquivo2 Now at patch quilt_tutorial2.patch
Git é um sistema de controle de versões focado em velocidade, escalabilidade e usabilidade para projetos grandes. Além disto, o git oferece um conjunto de pequenos comandos que facilitam o gerenciamento do projeto. Escrito em C e desenvolvido pessoalmente por Linus Torvalds.
Para instalar o aplicativo você pode baixar os fontes neste link, e seguir os passos do arquivo INSTALL que acompanha o software.
git-clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git linux-2.6
Tarefas Básicas
Para gerenciar sua árvore local acesse a pasta que o comando acima criou:
cd linux-2.6-linus-gittree/
E com o conjunto de ferramentas oferecido pelo git, atualize a versão da árvore do kernel em seu Desktop:
git pull git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Desfazendo todas as modificações
git checkout -f
Realizando uma alteração
vim <arquivo a ser modificado>
Verificando todas as alterações
git commit -a
Listando mudanças no diretório de trabalho no formato diff
git diff
Exibindo mudanças do último commit
git diff HEAD
Obtendo um índice de todas as mudanças no diretório de trabalho
git status
Lendo todos os logs
git log
Lendo um o log de um arquivo específico
git log arch/i386/kernel/reboot.c
Baixando um release do Kernel
Para baixar um versão do fonte do kernel, basta checar as versões disponiveis
ls .git/refs/tags
O comando acima vai listar todas as versões disponíveis para a versão 2.6 do kernel, começando da 2.6.11, apartir desta versão que foi abandonado o Bitkeeper para se usar o git, no meu caso quero baixar a versão: v2.6.20-rc7. Então dentro diretório do git executo a seguinte opção :
git-archive –format=tar –prefix=v2.6.20-rc7/ v2.6.20-rc7 | (cd ../ && tar xf -)
Simples assim. O comando acima criará um pasta v2.6.20-rc7 com todos os arquivos desta versão do kernel linux, basta compilar e instalar.
Finalizando
Este texto foi baseado no guia Git Howto.
Consulte outras informações aqui:
http://www.kernel.org/pub/software/scm/git/docs/
http://www.kernel.org/pub/software/scm/git/docs/tutorial.html
Este documento é um pequeno guia introdutório para operações básicas usando o GIT. A maioria das características são apresentadas em comparação com sistemas de controle de versão não distribuídos populares como o CVS e o Subversion.
O GIT é um sistema de controle de versão distribuído. Não há um repositório central, e cada desenvolvedor tem repositórios "particulares" na própria máquina onde está trabalhando. Qualquer um que tenha acesso a um repositório pode criar uma cópia exatamente igual, com todas as informações que o repositório original continha. Todas as cópias de repositórios são equivalentes entre si em funcionalidade.
Para facilitar a compreensão de quem já conhece outros sistemas de controle de versão, farei várias comparações do GIT com sistemas convencionais como o CVS e o Subversion, no texto abaixo, me referindo a eles como "CVS/SVN".
Ao contrário de CVS/SVN, no git não há diferença entre "repositório" e um "checkout" (chamado "working copy" no Subversion). Para obter o código de um repositório, você faz um clone de um repositório (uma cópia completa) na sua máquina.
No CVS/SVN, quando você fez checkout de um repositório remoto, o comando
"commit" pergunta a sua mensagem de log e envia as modificações para o servidor imediatamente. As ações de documentar e publicar suas modificações são inseparáveis.
No GIT, como você possui um repositório completo na sua máquina, você pode fazer commits à vontade no seu clone, e só publicar ou enviar essas informações para um servidor (se houver) quando quiser. Você pode fazer commits menores e mais frequentes, mesmo quando ainda está testando o seu código, pois você sabe que não vai estar commitando código não testado num repositório central.
Cada repositório GIT pode conter vários branches. Alguns são especialmente interessantes porque são criados por default e comumente utilizados.
Geralmente todo repositório tem um branch chamado "master", que
geralmente é o branch principal do repositório (semelhante ao "trunk"
no SVN e a HEAD no CVS).
O "master" é criado por default quando um repositório é criado (git-init-db), e também quando é feito um clone (git-clone). A não ser que você faça questão de trabalhar com vários branches, em geral você vai trabalhar sempre no branch master do seu repositório.
Nota: o parágrafo abaixo não se aplica mais, nas versões mais recentes do git. É necessário revisá-lo.
O branch "origin" é criado automaticamente quando é feito um clone
de outro repositório. Ele é utilizado para manter uma cópia do
repositório "original" quando você tem um clone de um repositório e
quer baixar modificações novas do repositório de onde você fez clone.
Apesar do GIT não impedir você de fazê-lo, é uma má idéia fazer
commits no branch "origin". A sua função é manter uma cópia de um
repositório externo, e commits nesse repositório irão confundir o
git-fetch (a ferramenta que busca modificações novas do repositório
original).
Logo, para tornar o seu uso do GIT mais agradável, siga a seguinte regra: Nunca faça commits no branch origin.
O HEAD não é um branch propriamente dito, mas é como um ponteiro
para o "branch atual". O "branch atual" é o branch onde você está
trabalhando no momento, onde seus commits serão colocados e é o
branch default para a maioria das operações.
Quando quiser trabalhar em outro branch, você pode trocar o branch
atual com o comando git-checkout.
git-clone <repositorio>
Este comando irá criar um repositório que contém uma cópia do
repositório original. O clone criado vai conter os branches do
repositório original, mais um branch chamado "origin".
git-init-db
Este comando irá criar um repositório vazio, ainda sem nenhum commit,
apenas com um branch chamado "master".
Para commitar as suas modificações no branch atual (HEAD):
git-commit -a [-s]
Usar o parâmetro -s é opcional, mas recomendável. Ele adiciona
uma linha "Signed-off-by" na sua mensagem de commit.
O parâmetro -a serve para simplificar algumas coisas. Caso queira
entender melhor o porquê, procure por "index file" na documentação
do GIT.
Caso arquivos tenham sido criados ou removidos, utilize
os commandos git-add e git-rm para adicioná-los e removê-los,
antes do commit.
git-checkout -f
Todas as modificações que não foram commitadas serão descartadas, e
os arquivos serão revertidos para a versão do branch atual (HEAD).
Para ver o log de commits de um branch:
git-log [<branch>]
Caso omitido, o log do branch atual (HEAD) será mostrado.
Para ver o que mudou em cada commit:
git-whatchanged [-p]
Com o parâmetro -p, um "diff" das modificações é mostrado. Sem
o parâmetro, apenas os nomes dos arquivos adicionados modificados e
removidos são mostrados.
Para entender melhor o que vai acontecer caso git-commit
seja executado, você pode observar a saída de:
git-status
git-branch
O branch atual (HEAD) é marcado com um asterisco, na lista.
Para mover para outro branch, para observar o código em um branch,
modificar e commitar no branch:
git-checkout <branch>
Nota: se houver modificações não "commitadas" no branch atual,
o git-checkout pode falhar. Caso queira guardá-las, commite as
modificações no branch atual (git-commit), ou jogue fora as
modificações com o comando git-checkout -f.
Para criar um branch:
git-branch <branch> [<origem>]
O branch criado será uma cópia de origem. Caso não seja especificado,
vai ser uma cópia do branch atual (HEAD).
Para criar um branch, e ao mesmo tempo apontar o "branch atual" (HEAD)
para o branch criado.
git-checkout -b <newbranch> [<origem>]
O comando acima é equivalente a um git-branch seguido de git-checkout.
Autor: Matt Mackall
Página: http://www.selenic.com/mercurial/
Licença: GPLv2
Plataformas suportadas: Linux, *BSD, Mac OS, Solaris, Windows
Mercurial é um sistema para gerenciamento de versões distribuído utilizado por alguns subsistemas do kernel e projetos opensource.
Todos os comandos começam com hg, uma referência ao elemento químico mercúrio
Fedora:
shell> sudo yum install mercurial
Debian/Ubuntu/Kubuntu:
shell> sudo apt-get install mercurial
clone, commit, status, add, remove, diff, extdiff
Cria uma cópia de repositório em um diretório
Exemplo:
shell> hg clone http://linuxtv.org/hg/v4l-dvb
shell> ls v4l-dvb
Envia as alterações para o repositório local
Exemplo:
shell> vi arquivo.c (algumas alterações ocorreram neste momento)
shell> hg commit [arquivo]
Exibe o status dos arquivos do repositório local
Exemplo:
shell> hg status [arquivo]
M arquivo
Os códigos de status são:
M = Arquivo alterado (modified)
A = Adicionado
C = Sem alterações (clean) (Quando usa-se o parâmetro -c)
R = Arquivo removido
! = Arquivo removido mas continua no repositório
? = Arquivo não desconhecido
I = Arquivo ignorado
Sem retorno = Não houveram alterações no arquivo
Sinaliza os arquivos que serão adicionados ao repositório local
Exemplo::
shell> hg add arquivo
shell> hg commit (envia as alterações para o repositório local)
Sinaliza os arquivos que serão removidos do repositório local
Exemplo:
shell> hg remove arquivo
shell> hg commit (envia as alterações para o repositório local)
Exibe as alterações de um determinado arquivo
Exemplo:
shell> hg diff arquivo
Exemplo para visualizar alterações incluindo arquivos binários:
shell> hg diff -a
Opções:
-r = revisão
shell>hg diff -r revisão arquivo
A extensão extdiff permite especificar a ferramenta que sera utilizada para visualizar as alterações feitas em um determinado programa.
Por padrão, a extensão extdiff utiliza a ferramenta diff para comparar os arquivos e validar se houveram alterações.
Porém, é possível facilmente alterar a ferramenta de comparação de código, por exemplo de diff para kdiff3.
1) Adicione a extensão ao hgrc padrão ou ao .hgrc do local
Exemplo 1:
shell> vi /etc/mercurial/hgrc
Exemplo 2:
shell>vi ~/.hgrc
2) Adicione as linhas:
[extensions]
extdiff =
Neste momento será possível especificar a ferramenta para diffs. No exemplo abaixo iremos passar o programa kdiff3 como parâmetro:
Exemplo:
shell> hg extdiff -p /usr/bin/kdiff3
Opções:
-p = Ferramenta (program) por padrão é utilizado a ferramenta diff
-o = parâmetros (options) por padrão é passado ao extdiff as opções -Npru
Ao invés de digitar hg extdiff -p /usr/bin/kdiff3 podemos criar um alias para digitar apenas:
shell> hg kdiff3
Adicione no seu arquivo ~/.hgrc local ou no hgrc geral /etc/mercurial/hgrc
[extensions]
extdiff =
[extdiff]
cmd.kdiff3 = kdiff3
# Caso queira passar opções, remova o comentário e adicione abaixo
# opts.kdiff3 =
Agora já é possível utilizar o novo comando
shell>hg kdiff3
Quem disse que o Linux não trava ?? Que atire a primeira pedra quem nunca viu ao menos um kernel panic na tela ? Pois bem, quando um erro grave ocorre no sistema, entre outras coisas que o kernel faz uma delas é exibir no terminal e/ou sistema de log, uma mensagem bastante conhecida por quem já passou por isso, a famosa mensagem de Oops. Trata-se de um dump do estado do CPU e da pillha do Kernel no momento em que o problema ocorreu. A mensagem de Oops mais conhecida é a que vem acompanhada de um kernel panic. Muitos ao se deparar com isso, percebem que nada funciona (na maioria dos casos), Ctrl+Alt+Backspace, teclas de função, e nem água, ai, simplesmente reiniciam a máquina, podendo causar ainda mais problemas.
Abaixo um exemplo de uma mensagem de Oops:
Unable to handle kernel paging request at virtual address 00010015 printing eip: c01e6608 *pde = 00000000 Oops: 0000 CPU: 0 EIP: 0010:[usb_unlink_urb+8/64] Tainted: P EFLAGS: 00010202 eax: 00010001 ebx: d70c6494 ecx: c7c81000 edx: 00010001 esi: c7c81640 edi: d70c6400 ebp: d70c64f0 esp: d2daded0 ds: 0018 es: 0018 ss: 0018 Process kpilotDaemon (pid: 30778, stackpage=d2dad000) Stack: d892a2ed 00010001 d70c6494 d70c6400 d3df51c0 00000000 d8924350 d70c6494 d3df51c0 d725a000 cc5faa40 c16063c0 c018c460 d725a000 d3df51c0 d3df51c0 cc5faa40 c16063c0 c8117e40 00000001 d3df51c0 bffff0e8 00000000 00000000 Call Trace: [] [] [release_dev+576/1280] [n_tty_ioctl+257/1200] [tty_release+10/16] [fput+76/224] [filp_close+92/112] [sys_close+67/96] [system_call+51/56] Code: 8b 42 14 85 c0 74 21 8b 80 bc 00 00 00 85 c0 74 17 8b 40 18
Esta mensagem pode ajudar aos desenvolvedores do kernel a depurar melhor o problema, e mesmo que você não reporte o bug, você pode se utilizar de um recurso que foi desenvolvido pensando nisto: As Magic SysRq Keys.
Trata-se de uma combinação de teclas que é utilizada para comunicar-se com o kernel do Linux, caso a opção CONFIG_MAGIC_SYSRQ tiver sido habilitada durante a compilação do kernel, ou em /proc/sys/kernel/sysrq.
Basta apertar Alt+PrintScreen+Tecla e a saída (dependendo da tecla) é enviada para o dmesg. Abaixo apenas algumas teclas:
t Lista de tarefas/processos com suas informações detalhadas
u Remonta todas as partições montadas, só que em read-only
m Mostra informações sobre o estado atual da memória
e Envia um sinal do tipo SIGTERM para todos os processos, exceto para o init
Existe a famosa combinação: Alt+PrintScreen+R E I S U B, onde basicamente mata todos os processos, sincroniza os discos, remonta todas os filesystems montados em read-only, e só então reinicia a máquina. Por tanto, antes de "meter o dedão" no botão de power, REISUB