16

module name: params.ko


#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/stat.h>
MODULE_LICENSE("Dual BSD/GPL");

static char *mystring = "this is my char string";
module_param(mystring, charp, S_IRUGO | S_IWUSR); 
MODULE_PARM_DESC(mystring, "A char string");

static int __init params_init(void)
{
  printk("Driver is loaded\n");
  printk("   My char string(mystring): %s\n", mystring);
  return 0;
}

static void __exit params_exit(void) { printk("Driver is unloaded\n"); }

module_init(params_init); module_exit(params_exit);

When I use the default setting, I can see the "this is my char string" when the driver is loaded.

However, if I use command line to pass the string with space, it will show up the following error:

Ex1: # insmod ./params.ko mystring="Hello World"

insmod: error inserting './params.ko': -1 Unknown symbol in module

The dmesg shows up the following information:

params: Unknown parameter 'World'

Ex2: # insmod ./params.ko mystring="HelloWorld"

If I use "HelloWorld" without space, there is no problem to show the string.

I also tried to use \ or ' ' to see if I can escape that space to ignore the space but in vain.

Would like to consult anyone who knows how to pass a string containing the space to the kernel module?

Thank you and appreciate your help.

5
  • Interesting. I assume the "world" is being parsed as a parameter, thus the error. Just for pig-iron, can you try mystring=Hello\ World i.e. Leave out the double quotes and escape the space
    – Greycon
    Commented Aug 26, 2014 at 15:42
  • Actually, I think this might be a general problem.. have a look at lists.busybox.net/pipermail/busybox/2011-February/074611.html
    – Greycon
    Commented Aug 26, 2014 at 15:56
  • @Greycon Thanks for more information. Seems that this is really a general problem without a solution for now..
    – rickhau
    Commented Aug 27, 2014 at 14:19
  • @Greycon I tried to use mystring=Hello\ World as you suggested. # insmod: error inserting './params.ko': -1 Unknown symbol in module dmesg output: params: Unknown parameter 'World'
    – rickhau
    Commented Aug 27, 2014 at 14:33
  • OK, I think it's a general problem so. I guess you will have to pass a string which is hyphenated, then parse those out in your kernel driver code.
    – Greycon
    Commented Aug 27, 2014 at 15:37

1 Answer 1

16

When you run insmod ./params.ko mystring="Hello World" your quotes are eaten by the shell and the insmod binary has the string mystring=Hello World as the parameter. It passes it to the kernel as is, and then it all goes down to the kernel parse_args function (in kernel/params.c), which, in turn, calls next_arg to split the next parameter into name and value.

It definitely can handle spaces, as we see the following comment in the code:

/* You can use " around spaces, but can't escape ". */
/* Hyphens and underscores equivalent in parameter names. */

and the following conditional statement:

static char *next_arg(char *args, char **param, char **val)
{
    ...
    for (i = 0; args[i]; i++) {
        if (isspace(args[i]) && !in_quote)
            break;
    ...
}

So the idea is that you need to pass the quotes to the kernel, not to the shell. Don't have a linux box to check the kernel module insertion right now, but I guess the following command will work:

# insmod ./params.ko mystring='"Hello World"'

Here the shell will consume the single quotes, and the parameter for insmod binary will be mystring="Hello World" so these quotes will be passed to kernel as is, which will make it possible to parse the value as you expect. Try that, should work.

1
  • 1
    If your string stores in environment variable then you can directly pass string to module parameter. for example - insmod ./params.ko mystring=$STRVAL Commented Jan 25, 2023 at 5:26

Not the answer you're looking for? Browse other questions tagged or ask your own question.