Autor: Elias Carlos Zoby
Toda solução nasce de um problema. Eu queria ter meu
Slackware com kernel da série 2.6, pois ele é melhor e mais rápido
geralmente, mas já havia usado o 2.4.31 e visto que ele era
muito mais veloz nos downloads de internet discada usando o
softmodem Hsp56 MR da Pctel que veio onboard na minha placa mãe
Via M825 v.7.2a. Não sei se com outro hardware ocorre o mesmo.
Então eu precisava de dois kernels. Tenho o linux-2.4.31
e 2.6.22.7. Em cada um necessitava instalar o software para
softmodem, respectivamente slmdm-2.7.10.tar.gz (2.7.8 também
serve) e slmodem-2.9.11-20070813.tar.gz (datas anteriores da
mesma versão também servem). Cada software tem sua forma de
instalação, configuração do modem e uso.
Escolhi o Slackware 10.2 porque é o que possuo, mas
creio que o 11 também sirva. O Slack 12 já não tolera a série
linux-2.4.x, precisaria adaptações de gcc, hotpluging etc.
A escolha do kernel a inicializar é feita colocando-se
os devidos comandos no "boot loader": GRUB (menu.lst), LiLo
(lilo.conf) ou outro. Vide Apêndice 1.
Incompatibilidades aparentes e que precisam ser resolvidas na inicialização:
1) rc.hotplug x rc.udev, ou se usa um ou outro, Udev é melhor e
mais rápido, mas requer kernel >= 2.6.15;
2) rc.modules, cada kernel precisa do seu, ou que sejam escritos
comandos condicionados para cada módulo (exigindo maior trabalho
e conhecimento);
3) rc.local, o software de modem para kernel 2.6 requer que
alguns comandos sejam colocados nesse arquivo, mas o soft do
kernel 2.4 não.
No Slack 10.2 o Udev vem sem configuração, então
precisei aprender a escrever regras para ele e aproveitei para
fazer upgrade para v. 111 do Slack 12. Vide Apêndice 2.
Decidi deixar /etc/rc.d/rc.modules e rc.local para o
kernel 2.6.22.7. Copiei rc.modules do kernel 2.4.31 e rc.local
originais do Slackware para /etc/rc.d/rc.modules-2.4.31 e
rc.local-2.4.
Como não entendo nada de escrevinhação de scripts, e
menos ainda de programação, procurei nos arquivos de
inicialização (rc.S, rc.modules e rc.M, chamados nesta ordem
durante o boot) alguns comandos que determinassem a versão do
kernel e condicionassem ações à resposta obtida. Em rc.modules
há, de forma descontínua, as seguintes partes:
# Determine the version of the running kernel:
RELEASE=$(uname -r)
# Also determine a "short release" such as 2.4, 2.6, etc.
SHORTREL=$(echo $RELEASE | cut -f 1,2 -d .)
# Only load if this is a 2.4.x kernel:
if echo $SHORTREL | grep -qw 2.4 ; then
/sbin/modprobe ide-scsi
fi
Então tendo resposta às variáveis RELEASE e SHORTREL pode-se dar o comando condicionado, exemplificando em kernel 2.4:
if echo $SHORTREL | grep -qw 2.4 ; then
faça alguma coisa
fi
Ou pode-se condicionar à inexistência de determinada resposta:
# Enable PC speaker support for 2.6.x+:
if echo $SHORTREL | grep -qvw 2.4 ; then
/sbin/modprobe pcspkr
fi
A opção -v no grep é algo como "se não" ($ man grep).
Outras opções viáveis são:
# Determine the filename for kernel symbols under /proc.
# (this is ksyms on 2.4 kernels and kallsyms on newer kernels)
if [ -r /proc/ksyms ]; then
faça alguma coisa
elif [ -r /proc/kallsyms ]; then
faça alguma coisa
fi
## Check kernel version to determine module names to use
if [ "`uname -r | cut -f 1,2 -d .`" = "2.2" ]; then
# # This module is for PPP support:
/sbin/modprobe ppp
#else # assume 2.4 or newer
# # This module is for PPP support:
# /sbin/modprobe ppp_generic
fi
Descobertos os condicionantes necessários, optei por
"uname -r" por ser mais simples (KISS).