Trying to Find All the Kernel Modules Needed for My MAChine Using Shell Script

Trying to find all the kernel modules needed for my machine using shell script

Anyone else trying to build a minimum kernel image also looking for reducing build time, should do the following:

1) copy distribution kernel config in your source tree. It can be done with either command given below:

$zcat /proc/config.gz > .config

or

$cp /boot/config-'uname -r' .config

2) Use localmodconfig target.

$make localmodconfig

It will use lsmod to find which modules are loaded at this moment. Then it will search through distribution's .config to enable them and disable others.

Its important to know that it does not always work flawlessly. So you should tweak your config further using make menuconfig. You will see some modules are still marked to be built which is in reality unnecessary for your system.

Sometimes out of tree modules may cause make localmodconfig to fail. If that's the case you can work around that issue in two ways :

a) unload the out of tree modules and try make localmodconfig again.
b) Run the perl script directly:

$chmod +x script/kconfig/streamline_config.pl
$perl script/kconfig/streamline_config.pl > .config

3) Install ccache[1]. It will improve your build time dramatically. It caches objects. So it will reduce subsequent builds.

Its possible that ccache is included in the distribution's repository so that you can install it through apt-get or yum. In CentOS its available in EPEL repo.[2]

4) Give as many cores as possible for the build job

$make -j8 CC="ccache gcc"

My results are :

real 3m10.871s
user 4m36.949s
sys 1m52.656s

[1] http://ccache.samba.org/
[2] http://fedoraproject.org/wiki/EPEL

How to trigger a kernel module from shell?


Loading module using system()

You are trying to become root in your application (by executing setuid(0)), but you don't have permissions to do that (if you run your program as regular user). Instead, you should check if your program was run from root (using getuid()). Also, it's good idea to test if your module file exists at all. Here is an example of such code (it's tested and does all checking needed):

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

#define ROOT_UID 0
#define INSMOD_PATH "/sbin/insmod"
#define MOD_PATH "/.../mymodule.ko"

int main(void)
{
uid_t uid;
int res;

/* Check if program being run by root */
uid = getuid();
if (uid != ROOT_UID) {
fprintf(stderr, "Error: Please run this program as root\n");
return EXIT_FAILURE;
}

/* Check if module file exists */
if (access(MOD_PATH, F_OK) == -1) {
fprintf(stderr, "Error: File \"%s\" doesn't exist\n", MOD_PATH);
return EXIT_FAILURE;
}

/* Load module */
res = system(INSMOD_PATH " " MOD_PATH);
if (res != 0) {
fprintf(stderr, "Error loading module: %d\n", res);
return EXIT_FAILURE;
}

printf("Module \"%s\" was successfully loaded\n", MOD_PATH);

return EXIT_SUCCESS;
}

Save this code as main.c file. Be sure to replace MOD_PATH definition with actual path of your module file.

Compile it using next command:

$ gcc -Wall -O2 main.c -o load_module

Now do the next:

$ su
# ./load_module
  1. First command switches your user to root (you will be asked to enter root password). If you don't know root password, try using sudo -s command instead of su.
  2. Second command runs your program.

Pay your attention to the last character at the command prompt:

  • # means you have root permissions at this point
  • $ means you only have regular user permissions.

Loading module using finit_module()

Using system() function in C is usually considered a bad practice (because it takes a lot of time for execution and basically just trying to replace a much more simple Bash script).

If you want to load kernel module in C without using system(), you can look into source code of insmod tool. See libkmod/libkmod-module.c file, kmod_module_insert_module() function. You can see those sources here.

Pay attention to finit_module() function call. A good explanation about this system call can be found at manual pages:

$ man finit_module

Here is an example how you can use finit_module() system call:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <sys/stat.h>
#include <fcntl.h>

#define ROOT_UID 0
#define MOD_PATH "/.../mymodule.ko"

static inline int finit_module(int fd, const char *uargs, int flags)
{
return syscall(__NR_finit_module, fd, uargs, flags);
}

int main(void)
{
uid_t uid;
long res;
int fd;

/* Check if program being run by root */
uid = getuid();
if (uid != ROOT_UID) {
fprintf(stderr, "Error: Please run this program as root\n");
return EXIT_FAILURE;
}

/* Check if module file exists */
if (access(MOD_PATH, F_OK) == -1) {
fprintf(stderr, "Error: File \"%s\" doesn't exist\n", MOD_PATH);
return EXIT_FAILURE;
}

/* Load module */
fd = open(MOD_PATH, O_RDONLY | O_CLOEXEC);
if (fd < 0) {
perror("Unable to open module file");
return EXIT_FAILURE;
}
res = finit_module(fd, "", 0);
if (res != 0) {
perror("Error when loading module");
close(fd);
return EXIT_FAILURE;
}
close(fd);

printf("Module \"%s\" was successfully loaded\n", MOD_PATH);

return EXIT_SUCCESS;
}

How can I get a list of all the active kernel drivers on my Android system?

Doing an ls /sys/module/ on my Samsung Galaxy S3 running 4.1.1 Jelly bean, I get the following output

http://pastebin.com/2zF8RwvS

That is a list of all the built-in modules in my Kernel 3.0.31

Additionally, there are loadable modules, ls /system/lib/modules/

http://pastebin.com/G5KLC65V

How to determine if a specific module is loaded in linux kernel

not sure if modinfo modname and checking $? will work for you, just a suggestion.

/tmp$ sudo modinfo e1000
/tmp$ echo $?
0
/tmp$ sudo modinfo keyboard
ERROR: modinfo: could not find module keyboard
/tmp$ echo $?
1

alternatively you also grep /proc/modules

Do I need to specify kernel modules in a particular order while using modprobe to insert them?

It shouldn't matter, and it definitely shouldn't segfault.



Related Topics



Leave a reply



Submit