Compilar el driver Realtek RTL8111/8168B para la rama 3.0 del kernel Linux

En la entrada Problemas con Realtek RTL8111/8168B Gigabit Ethernet se describió como solucionar los problemas de bloqueos, lentitud en la conexión, desconexiones... provocado por el driver, incluido en el kernel, de las tarjetas de red Realtek basadas en uno de los siguientes chipsets RTL8111B/RTL8168B/RTL8111/RTL8168, RTL8111C/RTL8111CP/RTL8111D(L), RTL8168C/RTL8111DP/RTL8111E o RTL8168E. Sin embargo un lector del blog (Ronindo) señalo problemas al compilar dicho driver en la rama 3.0 del kernel.

Hace poco actualicé al último kernel estable de gentoo, sys-kernel/gentoo-sources-3.0.6, y experimenté algunos problemas. En esta entrada se analizará el motivo y se ofrecerá la solución a este problema.

Puede obtener los drivers para su tarjeta de red en la página de descargas de Realtek. Una vez obtenga los drivers para su tarjeta, deberá descomprimir y ejecutar el instalador automático ./autorun.sh Al realizar este paso es probable que le arroje el siguiente error:

agd-desktop r8168-8.024.00 # ./autorun.sh 

Check old driver and unload it.
Build the module and install
install: el objetivo «/lib/modules/3.0.6-gentoo-agd/kernel/drivers/net/» no es un directorio: No existe el fichero o el directorio
make[1]: *** [install] Error 1
make: *** [install] Error 2

Para solucionar esto tan solo deberá crear dicho directorio y volver a lanzar el script de instalación:
agd-desktop r8168-8.024.00 # mkdir /lib/modules/3.0.6-gentoo-agd/kernel/drivers/net/
agd-desktop r8168-8.024.00 # ./autorun.sh 

Check old driver and unload it.
Build the module and install
Depending module. Please wait.
load module r8168
FATAL: Module r8168 not found.
Completed.
agd-desktop r8168-8.024.00 # ls /lib/modules/3.0.6-gentoo-agd/kernel/drivers/net/
r8168.o

Como puede ver, el proceso de compilación funciona correctamente pero falla la carga del módulo. De hecho, tras mirar lo que ha sido copiado a /lib/modules/3.0.6-gentoo-agd/kernel/drivers/net/, verá que no es el driver, o al menos no esta en el formato que el kernel espera encontrar (.ko). Por ello se procederá a revisar los log de compilación tanto de la rama 2.6 como de la 3.0 del kernel, para saber que ocurre al compilar el driver en ambos kernel:
  • Log compilación en kernel 2.6 [+/-] Ver / Ocultar
  • Log compilación en kernel 3.0 [+/-] Ver / Ocultar

Si ha sido cuidadoso al analizar el log, se habrá dado cuenta de la diferencia. En cualquier caso se resaltan a continuación:
install -m 744 -c r8168.ko /lib/modules/2.6.38-gentoo-r6-agd/kernel/drivers/net/
make[1]: se sale del directorio `/usr/src/r8168-8.024.00/src'

install -m 744 -c r8168.o /lib/modules/3.0.6-gentoo-agd/kernel/drivers/net/
make[1]: se sale del directorio `/usr/src/r8168-8.024.00/src'

Como puede observar, cuando se ejecuta el script de instalación en un entorno con un kernel 3.0, la compilación no lanza ningún error pero no se copia el driver correcto r8168.ko, sino r8168.o. Al listar el contenido de r8168-8.024.00/src/ el driver r8168.ko aparece por lo que presumiblemente fue correctamente compilado:
agd-desktop r8168-8.024.00 # ls src/
Makefile           r8168_asf.c  r8168.ko     r8168_n.o     rtl_eeprom.o
Makefile_linux24x  r8168_asf.h  r8168.mod.c  r8168.o       rtltool.c
modules.order      r8168_asf.o  r8168.mod.o  rtl_eeprom.c  rtltool.h
Module.symvers     r8168.h      r8168_n.c    rtl_eeprom.h  rtltool.o

Por tanto, lo único que debe hacer es copiar manualmente el driver de la tarjeta de red a su ubicación correcta, reconstruir la base de datos de dependencia de los módulos (modules.dep) y por último cargar el driver correspondiente. Ojo, si no lo ha hecho, antes de ejecutar estos comandos deberá descargar los drivers en uso con rmmod r8169, o rmmod xxx, el driver de red que este usando actualmente su kernel. A continuación podrá ver un ejemplo:
agd-desktop r8168-8.024.00 # cp src/r8168.ko /lib/modules/3.0.6-gentoo-agd/kernel/drivers/net/r8168.ko
agd-desktop r8168-8.024.00 # depmod -a
agd-desktop r8168-8.024.00 # modprobe -l
kernel/arch/x86/kernel/microcode.ko
kernel/fs/fat/fat.ko
kernel/fs/fat/vfat.ko
kernel/fs/fat/msdos.ko
kernel/fs/isofs/isofs.ko
kernel/fs/ntfs/ntfs.ko
kernel/fs/udf/udf.ko
kernel/drivers/acpi/acpi_pad.ko
kernel/drivers/block/loop.ko
kernel/drivers/scsi/sr_mod.ko
kernel/drivers/scsi/scsi_wait_scan.ko
kernel/drivers/cdrom/cdrom.ko
kernel/lib/zlib_inflate/zlib_inflate.ko
kernel/drivers/net/r8168.ko
video/nvidia.ko
agd-desktop r8168-8.024.00 # modprobe r8168
agd-desktop r8168-8.024.00 # lsmod 
Module                  Size  Used by
r8168                 183437  0 
nvidia              11759386  30 

Llegado a este punto, tan solo le queda levantar la interface y pedir una dirección ip a su router.
agd-desktop r8168-8.024.00 # ifconfig eth0 up
agd-desktop r8168-8.024.00 # ifconfig -a
eth0      Link encap:Ethernet  HWaddr 00:24:1d:cc:4b:e1  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:293 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:19124 (18.6 KiB)  TX bytes:0 (0.0 B)
          Interrupt:16 Base address:0xc000 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:640 errors:0 dropped:0 overruns:0 frame:0
          TX packets:640 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:51928 (50.7 KiB)  TX bytes:51928 (50.7 KiB)
agd-desktop r8168-8.024.00 # dhcpcd 
dhcpcd[4115]: version 5.2.12 starting
dhcpcd[4115]: eth0: broadcasting for a lease
dhcpcd[4115]: eth0: offered 192.168.1.20 from 192.168.1.10
dhcpcd[4115]: eth0: acknowledged 192.168.1.20 from 192.168.1.10
dhcpcd[4115]: eth0: checking for 192.168.1.20
dhcpcd[4115]: eth0: leased 192.168.1.20 for 21600 seconds
dhcpcd[4115]: forked to background, child pid 4144

Por último debe indicar al sistema que driver debe cargar al iniciarse el sistema, para lo cual debe colocar el driver conflictivo en /etc/modprobe.d/blacklist.conf y el driver correcto en /etc/modules.autoload.d/kernel-3.0
agd-desktop # echo "blacklist r8169" >> /etc/modprobe.d/blacklist.conf 
agd-desktop # mkdir /etc/modules.autoload.d/
agd-desktop # echo "r8168" >>  /etc/modules.autoload.d/kernel-3.0

12 comentarios:

#
Mr. Brown Dispatcher dijo...

Simplemente espectacular!

#
Antonio Guillen dijo...

Gracias :-)

Por cierto, no supe muy bien como meterlo en el propio post porque independientemente como construyera la frase, me parecía que la metía con calzador.

Donde dice "De hecho, tras mirar lo que ha sido copiado a /lib/modules/3.0.6-gentoo-agd/kernel/drivers/net/, verá que no es el driver, o al menos no esta en el formato que el kernel espera encontrar (.ko)."

La cuestión es que en el paso del kernel 2.4 al 2.6 cambió la forma en la que se trabajaba con los ELF object:
- En la rama 2.4 los objetos (xxx.o) los interpretaba un programa de espacio de usuario, preparaba una imagen y se la pasaba al kernel en ejecución.
- En la rama 2.6 en adelante, los drivers (xxx.ko) son pasados directamente al kernel y el se encarga de todo. En este caso el objeto debe contener información adicional.

Para poder diferenciar ambos tipos de objetos ELF, se decidió cambiar la extensión de .o a .ko. Por tanto cualquier archivo del tipo xxx.o es un objeto ELF para un núcleo 2.4, mientras que cualquier objeto ELF del tipo xxx.ko es para un núcleo 2.6 en adelante.

Si alguien está interesado, puede encontrar una explicación mucho mejor que la ofrecida aquí en Differences Between Versions Of Linux

PD: El motivo por el que el autorun.sh copió el driver para un kernel 2.4 en lugar de para un kernel 2.6 en adelante, lo desconozco.

#
Pack dijo...

Hola, mi problema es que al descargar muchos datos (descargar archivo grande, visualizar varios videos online a la vez, ...) pierdo la conexión. He seguido la entrada al pie de la letra (ya lo intente con la entrada que comentas al principio sin darme cuenta de que mi kernel era 3.0 y no 2.6) pero el problema persiste. Al seguir la entrada me da este problema al principio:


Check old driver and unload it.
rmmod r8168
Build the module and install
[: 48: r8168: unexpected operator
Depending module. Please wait.
load module r8168
Completed.


me dice lo d "unexpected operator". Aun asi, continue con todo lo que indicas y el problema persiste. ¿Alguna idea? Gracias de antemano.

#
Antonio Guillen dijo...

Pega la salida de los siguientes comandos:
lsmod | grep 81
lspci -k | grep -A5 RTL

#
Pack dijo...

:~$ lsmod | grep 81
r8168 107628 0
vboxdrv 251814 3 vboxpci,vboxnetadp,vboxnetflt
rtl8187 56323 0
mac80211 393459 1 rtl8187
cfg80211 172392 2 rtl8187,mac80211
eeprom_93cx6 12653 1 rtl8187

:~$ lspci -k | grep -A5 RTL
07:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 01)
Subsystem: CLEVO/KAPOK Computer Device 0122
Kernel driver in use: r8168
Kernel modules: r8168
08:07.0 FLASH memory: ENE Technology Inc ENE PCI Memory Stick Card Reader Controller
Subsystem: CLEVO/KAPOK Computer Device 0122

#
Antonio Guillen dijo...

Ahora mismo tu tarjeta cableada está usando el driver correcto (r8168) y el driver con problemas (r8169) no esta siendo cargado.

Si ahora mismo tienes problemas, debe ser otro distinto al que se comenta en esta entrada.

Haz la siguiente prueba. Reinicia el sistema, para partir de cero. Ejecuta el comando lspci -k | grep -A5 RTL para asegurarte de que el sistema esta usando el driver r8168 para tu tarjeta de red cableada. Y a continuación fuerza un fallo y revisa los logs; si la tarjeta de red se cae debe quedar registrado en algún log, como kern.log o en el propio dmesg.

Pega los logs donde este registrado ese evento en un servicio tipo Pastebin.com y enlaza-los.

#
Pack dijo...

Lo primero, darte las gracias ayudarme y sobretodo contestar tan rapido.

He hecho lo que me indicas y parece que el problema es que el kernel esta usando aun r8169 y no se porque ya que antes decia r8169.

:~$ lspci -k | grep -A5 RTL
07:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 01)
Subsystem: CLEVO/KAPOK Computer Device 0122
Kernel driver in use: r8169
Kernel modules: r8168
08:07.0 FLASH memory: ENE Technology Inc ENE PCI Memory Stick Card Reader Controller
Subsystem: CLEVO/KAPOK Computer Device 0122


Aun asi, he reproducido el error y eso es lo que se añade a kern.log al producirse http://pastebin.com/3iprPBAe

y esto lo que se añade a dmesg http://pastebin.com/p9b3cTAX

#
Antonio Guillen dijo...

El motivo por el que tu sistema está cargando el driver r8169 en lugar del driver r8168 es que olvidaste indicar al sistema que en lugar de cargar driver r8169 (/etc/modprobe.d/blacklist.conf) debe cargar el driver r8168 (/etc/modules.autoload.d/$(uname -r)). Si te fijas es justo el último párrafo de esta entrada.

En cualquier caso, y después de ojear tu log. El error que tienes es con la interface wifi, no con la cableada. Y en esta entrada se habla de como solucionar el problema que existe con el driver del chip RTL8111/8168B (cable).

Tras repasar los módulos que arroja tu lsmod, veo que tienes el módulo rtl8187, por lo que imagino que ese será tu chip wifi.

Para solucionar tu problema, deberás de descargar y compilar los drivers de tu wifi y no de tu tarjeta cableada. Los drivers para el chip rtl8187 los puedes descargar de Realtek RTL8185L/RTL8187L. Eso si, como tu tarjeta use el chip RTL8187B, mal asunto puesto que Realtek no tiene drivers para Linux para ese chip, así que tendrías que probar suerte con el RTL8187L.

Para instalarlo tan solo debes de ejecutar make && make install y despues reiniciar el PC. Aunque antes de reiniciar yo probaría a ver si esto efectivamente soluciona el problema para ello debes de ejecutar los siguientes comandos:
./wlan0down
./wlan0up


Tras esto te conectas a tu red e intentas provocar de nuevo el fallo.

Que tengas suerte ;)

#
Pack dijo...

Si que habia realizado los 2 ultimos pasos pero me sigue saliendo lo mismo al poner
lspci -k | grep -A5 RTL
los he vuelto a hacer y sigue poniendo r8169.

Pero estas en lo cierto y el problema es con la wifi y es RTL8187B (pensaba que los de la wifi eran los r8169). He probado con los 8185L como me indicas y no ha habido suerte y se sigue produciendo el error. Seguire buscando una solución y si lo consiguiera lo pondre aqui por si le sirviera a alguien.
Muchisimas gracias por tu tiempo!

#
Antonio Guillen dijo...

He investigado un poco y encontré el driver para RTL8187B, concretamente rtl8187B v.26.1056.1112.2009. Tan solo tienes que descargarlo, ejecutar make && make install y después reiniciar el ordenador.

Tras reiniciar asegúrate que el driver en uso por el adaptador wifi es r8187b y no r8187, para ello tan solo debes de ejecutar lspci -k. Si el driver cargado es el correcto (r8187b) intenta forzar el fallo.

Que tengas suerte ;)

PD: Para la red cableada, si estas interesado en saber porque no carga el driver correcto, pega la salida de cat /etc/modprobe.d/blacklist.conf y cat /etc/modules.autoload.d/kernel-3.0.

#
Anónimo dijo...

Primero felicitarte por la página. Como el driver de Relatek es compatible para las ramas 2.4 y 2.6 al compilar el driver me dada error y lo solucioné de la siguiente forma. Editamos el makefile:

r8168-8.024.00/src/makefile

Editamos el makefile para sustituir esta linea:

KEXT := $(shell echo $(KVER) | sed -ne 's/^2\.[567]\..*/k/p')o

Por esta otra:

KEXT := $(shell echo $(KVER) | sed -ne 's/^[23]\.[01567]\..*/k/p')o

http://code.google.com/p/r8168/issues

#
Antonio Guillen dijo...

Gracias por el aporte Anónimo #11. De hecho parece que este era el problema que tenía Pack #3 al compilar.

Publicar un comentario

Recuerde que puede utilizar algunos códigos HTML como <b>para negrita</b>, <i>para cursiva</i> y <a href="URL">para enlaces</a>.