En muchos ejemplos previos, tuvimos que codificar algo en el módulo del núcleo, tal como el nombre del fichero para los ficheros /proc o el número mayor del dispositivo para el dispositivo para que pudiéramos hacer ioctls en él. Esto va en contra de la filosofía de Unix, y Linux, que es escribir un programa flexible que el usuario pueda configurar.
La forma de decirle a un programa, o a un módulo del núcleo, algo que necesitan antes de empezar a trabajar es mediante los parámetros de la línea de órdenes. En el caso de los módulos del núcleo, no disponemos de argc y argv; en cambio tenemos algo mejor. Podemos definir variables globales en el módulo del núcleo e insmod las rellenará por nosotros.
En este módulo del núcleo definimos dos de ellas: str1 y str2. Todo lo que necesitas hacer es compilar el módulo del núcleo y entonces ejecutar insmod str1=xxx str2=yyy. Cuando se llama a init_module, str1 apuntará a la cadena de caracteres `xxx' y str2 a la cadena de caracteres `yyy'.
En la versión 2.0 no hay comprobación de tipos de estos argumentos6.1. Si el primer carácter de str1 o str2 es un dígito, el núcleo rellenará la variable con el valor del entero, en vez de con un puntero a la cadena de caracteres. En una situación de la vida real tienes que verificar esto.
En cambio, en la versión 2.2 usas la macro MACRO_PARM para decir a insmod lo que esperas como parámetros, su nombre y su tipo. Esto resuelve el problema de los tipos y permite a los módulos del núcleo recibir cadenas de caracteres que empiezan con un dígito, por ejemplo.
/* param.c * * Recibe en linea de comandos los par�metros en la instalaci�n del m�dulo */ /* Copyright (C) 1998-99 by Ori Pomerantz */ /* Los ficheros de cabeceras necesarios */ /* Est�ndar en los m�dulos del n�cleo */ #include <linux/kernel.h> /* Estamos haciendo trabajo del n�cleo */ #include <linux/module.h> /* Espec�ficamente, un m�dulo */ /* Distribuido con CONFIG_MODVERSIONS */ #if CONFIG_MODVERSIONS==1 #define MODVERSIONS #include <linux/modversions.h> #endif #include <stdio.h> /* Necesito NULL */ /* En 2.2.3 /usr/include/linux/version.h se incluye * una macro para esto, pero 2.0.35 no lo hace - por lo * tanto lo a�ado aqu� si es necesario */ #ifndef KERNEL_VERSION #define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c)) #endif /* Emmanuel Papirakis: * * Los nombres de par�metros son ahora (2.2) * manejados en una macro. * El n�cleo no resuelve los nombres de los * s�mbolos como parec�a que ten�a que hacer. * * Para pasar par�metros a un m�dulo, tienes que usar una macro * definida en include/linux/modules.h (linea 176). * La macro coge dos par�metros. El nombre del par�metro y * su tipo. El tipo es una letra entre comillas. * Por ejemplo, "i" deber�a de ser un entero y "s" deber�a * de ser una cadena de caracteres. */ char *str1, *str2; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) MODULE_PARM(str1, "s"); MODULE_PARM(str2, "s"); #endif /* Inicializa el m�dulo - muestra los par�metros */ int init_module() { if (str1 == NULL || str2 == NULL) { printk("La pr�xima vez, haz insmod param str1=<algo>"); printk("str2=<algo>\n"); } else printk("Cadenas de caracteres:%s y %s\n", str1, str2); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) printk("Si intentas hacer insmod a este m�dulo dos veces,"); printk("(sin borrar antes (rmmod)\n"); printk("al primero), quiz�s obtengas el mensaje"); printk("de error:\n"); printk("'el s�mbolo para el par�metro str1 no ha sido encontrado'.\n"); #endif return 0; } /* Limpieza */ void cleanup_module() { }