How to load kernel module while system is booting up - linux

I cannot load kernel module when the system boots up. I found one article that suggests me to try the following steps:
(a) Create directory for kmodule(the module I created):
# mkdir -p /lib/modules/$(uname -r)/kernel/drivers/mymodule
(b) Copy kmodule to that directory:
# cp kmodule.ko /lib/modules/$(uname -r)/kernel/drivers/mymodule/
(c) Edit /etc/modules file and add a line to it that consist your module name. In my case, it's kmodule as per the following:
# vi /etc/modules
1 # /etc/modules: kernel modules to load at boot time.
2 #
3 # This file contains the names of kernel modules that should beloaded
4 # at boot time, one per line. Lines beginning with "#" are ignored.
5 kmodule
(d) Reboot the system to see changes. Use lsmod command to check if the module is loaded or not.
# lsmod | grep kmodule
My Problem: it's not loaded when I reboot the system and when I debug using cmd $ cat /var/log/syslog | grep kmodule.
I found this:
May 20 15:40:14 SARATHI kernel: [17499.486762] kmodule: loading out-of-tree module taints kernel.
May 20 15:40:14 SARATHI kernel: [17499.486800] kmodule: module verification failed: signature and/or required key missing - tainting kernel
May 20 19:31:46 SARATHI systemd-modules-load[243]: Failed to find module 'kmodule'
What does that mean? How to resolve it?
NOTE: I'm new to kernel module and I'm using Ubuntu 16.04. Also, note that when I loaded manually using insmod cmd, it's successfully loaded.

Related

Can we disable aslr for linux kernel module (ko file)

Is there any way to disable ASLR for Linux kernel modules?
For example:
adb shell cat /proc/modules | grep module_name
module_name 8134656 27 - Live 0xffffffec11589000 (O)
Can we get the same address for all subsequent reboots?
Not possible without disabling KASLR altogether. There is no special KASLR flag for modules, it's either enabled or disabled globally, modules included (as you can see from the source code). If CONFIG_RANDOMIZE_BASE=y then the kernel image address as well as module addresses will be randomized, and this can be disabled only by using the nokaslr kernel command line parameter at boot.

Manually compiled kernel fails to boot: stuck in initramfs prompt

I am trying to compile a custom kernel for my old laptop (it's a Dell Inspiron 1525, with a Core 2 Duo processor, 2GB of memory and a HDD -- not SSD). In this computer I have 3 partitions, 2 small ones (10GB each) with the roots of distros that I use, and a large one for files. I'm using MX Linux (if that is relevant) and compiling the kernel in the large partition, which is mounted at /mnt/files. The first thing I did was to clone the v4.19 tag from Linus' repo at kernel.org, then I copied the configuration from the kernel that is currently running (from /boot/config-4.19.0-9-686-pae), run make menuconfig, just changed the string that goes after the version name to -copy, saved and exited. Then I compiled. This kernel, with the configuration just copied from the one that currently runs, works well. It is not custom, however, as it just uses the exact same configurations.
Then I started a new one, again by copying the current .config and using make menuconfig to disable a lot of things that I thought were not relevant for me. The compilation with make ARCH=i386 -j3 and then make INSTALL_MOD_STRIP=1 modules_install went well, apparently, but when I type make INSTALL_MOD_STRIP=1 install I get this:
$ sudo make INSTALL_MOD_STRIP=1 install
sh ./arch/x86/boot/install.sh 4.19.0-custom arch/x86/boot/bzImage \
System.map "/boot"
run-parts: executing /etc/kernel/postinst.d/apt-auto-removal 4.19.0-custom /boot/vmlinuz-4.19.0-custom
run-parts: executing /etc/kernel/postinst.d/dkms 4.19.0-custom /boot/vmlinuz-4.19.0-custom
Warning: Unable to find an initial ram disk that I know how to handle.
Will not try to make an initrd.
run-parts: executing /etc/kernel/postinst.d/initramfs-tools 4.19.0-custom /boot/vmlinuz-4.19.0-custom
update-initramfs: Generating /boot/initrd.img-4.19.0-custom
cryptsetup: WARNING: The initramfs image may not contain cryptsetup binaries
nor crypto modules. If that's on purpose, you may want to uninstall the
'cryptsetup-initramfs' package in order to disable the cryptsetup initramfs
integration and avoid this warning.
I: The initramfs will attempt to resume from /dev/sda1
I: (UUID=a1472f28-bb65-4a3a-a964-59b72d46b645)
I: Set the RESUME variable to override this.
run-parts: executing /etc/kernel/postinst.d/pm-utils 4.19.0-custom /boot/vmlinuz-4.19.0-custom
run-parts: executing /etc/kernel/postinst.d/unattended-upgrades 4.19.0-custom /boot/vmlinuz-4.19.0-custom
run-parts: executing /etc/kernel/postinst.d/zz-update-grub 4.19.0-custom /boot/vmlinuz-4.19.0-custom
Generating grub configuration file ...
Found theme: /boot/grub/themes/linen/theme.txt
Found linux image: /boot/vmlinuz-4.19.0-custom
Found initrd image: /boot/initrd.img-4.19.0-custom
Found linux image: /boot/vmlinuz-4.19.0-9-686-pae
Found initrd image: /boot/initrd.img-4.19.0-9-686-pae
Found linux image: /boot/vmlinuz-4.19.0-copy
Found initrd image: /boot/initrd.img-4.19.0-copy
Found memtest86+ image: /boot/memtest86+.bin
Found antiX 19.2 (19.2) on /dev/sda2
done
The first kernel (-copy) also gave these warnings, however (and it is working). This new kernel (-custom) starts booting but then gets stuck in a busybox (initramfs) prompt. I can issue some commands there, and I can see that there is a file system with some basic programs (I suppose from busybox). But it doesn't finish the boot process.
When I execute the exit command in this (initramfs) prompt I get something along these lines:
Gave up waiting for root file system device. Common problems:
- Boot args (cat /proc/cmdline)
- Check rootdelay= (did the system wait long enough?)
- Missing modules (cat /proc/modules; ls /dev)
ALERT! UUID=efdafcea-bdab-4c13-b2a7-caa77e4330ca does not exist. Dropping to a shell!
I tried to type the suggestions from the message above, but I don't know what to make out of them. If I type cat proc/cmdline in this same initramfs environment, I get something like:
BOOT_IMAGE=/boot/vmlinuz-4.19.0-custom root=UUID=efdafcea-bdab-4c13-b2a7-caa77e4330ca ro video=SVIDEO-1:d quiet splash
If I type cat proc/modules I get this output and if I type ls dev I get this. (Sorry for the bad image quality).
I am quite sure something that I removed during the configuration in menuconfig is what caused the problem, and if I understand anything from these messages I would guess that the kernel is not being able to mount the root filesystem, perhaps it is not finding the partition to mount?
My question here is, given this situation, is there any obvious candidates to be the problem among the settings in .config? This is my .config file.

How to view information about a newly loaded external Linux kernel module?

I have a simple Hello World kernel module from http://www.tldp.org/LDP/lkmpg/2.6/html/x121.html
I added a few lines with MODULE_AUTHOR, and MODULE_DESCRIPTION
It builds successfully, I'm able to insert it with insmod into the current kernel, view logs with dmesg, check that the module exists with lsmod.
However, I want to be able to view the module's info with modinfo but it doesn't work.
I get modinfo: ERROR: Module hello not found.
I tried running depmod and depmod -A but they didn't make a difference.
Is there any way to make modinfo "reload" so that I can view info for newly added modules?
From the man page:
modinfo extracts information from the Linux Kernel modules given on the command line. If the module name is not a filename, then the /lib/modules/version directory is searched, as is also done by
modprobe(8) when loading kernel modules.
So it looks like this command just uses the kernel module files to get this information, so you can either run:
modinfo hello.ko
or you could put your kernel module in the /lib/modules/version/ directory

Linux: Compiling a kernel device driver in standalone fashion

I'm compiling linux for an ARM board. I need to make some customized changes into an existing driver code present in the kernel repository and reload the driver.
I was expecting to find a ".ko" file in the driver directory after doing the make, but no such file exists. Apparently uImage/device tree image compilation doesn't work that way.
Do I need to write my own Makefile for standalone device driver compilation?
It may be a silly question, but sorry I'm pretty new to kernel/device drivers.
EDIT:
I followed the process outlined here: http://odroid.com/dokuwiki/doku.php?id=en:c1_building_kernel
After git checkout and installing the cross-compiler(arm-linux-gnueabihf-gcc 4.9.2), I issue the basic make comands
$ make odroidc_defconfig
$ make -j4
$ make -j4 modules
$ make uImage
All the steps are successful. The last few lines of log look like
KSYM .tmp_kallsyms1.o
KSYM .tmp_kallsyms2.o
LD vmlinux
SORTEX vmlinux
SYSMAP System.map
OBJCOPY arch/arm/boot/ccImage
Kernel: arch/arm/boot/ccImage is ready
Image arch/arm/boot/ccImage.lzo is ready
UIMAGE arch/arm/boot/uImage
Image Name: Linux-3.10.72
Created: Sat Mar 28 22:44:45 2015
Image Type: ARM Linux Kernel Image (lzo compressed)
Data Size: 5459649 Bytes = 5331.69 kB = 5.21 MB
Load Address: 00208000
Entry Point: 00208000
Image arch/arm/boot/uImage is ready
EDIT 2: Path to the driver code
https://github.com/hardkernel/linux/tree/odroidc-3.10.y/drivers/amlogic/efuse
Examining your Makefile
#
# Makefile for eFuse.
#
obj-$(CONFIG_EFUSE) += efuse_bch_8.o efuse_version.o efuse_hw.o efuse.o
We learn that the code can be built as either a loadable module, or permanently linked into the kernel itself.
Examining odroidc_defconfig from branch odroidc-3.10.y-android mentioned in your instructions we find
#
# EFUSE Support
#
CONFIG_EFUSE=y
With the "y" indicating that the code is to be linked into the driver. Had it instead said "m" it would be built as a module.
It's possible you could change that in the kernel config, but it might also cause problems if there's nothing setup to load the module before it is needed.
Likely simply installing the newly built kernel with the code already linked inside (ie, forgetting about the module idea) will work.
Not sure if you are still looking for the answers to this question.
But looking at the Kconfig file in your code, show that -
config EFUSE
bool "EFUSE Driver"
And since all your driver files are compiled with this config, the above config description allows the CONFIG_EFUSE to be 'n' or 'y'. So you can only build static modules (build-in) with this.
All you need to do is change the above description to:
config EFUSE
**tristate** "EFUSE Driver"
and also change the other configs in Kconfig to tristate.
This will allow your driver to be compiled as module once you select the driver as 'M' in your kernel config. Then you should be able to see the ".ko" file corresponding to the driver.
Also do make sure to use EXPORT_SYMBOL(foo) when building the driver as module so that any dependencies are taken care of when loading module symbols.

Patching and compiling Ext4 as a kernel module

I'm currently patching Ext4 for academic purposes (only linux/fs/ext4/*, like file.c, ioctl.c, ext4.h) . I'm working on the QEMU virtual machine, and to speed up the whole process I've selected Ext4 to compile as a kernel module. The problem occurs when it comes to test new changes, as, even though I run make modules ARCH=x86 && make modules_install ARCH=x86 and reboot the machine (/ is Ext4), they are not visible unless I recompile the whole kernel. It's a little bit weird as I have a variety of signs that the Ext4 has been compiled as a module:
It is configured as that:
$ grep EXT4 .config
CONFIG_EXT4_FS=m
It does compile as a module:
$ make modules ARCH=x86
(...)
CC [M] fs/ext4/ioctl.o
LD [M] fs/ext4/ext4.o
Building modules, stage 2.
MODPOST 3 modules
LD [M] fs/ext4/ext4.ko
After $ make modules_install ARCH=x86 the files in /lib/modules/3.13.3/kernel/fs/ have proper time stamp.
Finally:
$ lsmod
Module Size Used by
ext4 340817 1
(...)
For some reason I have to do $ make all ARCH=x86 in order to see my changes appear in the runtime. What have I missed? Thanks!
Most boot processes use an "initial ramdisk" (initrd) which contains all kernel modules which the kernel needs to load to be able to do anything - after all, to read files from an Ext4 file system, the kernel needs a driver for this file system and if the driver is on said file system, well, ...
So the solution is to pack all those files into an archive (the initial ramdisk) and save the hard disk blocks as a list of numbers in the boot loader. It can then use a primitive IDE/SATA driver to load the blocks directly, extract the drivers and load them.
Check the documentation of your linux distro to find out how to update initrd. On my Ubuntu Linux, it's mkinitramfs.
Related:
Linux initial RAM disk (initrd) overview

Resources