Module Parameters
Several parameters that a driver needs to know can change from system to system. These can vary from the device number to use (as we'll see in the next chapter) to numerous aspects of how the driver should operate. For example, drivers for SCSI adapters often have options controlling the use of tagged command queuing, and the Integrated Device Electronics (IDE) drivers allow user control of DMA operations. If your driver controls older hardware, it may also need to be told explicitly where to find that hardware's I/O ports or I/O memory addresses. The kernel supports these needs by making it possible for a driver to designate parameters that may be changed when the driver's module is loaded.
These parameter values can be assigned at load time by insmod or modprobe ; the latter can also read parameter assignment from its configuration file (/etc/modprobe.conf ). The commands accept the specification of several types of values on the command line. As a way of demonstrating this capability, imagine a much-needed enhancement to the "hello world" module (called hellop) shown at the beginning of this chapter. We add two parameters: an integer value called howmany and a character string called whom. Our vastly more functional module then, at load time, greets whom not just once, but howmany times. Such a module could then be loaded with a command line such as:
insmod hellop howmany=10 whom="Mom"
Upon being loaded that way, hellop would say "Hello, Mom" 10 times
However, before insmod can change module parameters, the module must make them available. Parameters are declared with the module_param macro, which is defined in moduleparam.h. module_param takes three parameters: the name of the variable, its type, and a permissions mask to be used for an accompanying sysfs entry. The macro should be placed outside of any function and is typically found near the head of the source file. So hellop would declare its parameters and make them available to insmod as follows:static char *whom = "world";
static int howmany = 1; module_param(howmany, int, S_IRUGO); module_param(whom, charp, S_IRUGO);
Numerous types are supported for module parameters
bool
invbool A boolean (true or false) value (the associated variable should be of type int). The invbool type inverts the value, so that true values become false and vice versa.
charp A char pointer value. Memory is allocated for user-provided strings, and the pointer is set accordingly.
int long short uint ulong ushort
Basic integer values of various lengths. The versions starting with u are for unsigned values.
Array parameters, where the values are supplied as a comma-separated list, are also supported by the module loader. To declare an array parameter, use:
module_param_array(name,type,num,perm);
Where name is the name of your array (and of the parameter), type is the type of the array elements, num is an integer variable, and perm is the usual permissions value. If the array parameter is set at load time, num is set to the number of values supplied. The module loader refuses to accept more values than will fit in the array.
If you really need a type that does not appear in the list above, there are hooks in the module code that allow you to define them; see moduleparam.h for details on how to do that. All module parameters should be given a default value; insmod changes the value only if explicitly told to by the user. The module can check for explicit parameters by testing parameters against their default values.
The final module_param field is a permission value; you should use the definitions found in <linux/stat.h>. This value controls who can access the representation of the module parameter in sysfs. If perm is set to 0, there is no sysfs entry at all; otherwise, it appears under /sys/module[3] with the given set of permissions. Use S_IRUGO for a parameter that can be read by the world but cannot be changed; S_IRUGO|S_IWUSR allows root to change the parameter. Note that if a parameter is changed by sysfs, the value of that parameter as seen by your module changes, but your module is not notified in any other way. You should probably not make module parameters writable, unless you are prepared to detect the change and react accordingly.