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
- 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 ofsu
. - 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
Is It Safe to Issue Blocking Write() Calls on the Same Tcp Socket from Multiple Threads
Adding a New System Call in Linux Kernel 3.3
Rename Multiple Directories Matching Pattern
How to "Git Pull" - Host Key Verification Failed
Cannot Sudo Su Anymore, "No Tty Present and No Askpass Program Specified"
How to Specify Time in Cron Considering Year
Redirect Process Stdin and Stdout to Netcat
Writing a Bash For-Loop with a Variable Top-End
How to Apply Password to Sudo in One Line Command and Execute Su Root
How to Use .Notparallel in Makefile Only on Specific Targets
How to Get Notified for Ip Address Changes Automatically
Difference Between Completion Variables and Semaphores
Arm Linux Atags VS Device Tree
Switch from 32Bit Mode to 64 Bit (Long Mode) on 64Bit Linux
Find Command in Bash Script Resulting in "No Such File or Directory" Error Only for Directories
Cannot --Enable-Pcregrep-Libbz2 Because Bzlib.H Was Not Found