LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Kernel (http://www.linuxquestions.org/questions/linux-kernel-70/)
-   -   Passing a custom parameter to the kernel (http://www.linuxquestions.org/questions/linux-kernel-70/passing-a-custom-parameter-to-the-kernel-587787/)

jkoshi 09-27-2007 12:48 PM

Passing a custom parameter to the kernel
 
Hi,

I'm hacking some code in the kernel, and want to pass in a custom
parameter to the kernel (either at boot time, or after startup),
which my new code will use. This parameter is a number, ranging from
40 to 800, for example.

The existing boot command line parameters do not allow the use of a
user defined custom parameter to be passed in to the kernel. Is there
a way to do this, either during or after boot?

Thanks,
John

osor 09-27-2007 01:46 PM

Have you tried using module_param()?

marozsas 09-27-2007 02:21 PM

As far I know, any string you pass to kernel at boot time is available in /proc/cmdline pseudo file.
Check your current /proc/cmdline and you will find all strings you kernel received at boot time, even those are user space specific or are not used by anyone.

jkoshi 09-28-2007 06:31 PM

Quote:

Originally Posted by marozsas (Post 2905733)
As far I know, any string you pass to kernel at boot time is available in /proc/cmdline pseudo file.
Check your current /proc/cmdline and you will find all strings you kernel received at boot time, even those are user space specific or are not used by anyone.

Thanks for the tips, Osor and Marozsas. I haven't had time to try out
either one. I will post what I find after looking into it some more.

John

jkoshi 10-08-2007 11:50 AM

Quote:

Originally Posted by osor (Post 2905693)
Have you tried using module_param()?

Hi Osor,

I was looking into module_param, but it appears that it is used mainly
for modules. There seems to be no documentation on what needs to be
done if I wanted to add a parameter to the "kernel" boot command line
in grub.conf, that would be visible as a global after init is done.

John

osor 10-08-2007 01:56 PM

Quote:

Originally Posted by jkoshi (Post 2917349)
There seems to be no documentation on what needs to be
done if I wanted to add a parameter to the "kernel" boot command line
in grub.conf, that would be visible as a global after init is done.

The module_param() macro is indeed for modules. If your “module” is not built as a module, but actually built-in to the kernel, you may still use the macro. In this case, you pass the parameter through the kernel command line using the modulename, followed by a dot (“.”), followed by the parameter. This is all documented here.

For example, consider the loopback block device module (loop.ko). This module takes a single optional parameter (max_loop) telling it the maximum number of loopback devices. So if I want to alter this parameter at the time of module loading, I would do something like this:
Code:

# modprobe loop max_loop=32
Suppose, however, that I have compiled the loopback block device “module” into my kernel. Then, I might pass the following line to the kernel at boot:
Code:

kernel /vmlinuz root=/dev/sda3 loop.max_loop=32
You can also assign permissions such that the file “/sys/module/loop/parameters/max_loop” is readable, is writable, is both, or is neither. In this case, the permissions are 0 (so the sysfs-interface file simply doesn’t exist).

If you want to be slightly more arcane about kernel parameters for built-in code, you can always use the __setup() macro. If you want to be slightly more sophisticated, you could create a sysctl interface.

marozsas 10-08-2007 02:19 PM

Quote:

Originally Posted by jkoshi (Post 2907012)
Thanks for the tips, Osor and Marozsas. I haven't had time to try out
either one. I will post what I find after looking into it some more.

You don't tell us if you have tried it already, but if you start your linux with
Code:

kernel /vmlinuz ro root=LABEL=/ rhgb quiet loop.max_loop=32 myparam=45
then, in the file /proc/cmdline you will have:
Code:

[root@agente86 ~]# cat /proc/cmdline
ro root=LABEL=/ rhgb quiet loop.max_loop=32 myparam=45
[root@agente86 ~]#

and you can inspect and parse the file contents in usual ways, e.g.:
Code:

[root@agente86 ~]# for arg in $(cat /proc/cmdline); do 
    echo $arg | grep -q myparam ;
    if [ $? == 0 ]; then     
        val=$(echo $arg | cut -d= -f2);   
        echo "myparm is $val";
    fi;
done
myparm is 45
[root@agente86 ~]#

Using this technique you can pass any string at boot time to any program in user space, like init scripts, /etc/rc.whatever scripts....

jkoshi 10-15-2007 12:00 PM

Quote:

Originally Posted by osor (Post 2917455)
The module_param() macro is indeed for modules. If your “module” is not built as a module, but actually built-in to the kernel, you may still use the macro. In this case, you pass the parameter through the kernel command line using the modulename, followed by a dot (“.”), followed by the parameter. This is all documented....

Thanks Osor,

Since this is a hack for a temporary test system, I decided to use the
__setup macro and get_option() in init/main.c, as follows:
Code:

unsigned int my_param;
EXPORT_SYMBOL (my_param);
.
.
.
static int __init set_my_param(char *str)
{
    get_option(&str, &my_param);
    return 1;
}

__setup("my_param=", set_my_param);

I then add "my_param=<value>" to the "kernel" line in grub.conf,
and in the kernel code areas where I need to use this parameter,
I extern my_param and use it;

I'm still not clear how I would use module_param() in the case where
it is not a parameter for a single module, but rather a value that I
need to see and use in several kernel code areas, ie: mm and fs, for
example.

jkoshi 10-15-2007 12:14 PM

Quote:

Originally Posted by marozsas (Post 2917469)
You don't tell us if you have tried it already, but if you start your linux with...

Thanks marozsas,

I wanted to add that in the current kernel, the command line
is also available as a global:
Code:

char *saved_command_line
Since strtok is available as a kernel function, this string can be
easily parsed in C code in the kernel, to get any user parameter that
is added to the "kernel" line of the grub configuration file. Please
see my earlier post for what I eventually used.

marozsas 10-15-2007 12:26 PM

Sorry !

I didn't realize you are talking about coding in kernel space.
I had to read your post a second time to figure out that, and it is very clear at beginning of your original post - my bad ....

have a happy hacking,

othe 07-10-2009 01:42 PM

Quote:

Originally Posted by jkoshi (Post 2924990)
Thanks Osor,

Since this is a hack for a temporary test system, I decided to use the
__setup macro and get_option() in init/main.c, as follows:
Code:

unsigned int my_param;
EXPORT_SYMBOL (my_param);
.
.
.
static int __init set_my_param(char *str)
{
    get_option(&str, &my_param);
    return 1;
}

__setup("my_param=", set_my_param);

I then add "my_param=<value>" to the "kernel" line in grub.conf,
and in the kernel code areas where I need to use this parameter,
I extern my_param and use it;

how do i extern my_param and use it?
and is a specific point i put this function in main.c or not?

jkoshi 07-13-2009 11:54 AM

Quote:

Originally Posted by othe (Post 3603632)
how do i extern my_param and use it?
and is a specific point i put this function in main.c or not?

Hi,

Declare the function in main.c like the other __init functions like nosmp, maxcpus, etc, and then the related __setup() function below that, for clarity. In the code area where you want to use this parameter, declare "extern my_param" up top, so you can use it.

Hope this helps.

John


All times are GMT -5. The time now is 11:26 PM.