Tutorial de Compilación de un driver en Linux
Tabla de Contenidos
1. Introducción
Esta Guía de Desarrollo explica paso a paso cómo compilar un driver o controlador en Linux para hacer uso de equipos no reconocidos directamente por el sistema operativo. Se indica todo lo necesario para configurar correctamente el entorno del sistema operativo para poder compilar el driver y su posterior adición al kernel.
Módulo de comunicación para compilar el driver
Los pasos que se muestran en esta Guía están orientados a crear el driver necesario para poder utilizar el módulo de comunicaciones SLM750 en formato mini PCIExpress del fabricante MeiG Smart Technology Co., Ltd. Este fabricante enfocado en el desarrollo y fabricación de módulos de comunicaciones tanto 4G como en 5G, así como en NB-IoT, proporciona todo lo necesario para poder hacer uso de los módulos de comunicaciones, como esquemáticos, hojas de características, comandos AT y la información básica para poder compilar de forma sencilla el driver necesario para utilizarlo en Linux.
Módulo SLM750 en formato mini PCIE
El módulo SLM750 (LTE CAT4/3G/2G) está basado en el chipset MDM9X07 de Qualcomm, y entre sus características más destacadas encontramos las siguientes:
- Cobertura LTE-FDD/ LTE-TDD/ WCDMA/ TD-SCDMA/ EDGE/ GPRS/ GSM/ EVDO&CDMA
- Qualcomm® IZat™ Gen 8C, Soporta GPS/GLONASS/BeiDou//Galileo
- Admite interfaz SDIO de 2 canales, periféricos de módulo Wi-Fi
- Compatible con códec de voz (HR/FR/EFR/AMR/AMR-WB), Admite SRLTE/CSFB/VOLTE (opcional)
- Interfaz USB2.0 de alta velocidad
- Rx Diversity y tecnología MIMO
- Pilas de protocolo integrado TCP/IP
- HW&SW totalmente compatible con SLM750-ZX (LTE CAT1)
Como se puede observar, este módulo es compatible con Sistemas Operativos tanto Android, Windows o Linux. En el presente documento se muestran los pasos para compilar el driver para este último SO.
Para poder sacarle el máximo partido al módulo los fabricantes proporcionan los archivos y documentación necesaria para compilar nuestro propio driver para que el módulo sea detectado por nuestro Sistema Operativo Linux. De esta manera, tendremos un driver disponible para insertar en el kernel y que sea detectable por nuestro equipo, como puede ser un Box PC o un SBC.
El puerto USB del módulo se encuentra multiplexado, por lo que será necesario modificar el driver necesario destinado al uso de modems GSM en formato USB.
En los siguientes capítulos se explicará en detalle los pasos necesarios para llegar a tener el driver compilado y el módulo funcionando correctamente en un equipo con Linux.
2. Preparación del entorno
A través de esta sección se irán explicando los pasos a seguir para la correcta configuración del entorno de desarrollo desde el que se realizará la compilación. Todas las instrucciones que se muestran están basadas en Ubuntu14.04 LTS x64. Para poder trabajar en un entorno perfectamente configurado, se recomienda el uso de Máquinas Virtuales, mediante las cuales podremos instalar la distribución de Linux necesaria para poder realizar la compilación.
Una vez tengamos la máquina Host configurada, debemos utilizar la documentación del fabricante para conocer la información que debemos insertar en los archivos necesarios para realizar la compilación del driver.
A continuación se explica el contenido y algunos términos que intervienen a la hora de modificar el kernel:
-
- Kernel:El kernel de Linux es el elemento principal de los sistemas operativos (SO) Linux, y es la interfaz fundamental entre el hardware de un equipo y sus procesos. Los comunica entre sí y gestiona los recursos de la manera más eficiente posible. Se llama kernel porque se encuentra dentro del sistema operativo y controla todas las funciones principales del hardware, ya sea un teléfono, un ordenador portátil, un servidor o cualquier otro tipo de equipo.
El kernel cumple cuatro tareas:
-
- Gestión de la memoria: supervisa cuánta memoria se utiliza para almacenar qué tipo de elementos, así como el lugar en que los guarda.
- Gestión de los procesos: determina qué procesos pueden usar la unidad central de procesamiento (CPU), cuándo y durante cuánto tiempo.
- Controladores de dispositivos: actúa como mediador o intérprete entre el hardware y los procesos.
- Seguridad y llamadas al sistema: recibe solicitudes de servicio por parte de los procesos.
Para poder generar un kernel propio se deben instalar las fuentes del kernel (paquete kernel-source). Para ello seguimos los siguientes pasos:
$ sudo apt-get update -y
$ sudo apt-get install linux-source
$ cd /usr/src/
$ sudo tar -jxvf linux-source-[version].tar.bz2
Tras la instalación, las fuentes del kernel se encuentran en el directorio /usr/src/linux-(versión_kernel)
Para realizar el proceso de compilación haremos uso de la herramienta make.
Makees una herramienta de gestión de dependencias, típicamente, las que existen entre los archivos que componen el código fuente de un programa, para dirigir su recompilación o «generación» automáticamente.Make es muy usada en los sistemas operativos tipo Unix/Linux. Por defecto lee las instrucciones para generar el programa u otra acción del fichero makefile. Las instrucciones escritas en este fichero se llaman dependencias.
La herramienta make se usa para las labores de creación de fichero ejecutable o programa, para su instalación, la limpieza de los archivos temporales en la creación del fichero, todo ello especificando unos parámetros iniciales (que deben estar en el makefile) al ejecutarlo. Dentro de este archivo makefile estará declarado el siguiente contenido:
- Comentarios
- Variables
- Reglas explícitas
- Reglas implícitas
Las Reglas explícitas le indican a make qué archivos dependen de otros archivos, así como los comandos requeridos para compilar un archivo en particular. Las Reglas implícitas son reglas que make interpreta para actualizar destinos sin tener que escribirlas dentro del fichero makefile.
A continuación habrá que instalar las dependencias para poder usar la herramienta make.
$ sudo apt-get install -y build-essential gcc g++ autoconf automake libtool bison flex gettext patch
$ sudo apt-get install -y libncurses5 libncurses5-dev
$ sudo apt-get install -y zlib1g-dev liblzo2-2 liblzo2-dev libssl-dev
De las aplicaciones instaladas con el comando anterior, podemos destacar las siguientes:
- build-essential: A la hora de crear paquetes para distribuciones GNU Linux, como Debian, una herramienta clave es build-essentials. Se trata de un paquete que contiene una lista informativa de los paquetes que se consideran esenciales para la creación de paquetes Debian. Para la instalación de muchos módulos o drivers, es necesario tener instalado este paquete.
- flex y bison: Flex y Bison son dos herramientas útiles para crear programas que reaccionen a una entrada de datos con una estructura y un lenguaje predeterminado. Como ejemplo se pueden crear compiladores intérprete y analizadores de línea de comando.
- libtool: Es una herramienta de programación GNU proveniente del sistema de construcción para GNU usada para crear bibliotecas de software portables.
- libncurses5: Muchas aplicaciones de terminal utilizan la biblioteca ncurses para controlar la salida a la pantalla y la entrada del usuario.
En este punto ya se tendría la máquina Host correctamente configurada para poder llevar a cabo el proceso de compilación del driver en Linux.
3. Proceso de compilación:
Configuración del kernel
Tras haber instalado linux-source, debemos modificar el archivo .config de /usr/src/linux-source-[version]. En este archivo se encuentran los parámetros de configuración del kernel. Una opción indicará que algún controlador está integrado en el núcleo («=y») o que se creará como un módulo («=m») o que no está seleccionado.
Se tendrá que activar una serie de opciones en el archivo de configuración del kernel (.config). En caso de que el archivo no se encuentre disponible, debemos ejecutar primeramente el comando make menuconfig para abrir el menú de opciones y poder guardar el archivo .config.
Editaremos el archivo .config con los siguientes parámetros:
Modificación del driver option.c
Para realizar el proceso de compilación del driver, será necesario añadir los VID y PID de los productos de Meig en el archivo option.c. En este archivo se añadirá toda la configuración necesaria para utilizar los módems USB. El VID se utiliza para identificar al fabricante, y el PID es el identificador del propio dispositivo. Habrá que añadir los siguientes valores para poder hacer uso del módulo SLM750 y otros del fabricante Meig.
Tabla con los VID y PID de los distintos módulos de Meig
De igual forma, añadimos la siguiente información para hacer uso de esos PID y VID:
/*[MEIG-zhaopf-2019-11-04]add for meig modem supported {*/
{ USB_DEVICE(MEIG_VENDOR_ID, MEIG_PRODUCT_SRM815),
.driver_info = RSVD(4) | RSVD(5) },
{ USB_DEVICE(MEIG_VENDOR_ID, MEIG_PRODUCT_SRM815_ECM),
.driver_info = RSVD(4) | RSVD(5) },
{ USB_DEVICE(MEIG_QCM_VENDOR_ID,
MEIG_QCM_PRODUCT_SLM750_SRM815_SLM868),
.driver_info = RSVD(4) | RSVD(5) },
{ USB_DEVICE(MEIG_VENDOR_ID, MEIG_PRODUCT_SLM790),
.driver_info = RSVD(0) | RSVD(5) | RSVD(6) | RSVD(7) },
/*[MEIG-zhaopf-2019-11-04]add for meig modem supported }*/
Tras insertar los parámetros necesarios, podremos hacer uso de la herramienta make para compilar el driver. Teniendo en cuenta que se va a modificar el kernel, es importante indicar que únicamente compile el módulo necesario. De esta manera, evitaremos que se compile el kernel completo, ahorrándonos el tiempo que tardaría en hacer esta tarea, que podría llegar a durar horas.
$ make scripts prepare modules_prepare
$ make -C . M=drivers/usb/serial/
Tras realizar la compilación, además de los archivos en formato .c, se generarán otros de igual nombre, pero en formato .o y .ko.
El archivo .ko es el archivo de objeto vinculado con algunas estructuras de datos generadas automáticamente por el kernel que necesita el kernel.
El archivo .o es el archivo objeto del módulo, resultado de compilar el archivo C. Luego, el sistema de compilación del kernel crea automáticamente otro archivo C con algunas estructuras de datos que describen el módulo del kernel (llamado your_module_kmod.c). Se compila este archivo C en otro archivo de objeto y vincula su archivo de objeto y el archivo de objeto que creó para crear el .ko expediente.
El enlazador dinámico en el kernel que está a cargo de cargar los módulos del kernel espera encontrar la estructura de datos que el kernel colocó en el objeto kmod en el archivo .ko y no podrá cargar su módulo del kernel sin ellos.
Los tres archivos importantes que necesitaremos de esta carpeta serán los siguientes, que están asociados al driver de módems USB que se encargan de demultiplexar los puertos y generar los puertos serie virtuales:
- usbserial.ko
- usb_wwan.ko
- option.ko
4. Instalación del driver
Los tres archivos .ko generados debemos pegarlos en la ruta /lib/modules. Este directorio contiene directorios con módulos kernel necesarios para el kernel. Estos directorios se crean después de compilar el kernel.
$ sudo cp /usr/src/linux-source-5.4.0/drivers/usb/serial/option.ko /lib/modules/5.4.0-42-generic/kernel/drivers/usb/serial
$ sudo cp /usr/src/linux-source-5.4.0/drivers/usb/serial/usbserial.ko /lib/modules/5.4.0-42-generic/kernel/drivers/usb/serial
$ sudo cp /usr/src/linux-source-5.4.0/drivers/usb/serial/usb_wwan.ko /lib/modules/5.4.0-42-generic/kernel/drivers/usb/serial
Una vez copiados los archivos en la ruta correspondiente, usaremos la herramienta depmod para crear una lista de dependencias de módulos leyendo cada módulo en /lib/modules/version y determinando qué símbolos exporta y qué símbolos necesita.
$ sudo depmod
Tras usar la instrucción, reiniciamos el sistema y comprobaremos si se ha aplicado correctamente el driver compilado.
$ reboot
anatronic@testing:~# dmesg | grep ttyUSB
[ 8.796229] usb 1-4: GSM modem (1-port) converter now attached to ttyUSB0
[ 8.796879] usb 1-4: GSM modem (1-port) converter now attached to ttyUSB1
[ 8.797367] usb 1-4: GSM modem (1-port) converter now attached to ttyUSB2
[ 8.797969] usb 1-4: GSM modem (1-port) converter now attached to ttyUSB3
Una vez comprobado que los puertos serie virtuales se han generado correctamente, podemos hacer uso del módem. Para estas pruebas, haremos uso de la herramienta Modem Manager. Esta herramienta permite controlar las funciones específicas del módem de banda ancha compatible utilizado los canales de comunicación (2G / 3G / 4G / CDMA), conexiones de procesos (USB, RS232, Bluetooth) y gestión (AT, QCDM, QMI, MBIM).
Haciendo uso del comando mmcli -m 0, se lista toda la información asociada al módem conectado: