mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
Less converstaion
This commit is contained in:
13
README.md
13
README.md
@@ -12,14 +12,13 @@ Run one command, get a QEMU Buildroot BusyBox virtual machine built from source
|
||||
1. [X11](x11.md)
|
||||
1. [gdbserver](gdbserver.md)
|
||||
1. [Count boot instructions](count-boot-instructions.md)
|
||||
1. [Record and replay](record-and-replay.md)
|
||||
1. [Hello host](hello_host/)
|
||||
1. Conversation
|
||||
1. [Introduction](introduction.md)
|
||||
1. [Build](build.md)
|
||||
1. [kmod](kmod.md)
|
||||
1. [vermagic](vermagic.md)
|
||||
1. [ftrace](ftrace.md)
|
||||
1. [Device tree](device-tree.md)
|
||||
1. [modprobe](modprobe.md)
|
||||
1. Failed action
|
||||
1. [Record and replay](record-and-replay.md)
|
||||
1. [GEM5](gem5.md)
|
||||
1. [Bibliography](bibliography.md)
|
||||
1. Conversation
|
||||
1. [kmod](kmod.md)
|
||||
1. [Bibliography](bibliography.md)
|
||||
|
||||
31
build.md
31
build.md
@@ -1,31 +0,0 @@
|
||||
# Build
|
||||
|
||||
The module building system.
|
||||
|
||||
Explained at: <https://www.kernel.org/doc/Documentation/kbuild/modules.txt>
|
||||
|
||||
Full method: get the kernel, build it to a directory `$KDIR`, and then run:
|
||||
|
||||
make -C "$KDIR" M="$(PWD)" modules
|
||||
|
||||
Quick method: no need for a full build, just:
|
||||
|
||||
make modules_prepare
|
||||
|
||||
but you lose some functionality. TODO: module insert on host then fails with:
|
||||
|
||||
insmod: ERROR: could not insert module hello.ko: Invalid module format
|
||||
|
||||
even though kernel tree was checked out to match the host.
|
||||
|
||||
Using your distro's kernel version:
|
||||
|
||||
/lib/modules/$(uname -r)/build
|
||||
|
||||
## includes
|
||||
|
||||
Header files come from the same directory as the makefile: `/lib/modules/$(uname -r)/build`.
|
||||
|
||||
TODO how is that different from: `/usr/src/linux-headers-$(uname -r)/` ?
|
||||
|
||||
Those come directly from the kernel source tree.
|
||||
@@ -236,31 +236,6 @@ or on host:
|
||||
|
||||
cat buildroot/output.*~/build/linux-custom/.config
|
||||
|
||||
## insmod alternatives
|
||||
|
||||
If you are feeling fancy, you can also insert modules with:
|
||||
|
||||
modprobe hello
|
||||
|
||||
This method also deals with module dependencies, which we almost don't use to make examples simpler:
|
||||
|
||||
- <https://askubuntu.com/questions/20070/whats-the-difference-between-insmod-and-modprobe>
|
||||
- <https://stackoverflow.com/questions/22891705/whats-the-difference-between-insmod-and-modprobe>
|
||||
|
||||
`modprobe` searches for modules under:
|
||||
|
||||
ls /lib/modules/*/extra/
|
||||
|
||||
Kernel modules built from the Linux mainline tree with `CONFIG_SOME_MOD=m`, are automatically available with `modprobe`, e.g.:
|
||||
|
||||
modprobe dummy-irq
|
||||
|
||||
If you are feeling raw, you can use our own minimal:
|
||||
|
||||
/myinsmod.out /hello.ko
|
||||
|
||||
which demonstrates the C module API: <https://stackoverflow.com/questions/5947286/how-can-linux-kernel-modules-be-loaded-from-c-code/38606527#38606527>
|
||||
|
||||
## QEMU GUI is unresponsive
|
||||
|
||||
Sometimes in Ubuntu 14.04, after the QEMU SDL GUI starts, it does not get updated after keyboard strokes, and there are artifacts like disappearing text.
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
# Introduction
|
||||
|
||||
There are things which are hard to do from regular user programs such as directly talking to hardware.
|
||||
|
||||
Some operations can be done via system calls, but if you want flexibility and speed, using the kernel ring is fundamental
|
||||
|
||||
However:
|
||||
|
||||
- it would be very complicated to recompile the kernel and reboot every time you make some modification
|
||||
- the kernel would be huge if it were to support all possible hardware
|
||||
|
||||
Modules overcome those two problems exactly because they can be loaded into the kernel *while it is running* and use symbols that the kernel chooses to export TODO which
|
||||
|
||||
It then runs in the same address space as the kernel and with the same permissions as the kernel (basically do anything)
|
||||
|
||||
Compiled modules are special object files that have a `.ko` extension instead of `.o` they also contain module specific metadata
|
||||
|
||||
Device drivers (programs that enables the computer to talk to hardware) are one specific type of kernel modules
|
||||
|
||||
Two devices can map to the same hardware!
|
||||
|
||||
## Configuration files
|
||||
|
||||
If file it gets read, if dir, all files in dir get read:
|
||||
|
||||
sudo ls /etc/modprobe.d
|
||||
sudo ls /etc/modprobe.conf
|
||||
|
||||
Modules loaded at boot:
|
||||
|
||||
sudo cat /etc/modules
|
||||
|
||||
## Hardware communication
|
||||
|
||||
Talking to hardware always comes down to writing bytes in specific registers at a given memory addresses.
|
||||
|
||||
Some processors implement a single address space for memory and other hardware devices, and others do not.
|
||||
|
||||
However, since x86 is the most popular and it separates address spaces, every architecture must at least mimic this separation.
|
||||
|
||||
On x86, the following specialized instructions exist for port IO:
|
||||
|
||||
- `IN`: Read from a port
|
||||
- `OUT`: Write to a port
|
||||
- `INS/INSB`: Input string from port/Input byte string from port
|
||||
- `INS/INSW`: Input string from port/Input word string from port
|
||||
- `INS/INSD`: Input string from port/Input `doubleword` string from port
|
||||
- `OUTS/OUTSB`: Output string to port/Output byte string to port
|
||||
- `OUTS/OUTSW`: Output string to port/Output word string to port
|
||||
- `OUTS/OUTSD`: Output string to port/Output `doubleword` string to port
|
||||
|
||||
However, you should avoid using those instructions directly in your device driver code since Linux functions abstract over multiple architectures (when possible) making your code more portable.
|
||||
|
||||
Those instructions cannot be used from an user space program since the kernel prevents those from accessing hardware directly.
|
||||
|
||||
The memory space for non-memory locations is called I/O ports or I/O space.
|
||||
|
||||
To use a port, you must first reserve it. To see who reserved what:
|
||||
|
||||
sudo cat /proc/ioports
|
||||
@@ -6,7 +6,10 @@
|
||||
1. [hello](hello.c)
|
||||
1. [hello2](hello2.c)
|
||||
1. [panic](panic.c)
|
||||
1. [params](params.c)
|
||||
1. Module utils
|
||||
1. [params](params.c)
|
||||
1. [vermagic](vermagic.c)
|
||||
1. [vermagic_fail](vermagic_fail.c)
|
||||
1. Pseudo filesystems
|
||||
1. [debugfs](debugfs.c)
|
||||
1. [procfs](procfs.c)
|
||||
|
||||
21
kernel_module/vermagic.c
Normal file
21
kernel_module/vermagic.c
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
insmod /vermagic.ko
|
||||
# => 4.9.6 SMP mod_unload modversions
|
||||
TODO how to get the vermagic from running kernel from userland? <https://lists.kernelnewbies.org/pipermail/kernelnewbies/2012-October/006306.html>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/vermagic.h>
|
||||
|
||||
static int myinit(void)
|
||||
{
|
||||
pr_info(VERMAGIC_STRING "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void myexit(void) {}
|
||||
|
||||
module_init(myinit)
|
||||
module_exit(myexit)
|
||||
MODULE_LICENSE("GPL");
|
||||
30
kernel_module/vermagic_fail.c
Normal file
30
kernel_module/vermagic_fail.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
insmod /vermagic_fail.ko
|
||||
# => insmod: can't insert '/vermagic_fail.ko': invalid module format
|
||||
|
||||
modinfo /vermagic_fail.ko | grep vermagic
|
||||
# => vermagic: asdfqwer
|
||||
# => vermagic: 4.9.6 SMP mod_unload modversions
|
||||
|
||||
kmod `modprobe` has a flag to skip the check:
|
||||
|
||||
--force-modversion
|
||||
|
||||
Looks like it just strips `modversion` information from the module before loading, and then the kernel skips the check.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
static int myinit(void)
|
||||
{
|
||||
pr_info("vermagic_fail\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void myexit(void) {}
|
||||
|
||||
module_init(myinit)
|
||||
module_exit(myexit)
|
||||
MODULE_INFO(vermagic, "asdfqwer");
|
||||
MODULE_LICENSE("GPL");
|
||||
119
kmod.md
119
kmod.md
@@ -1,114 +1,35 @@
|
||||
# kmod
|
||||
|
||||
Multi-call executable that implements: `lsmod`, `insmod`, `rmmod`, and other tools.
|
||||
Multi-call executable that implements: `lsmod`, `insmod`, `rmmod`, and other tools on desktop distros such as Ubuntu 16.04, where e.g.:
|
||||
|
||||
BusyBox also implements its own version of those executables.
|
||||
ls -l /bin/lsmod
|
||||
|
||||
Source: <https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git>
|
||||
gives:
|
||||
|
||||
The other tools are just symlinks to it.
|
||||
lrwxrwxrwx 1 root root 4 Jul 25 15:35 /bin/lsmod -> kmod
|
||||
|
||||
and:
|
||||
|
||||
dpkg -l | grep -Ei
|
||||
|
||||
contains:
|
||||
|
||||
ii kmod 22-1ubuntu5 amd64 tools for managing Linux kernel modules
|
||||
|
||||
BusyBox also implements its own version of those executables. There are some differences.
|
||||
|
||||
Buildroot also has a kmod package, but we are not using it since BusyBox' version is good enough so far.
|
||||
|
||||
This page will only describe features that differ from kmod to the BusyBox implementation.
|
||||
|
||||
Source code: <https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git>
|
||||
|
||||
## module-init-tools
|
||||
|
||||
Name of a predecessor set of tools.
|
||||
|
||||
## package version
|
||||
|
||||
From any of the commands, `--version`:
|
||||
|
||||
modinfo --version
|
||||
|
||||
Package that provides utilities
|
||||
|
||||
## lsmod
|
||||
|
||||
List loaded kernel modules.
|
||||
|
||||
Info is taken from `/proc/modules`
|
||||
|
||||
lsmod
|
||||
|
||||
Sample output:
|
||||
|
||||
cfg80211 175574 2 rtlwifi,mac80211
|
||||
^^^^^^^^ ^^^^^^ ^ ^^^^^^^,^^^^^^^^
|
||||
1 2 3 4 5
|
||||
|
||||
1. Name.
|
||||
|
||||
2. Size.
|
||||
|
||||
3. Number of running instances.
|
||||
|
||||
If negative, TODO
|
||||
|
||||
4. Depends on 1.
|
||||
|
||||
5. Depends on 2.
|
||||
|
||||
To get more info:
|
||||
|
||||
cat /proc/modules
|
||||
|
||||
Also contains two more columns:
|
||||
|
||||
- status: Live, Loading or Unloading
|
||||
- memory offset: 0x129b0000
|
||||
|
||||
## modinfo
|
||||
|
||||
Get info about a module by filename or by module name:
|
||||
|
||||
modinfo ./a.ko
|
||||
modinfo a
|
||||
|
||||
TODO must take a `.ko` file?
|
||||
|
||||
## insmod
|
||||
|
||||
sudo insmod hello.ko
|
||||
|
||||
Loads the module.
|
||||
|
||||
Does not check for dependencies.
|
||||
|
||||
## rmmod
|
||||
|
||||
Remove a module. Takes either the module name or the `.ko` file:
|
||||
|
||||
sudo rmmod hello
|
||||
sudo rmmod ./hello.ko
|
||||
|
||||
## modprobe
|
||||
|
||||
Vs `insmod`:
|
||||
|
||||
- <https://askubuntu.com/questions/20070/whats-the-difference-between-insmod-and-modprobe>
|
||||
- <https://stackoverflow.com/questions/22891705/whats-the-difference-between-insmod-and-modprobe>
|
||||
|
||||
List available modules relative path to `/lib/modules/$KERNEL_VERSION/`:
|
||||
|
||||
sudo modprobe -l
|
||||
|
||||
Load the module:
|
||||
|
||||
sudo modprobe $m
|
||||
|
||||
Checks for dependencies.
|
||||
|
||||
Load module under different name to avoid conflicts:
|
||||
|
||||
sudo modprobe vmhgfs -o vm_hgfs
|
||||
|
||||
Remove module:
|
||||
|
||||
sudo modprobe -r $m
|
||||
|
||||
Check if dependencies are OK:
|
||||
|
||||
sudo depmod -a
|
||||
|
||||
Get info about given `.ko` module file:
|
||||
|
||||
m=a
|
||||
sudo rmmod $m
|
||||
|
||||
35
modprobe.md
Normal file
35
modprobe.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# modprobe
|
||||
|
||||
If you are feeling fancy, you can also insert modules with:
|
||||
|
||||
modprobe dep2
|
||||
lsmod
|
||||
# dep and dep2
|
||||
|
||||
This method also deals with module dependencies, which we almost don't use to make examples simpler:
|
||||
|
||||
- <https://askubuntu.com/questions/20070/whats-the-difference-between-insmod-and-modprobe>
|
||||
- <https://stackoverflow.com/questions/22891705/whats-the-difference-between-insmod-and-modprobe>
|
||||
|
||||
Removal also removes required modules that have zero usage count:
|
||||
|
||||
modprobe -r dep2
|
||||
lsmod
|
||||
# Nothing.
|
||||
|
||||
but it can't know if you actually insmodded them separately or not:
|
||||
|
||||
modprobe dep
|
||||
modprobe dep2
|
||||
modprobe -r dep2
|
||||
# Nothing.
|
||||
|
||||
so it is a bit risky.
|
||||
|
||||
`modprobe` searches for modules under:
|
||||
|
||||
ls /lib/modules/*/extra/
|
||||
|
||||
Kernel modules built from the Linux mainline tree with `CONFIG_SOME_MOD=m`, are automatically available with `modprobe`, e.g.:
|
||||
|
||||
modprobe dummy-irq
|
||||
27
vermagic.md
27
vermagic.md
@@ -1,27 +0,0 @@
|
||||
# vermagic
|
||||
|
||||
If the module does not match that of the kernel, `insmod` is unhappy and fails.
|
||||
|
||||
Get it from kernel module:
|
||||
|
||||
modinfo mymod.ko
|
||||
|
||||
Override it on module source:
|
||||
|
||||
MODULE_INFO(vermagic, "newver");
|
||||
|
||||
On the Linux kernel 4.9.6, it is defined under `include/linux/vermagic.h`:
|
||||
|
||||
#define VERMAGIC_STRING \
|
||||
UTS_RELEASE " " \
|
||||
MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \
|
||||
MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \
|
||||
MODULE_ARCH_VERMAGIC
|
||||
|
||||
TODO can you get it from running kernel from userland? <https://lists.kernelnewbies.org/pipermail/kernelnewbies/2012-October/006306.html>
|
||||
|
||||
Desktop `modprobe` has a flag to skip the check:
|
||||
|
||||
`--force-modversion`
|
||||
|
||||
Looks like it just strips `modversion` information from the module, and then the kernel skips the check.
|
||||
Reference in New Issue
Block a user