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).