| |
- Onde Começar?
- Onde eu obtenho a última versão do
código fonte do kernel?
- Como funcionam as versões do kernel?
- O que é um patch?
- Como eu aplico um patch?
- Como eu compilo o kernel?
- O que são módulos do kernel?
- Como eu compilo um módulo?
- Por quê a instrução goto no kernel
Linux é muito usada?
- O canal #kernelnewbies mudou de lugar?
- Quem eu posso encontrar no canal #kernelnewbies?
E no #kernel-br?
- Como compilar o kernel para usar em
máquinas SPARC?
01. Onde Começar?
- Uma pergunta muito comum feita por novatos é "Eu
baixei um enorme tar do kernel e agora eu quero ajudar,
mas por onde devo começar?".
Poucos são aqueles que dominam o kernel por inteiro,
os contribuintes se especializam em uma determinada
parte do Kernel, então nós aconselhamos o mesmo,
se você quer se especializar em TCP/IP não perca
tempo olhando o código de Filesystem.
02. Onde eu obtenho a última versão
do código fonte do kernel?
- O primeiro site que hospeda o código fonte do Linux
kernel é o servidor dedicado www.kernel.org
Existem diversos "mirrors" deste site ao redor do
mundo e links para cada país. Para acessar o mirror
de um determinado país use http://www.CODE.kernel.org,
onde CODE é o código apropriado de cada país. Por
exemplo, br é o código do Brasil, deste modo
o principal espelho (mirror) do país é o site
www.br.kernel.org. Você pode
baixar o fonte do kernel em ftp.br.kernel.org. Neste endereço você também encontra os
pre-release patches das versões.
03. Como funcionam as versões
do kernel?
- O Linux distingue kernel estável do kernel em desenvolvimento
através de um simples esquema de números. Cada versão
é caracterizada por três números. Os dois primeros
números indicam o número da versão e o terceiro número
indica a release.
O que diferencia a série de desenvolvimento é que
o segundo número é impar, e na série estável este
número é par. Por exemplo, a série 2.4.xx é uma
série estável, enquanto a série 2.5.xx é de desenvolvimento.
Atualmente a última versão estável do kernel é
a 2.4.18, enquanto a de desenvolvimento é a 2.5.6.
04. O que é um patch?
- Um arquivo patch é um arquivo texto em ASCII que
contém as diferenças entre um código fonte original
e um novo código, com o nome dos arquivos e o número
das linhas onde estas diferenças ocorrem. Através
do programa patch (para mais detalhes execute: man
patch) aplica-se o patch na árvore do código fonte
original do kernel.
05. Como eu aplico um patch?
- Esta resposta depende de como o patch foi criado,
especificamente de qual diretório o patch foi feito.
Em geral os patches são feitos no diretório root da
árvore (/usr/src/linux).
Por exemplo, você descompactou o kernel 2.4.17,
e quer aplicar o patch-2.4.18.bz2, e o arquivo patch
está no /usr/src, então faça:
cd /usr/src/linux
bzip2 -dc /usr/src/patch-2.4.18.bz2 | patch -p1 --dry-run
Nós usamos a opção --dry-run para checar
se o patch irá ser aplicado corretamente, ou seja,
mostra o resultado da aplicação do patch só que
sem alterar nenhum arquivo.
A opção -p1, indica qual o ponto da árvore
ele vai aplicar o patch.
Agora que nós já checamos que o patch deve ser
aplicado corretamente, vamos aplicá-lo:
bzip2 -dc /usr/src/patch-2.4.18.bz2 | patch -p1
Pronto, patch aplicado. Vale lembrar que os patches
do kernel não são incrementais, ou seja, o patch-2.4.19-pre2
deve ser aplicado no topo da fonte da versão anterior,
neste caso a 2.4.18.
Se você tem 2.4.19-pre1, você pode voltar para
2.4.18 através do "Reversing a patch". Simplesmente
utilizando a opção -R do programa patch com
o mesmo arquivo patch o qual você tenha aplicado.
Para mais detalhes:
man patch
06. Como eu compilo o kernel?
- Este exemplo assume que você está instalando o kernel
2.4.17. Substitua pela versão que você está tentando
instalar.
Baixe o fonte do ftp.br.kernel.org. Descompacte o arquivo no diretório /usr/src
tar zxvf linux-2.4.17.tar.gz
Se você baixou o linux-2.4.17.tar.bz2, use
bzip2 -dc linux-2.4.17.tar.bz2 | tar xvf -
Entre no diretório onde o kernel foi descompactado.
Você deve rodar este comando para limpar todos os
arquivos de configurações, arquivos objetos de alguma
configuração anterior. Ele garante que a sua nova
árvore está totalmente limpa de configurações anteriores.
Este comando é recomendado quando você vai compilar
pela primeira vez um kernel.
make mrproper
Você terá que configurar o kernel para a máquina
que você tem. Para isto use um dos comandos:
- make config: configuração na linha de
comando
- make oldconfig: se você quiser manter
o .config de versões anteriores
- make menuconfig: menu contruído com ncurses
- make xconfig: configuração em X-Windows
baseado em TCL/TK
Agora, você precisa contruir as dependências
make dep
make clean
make clean limpa os todos os arquivos objetos
e algumas outras coisas que outras configurações
deixaram para trás. Para contruir agora a imagem
do kernel:
make bzImage
Quando este comando terminar, você tem que compilar
os módulos que você configurou:
make modules
Instale os módulos:
make modules_install
Agora, copie a imagem contruída para /boot:
cp ./arch/i386/boot/bzImage /boot/vmlinuz-2.4.17
Edite o arquivo /etc/lilo.conf e acrescente
estas linhas:
image = /boot/vmlinuz-2.4.17
label = 2.4.17
root=/dev/xxx
Onde xxx é a sua partição /, algo
como /dev/hda1.
Copie esta linha da sua outra imagem configurada
no /etc/lilo.conf. Para terminar rode:
/sbin/lilo
Agora reinicialize a máquina.
07. O que são módulos do kernel?
- Módulos são partes do kernel que não precisam estar
sempre em memória. Eles podem ser carregados quando
se fazem necessários pelo kernel e ausentes no restante
do tempo. Na maioria das vezes são drivers para dispositivos.
Imagine por exemplo os drivers para o seu CD-ROM,
placa de rede ou som, eles não precisam estar sempre
em memória e assim ocupando espaço que poderia estar
sendo utilizado por alguma aplicação. Em vez disso,
eles podem ser compilados como módulos do kernel,
ou seja, só vão ser carregados para memória quando
você acessar o dispositivo, e removidos quando não
for mais necessário. Para isto o Linux executa periodicamente,
via crontab, o comando /sbin/rmmod -as, o qual
tenta remover os módulos que não estão mais sendo
usandos.
08. Como eu compilo um módulo?
- Em geral, um módulo é compilado assim:
gcc -c -o modulo.o modulo.c -D__KERNEL__ -DMODULE -DLINUX -O2 -Wall -I/usr/src/linux/include
Você tem que usar a mesma versão do gcc que você
compilou o seu kernel. Você tem que especificar
as flags -D__KERNEL__ -DMODULE -DLINUX -O2.
Esteja seguro de que está usando o mesmo kernel
headers que você compilou o kernel e que o PATH
do -I está correto.
09. Por quê a instrução goto no
kernel Linux é muito usada?
- Goto é uma instrução de controle de fluxo, ela
pode realizar saltos para locais específicos. Algumas
formas de escrita do código resultam em executáveis
mais rapidos. Desenvolvedores do kernel recorrem ao
uso do goto em busca de velocidade.
O goto, muitas vezes também pode tornar o código
mais claro (sim, goto também pode ser bom em alguns
casos :), principalmente no caso de tratamento de
erro. Quando uma determinada função obtém para si
vários recursos (aloca memória, obtém um lock, por
exemplo), e realiza operações que podem resuultar
em erro, certas operações devem ser sempre realizadas,
ou então realizadas caso ocorra um erro em qualquer
ponto. Se a função obtém um lock que é "largado"
antes da função retornar, o lock deve ser "largado"
mesmo caso ocorra algum erro.
Este é um exemplo, retirado de drivers/net/ppp_generic.c:
static int
p_connect_channel(struct channel *pch, int unit)
{
struct ppp *ppp;
int ret = -ENXIO;
int hdrlen;
down(&all_ppp_sem);
ppp = ppp_find_unit(unit);
if (ppp == 0)
goto out;
write_lock_bh(&pch->upl);
ret = -EINVAL;
if (pch->ppp != 0)
goto outl;
/* ele faz várias outras operações aqui, removidas
propositalmente para o exemplo ficar mais simples
*/
ret = 0;
outl:
write_unlock_bh(&pch->upl);
out:
up(&all_ppp_sem);
return ret;
}
Neste exemplo, o goto é utilizado para que certas
operações sejam sempre desfeitas, mesmo no caso
de ocorrer um erro. O semáforo sempre será "largado",
independentemente da ocorrência de um erro. O mesmo
acontece com write_unlock_bh() que sempre
é chamado, caso um erro ocorra após write_lock_bh()
ser chamado.
Outro exemplo, retirado de drivers/net/ppp_synctty.c:
static int
ppp_sync_open(struct tty_struct *tty)
{
struct syncppp *ap;
int err;
MOD_INC_USE_COUNT;
ap = kmalloc(sizeof(*ap), GFP_KERNEL);
err = -ENOMEM;
if (ap == 0)
goto out;
/* Aqui, várias operações foram removidas também,
para simplificar o exemplo
*/
err = ppp_register_channel(&ap->chan);
if (err)
goto out_free;
tty->disc_data = ap;
return 0;
out_free:
kfree(ap);
out:
MOD_DEC_USE_COUNT;
return err;
}
Neste caso, há certas operações que são executadas
apenas quando ocorre um erro. Caso ocorra um erro,
a memória alocada previamente não será usada, e
deve ser liberada. Além disso, MOD_DEC_USE_COUNT
também é chamado, quando ocorre um erro, assim,
caso o dispositivo não seja aberto, o "use
count" do módulo não será incrementado.
Nos dois casos, há a vantagem de eficiência do
código, já que o fluxo "normal" do código
não tem o tratamento de erros "enfiado"
no meio, e sim em uma região separada da memória
(aí [resumidamente], o código "principal"
fica menor, e aproveita melhor o cache de memória).
Além disso, há a vantagem da legibilidade e "mantebilidade"
do código, é mais simples de enxergar que parte
da função faz o que, e enxergar o que acontece caso
ocorra um erro (o que pode ocorrer em várias partes
diferentes da função), com a "parte principal"
separada do tratamento de erros. Fazendo uma comparação
grosseira, tem mais ou menos a mesma utilidade que
a utilização de 'try', 'finally' e 'except' (ou
'catch') disponíveis em algumas linguagens de programação.
10. O canal #kernelnewbies mudou
de lugar?
- Sim. Devido a divergências políticas, o canal #kernelnewbies
agora está oficialmente na rede www.oftc.net. Mais informações em www.kernelnewbies.org. Por enquanto, o kernel-br continua
na rede www.freenode.net.
11. Quem eu posso encontrar no
canal #kernelnewbies? E no #kernel-br?
-
| #kernelnewbies |
| |
| Nome Real |
Nick |
Responsabilidade no Kernel |
| Arjan van de Ven |
arjan |
kHTTPd,Powertweak |
| Andre Hedrick |
ata |
IDE |
| Jens Axboe |
axboe |
Camada de CDROM/DVD |
| Ralf Baechle |
Bacchus |
Linux-MIPS |
| Ben LaHaise |
bcrl |
Gerenciamento de memória |
| Dave Jones |
davej |
Powertweak, random hacks |
| Erik Mouw |
erikm |
ArmLinux, SA1100-Linux |
| f00f |
f00f |
Larting, jumping, and logging |
| Christoph Hellwig |
hch |
Filesystems, kbuild, kernel cleanup |
| Jeff Dike |
jdike |
User Mode Linux |
| Jeff Garzik |
jgarzik |
Network drivers, PCI, kernel cleanup |
| Greg Kroah |
kroah |
USB |
| lxrbot |
lxrbot |
O canal oracle. |
| Thiago Rondon |
maluco |
Random hacking |
| Marcelo W. Tosatti |
marcelo |
drbd, Alta Disponibilidade, RPM do kernel
da Conectiva |
| John Levon |
movement |
oprofile, random minor hacking |
| Fabio O. Leite |
olive |
drbd, Alta Disponibiliade, heartbeat |
| Juan Quintela |
quintela |
Gerenciamento de Memória |
| Rik van Riel |
riel |
Gerenciamento de Memória |
| Russell King |
rmk |
Linux/ARM |
| Tigran Aivazian |
tigran |
Random hacking |
| Steve Dodd |
TC |
NTFS rewrite, random hacking |
| Daniel Phillips |
phillips |
TUX2 filesystem, ext2 improvement, memory
management hacking |
| |
#kernel-br |
| |
| Edison Junior |
EFJ |
|
| Andrea Fabiana |
fabiana |
|
| Guilherme Polo |
polo |
|
| Thobias Trevisan |
thobias |
|
| Eduardo Habkost |
boto |
|
| Vinícius Líbera |
dm1tri |
|
| Caio Begotti |
caio1982 |
|
| Lucio F. Maciel |
gcc_ |
|
| José Alves |
R_ealitY |
|
| Fábio Minami |
sussumo |
|
| Wellington Castello |
nerdwell |
|
12. Como compilar o kernel para
usar em máquinas SPARC?
- O procedimento para instalar o kernel é muito
parecido com o de uma arquitetura x86. Mas mesmo assim
vou listar todos os passos.
- baixe o kernel que você deseja em http://www.kernel.org
- descompacte o kernel
no /usr/src, faco o link do linux para o novo
dir (ln -sf /usr/src/linux-x.y.zz linux)
- entre no diretório /usr/src/linux
- rode os comandos
default make mrproper, make menuconfig, make dep,
make clean
- agora aqui temos a primeira diferença,
para gerar a imagem do kernel nós não
utilizamos o make bzImage nem o make zImage, para
gerar a image utilizamos o comando make vmlinux.
Isto é devido ao fato de não existir
tamanho limite em SPARC, deste modo não
precisamos comprimir a imagem do kernel.
- próxima diferença, a imagem gerada
pelo comando anterior fica no diretório
raiz do fonte, /usr/src/linux, assim rode o comando
cp vmlinux /boot/vmlinux-x.yy.zz
- make modules && make modules_install
Em SPARC existem um loader diferente, ele é
o SILO (Sparc Improved boot LOader). Note que o SILO
é mais poderoso que o lilo, assim você
não precisa rodar o comando silo toda vez que
você mudar o arquivo /etc/silo.conf.
SILO consegue ler sistemas de arquivos ext2, assim
ele pode ler o silo.conf durante o startup para descobrir
qual o kernel você quer 'bootar'. Isto é
diferente do lilo, onde ele não consegue ler
um sistema de arquivos e precisa ter em seu map loader
um offset físico do disco para carregar as
imagens.
Se voce já tiver o silo instalado na sua máquina,
apenas acrescente uma entrada no arquivo /etc/silo.conf:
Finalmente reboot ;-) e para saber mais, visite:
http://www.sparc.org/
http://silo.sourceforge.net/
http://www.ibiblio.org/pub/Linux/docs/HOWTO/other-formats/html_single/SPARC-HOWTO.html
http://shamir.ebizlab.hit.bme.hu/docs/os/Linux/sparc/faq.html
http://www.ultralinux.org/faq.html
|