split kernel module api docs to README

This commit is contained in:
Ciro Santilli
2018-07-01 23:37:37 +01:00
parent 8f37cd0d22
commit 6c241279a6
18 changed files with 490 additions and 296 deletions

View File

@@ -1,14 +1,7 @@
= kernel_module
. Modules
.. link:params.c[]
.. link:vermagic.c[]
.. link:vermagic_fail.c[]
.. link:module_init.c[]
.. link:module_info.c[]
.. Module dependencies
... link:dep.c[]
... link:dep2.c[]
Our kernel modules!
. Asynchronous
.. link:irq.c[]
.. link:schedule.c[]

View File

@@ -1,76 +1,22 @@
/*
Exports the lkmc_dep which dep2.ko uses.
/* https://github.com/cirosantilli/linux-kernel-module-cheat#kernel-module-dependencies */
insmod /dep.ko
# dmesg => 0
# dmesg => 0
# dmesg => ...
insmod /dep2.ko
# dmesg => 1
# dmesg => 2
# dmesg => ...
rmmod dep
# Fails because dep2 uses it.
rmmod dep2
# Dmesg stops incrementing.
rmmod dep
sys visibility:
dmesg -n 1
insmod /dep.ko
insmod /dep2.ko
ls -l /sys/module/dep/holders
# => ../../dep2
cat refcnt
# => 1
proc visibility:
grep lkmc_dep /proc/kallsyms
Requires "CONFIG_KALLSYMS_ALL=y".
depmod:
grep dep "/lib/module/"*"/depmod"
# extra/dep2.ko: extra/dep.ko
# extra/dep.ko:
modprobe dep
# lsmod
# Both dep and dep2 were loaded.
TODO: at what point does buildroot / busybox generate that file?
*/
#include <linux/delay.h> /* usleep_range */
#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
int lkmc_dep = 0;
u32 lkmc_dep = 0;
EXPORT_SYMBOL(lkmc_dep);
static struct task_struct *kthread;
static int work_func(void *data)
{
while (!kthread_should_stop()) {
pr_info("%d\n", lkmc_dep);
usleep_range(1000000, 1000001);
}
return 0;
}
static struct dentry *debugfs_file;
static int myinit(void)
{
kthread = kthread_create(work_func, NULL, "mykthread");
wake_up_process(kthread);
debugfs_file = debugfs_create_u32("lkmc_dep", S_IRUSR | S_IWUSR, NULL, &lkmc_dep);
return 0;
}
static void myexit(void)
{
kthread_stop(kthread);
debugfs_remove(debugfs_file);
}
module_init(myinit)

View File

@@ -1,30 +1,21 @@
#include <linux/delay.h> /* usleep_range */
/* https://github.com/cirosantilli/linux-kernel-module-cheat#kernel-module-dependencies */
#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
extern int lkmc_dep;
static struct task_struct *kthread;
static int work_func(void *data)
{
while (!kthread_should_stop()) {
usleep_range(1000000, 1000001);
lkmc_dep++;
}
return 0;
}
extern u32 lkmc_dep;
static struct dentry *debugfs_file;
static int myinit(void)
{
kthread = kthread_create(work_func, NULL, "mykthread");
wake_up_process(kthread);
debugfs_file = debugfs_create_u32("lkmc_dep2", S_IRUSR | S_IWUSR, NULL, &lkmc_dep);
return 0;
}
static void myexit(void)
{
kthread_stop(kthread);
debugfs_remove(debugfs_file);
}
module_init(myinit)

View File

@@ -0,0 +1,16 @@
/* https://github.com/cirosantilli/linux-kernel-module-cheat#init_module */
#include <linux/module.h>
#include <linux/kernel.h>
int init_module(void)
{
pr_info("init_module\n");
return 0;
}
void cleanup_module(void)
{
pr_info("cleanup_module\n");
}
MODULE_LICENSE("GPL");

View File

@@ -1,17 +1,4 @@
/*
- https://stackoverflow.com/questions/4839024/how-to-find-the-version-of-a-compiled-kernel-module/42556565#42556565
- https://stackoverflow.com/questions/19467150/significance-of-this-module-in-linux-driver/49812248#49812248
Usage:
insmod /module_info.ko
# dmesg => name = module_info
# dmesg => version = 1.0
cat /sys/module/module_info/version
# => module_info
modinfo /module_info.ko | grep -E '^version:'
# => version: 1.0
*/
/* https://github.com/cirosantilli/linux-kernel-module-cheat#module_info */
#include <linux/module.h>
#include <linux/kernel.h>
@@ -19,8 +6,10 @@ Usage:
static int myinit(void)
{
/* Set by default based on the module file name. */
pr_info("name = %s\n", THIS_MODULE->name);
pr_info("name = %s\n", THIS_MODULE->name);
pr_info("version = %s\n", THIS_MODULE->version);
/* ERROR: nope, not part of struct module. */
/*pr_info("asdf = %s\n", THIS_MODULE->asdf);*/
return 0;
}
@@ -28,5 +17,6 @@ static void myexit(void) {}
module_init(myinit)
module_exit(myexit)
MODULE_INFO(asdf, "qwer");
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL");

View File

@@ -1,26 +0,0 @@
/*
https://stackoverflow.com/questions/3218320/what-is-the-difference-between-module-init-and-init-module-in-a-linux-kernel-mod
Hello world with direct init_module and cleantup_module.
This appears to be an older method that still works but has some drawbacks.
vs module_init and module_exit?
- modprobe only works with the module_init / module_exit. Try "modprobe module_init".
*/
#include <linux/module.h>
#include <linux/kernel.h>
int init_module(void)
{
pr_info("init_module\n");
return 0;
}
void cleanup_module(void)
{
pr_info("cleanup_module\n");
}
MODULE_LICENSE("GPL");

View File

@@ -1,68 +1,53 @@
/*
Allows passing parameters at insertion time.
Those parameters can also be read and modified at runtime from /sys.
insmod /params.ko
# dmesg => 0 0
cd /sys/module/params/parameters
cat i
# => 1 0
printf 1 >i
# dmesg => 1 0
rmmod params
insmod /params.ko i=1 j=1
# dmesg => 1 1
rmmod params
modinfo
/params.ko
# Output contains MODULE_PARAM_DESC descriptions.
modprobe insertion can also set default parameters via the /etc/modprobe.conf file. So:
modprobe params
Outputs:
12 34
*/
/* https://github.com/cirosantilli/linux-kernel-module-cheat#kernel-module-parameters */
#include <linux/debugfs.h>
#include <linux/delay.h> /* usleep_range */
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/seq_file.h> /* seq_read, seq_lseek, single_release */
#include <uapi/linux/stat.h> /* S_IRUSR | S_IWUSR */
static int i = 0;
static int j = 0;
static u32 i = 0;
static u32 j = 0;
module_param(i, int, S_IRUSR | S_IWUSR);
module_param(j, int, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(i, "my favorite int");
MODULE_PARM_DESC(j, "my second favorite int");
static struct task_struct *kthread;
static struct dentry *debugfs_file;
static int work_func(void *data)
static int show(struct seq_file *m, void *v)
{
while (!kthread_should_stop()) {
pr_info("%d %d\n", i, j);
usleep_range(1000000, 1000001);
}
char kbuf[18];
int ret;
ret = snprintf(kbuf, sizeof(kbuf), "%d %d", i, j);
seq_printf(m, kbuf);
return 0;
}
static int open(struct inode *inode, struct file *file)
{
return single_open(file, show, NULL);
}
static const struct file_operations fops = {
.llseek = seq_lseek,
.open = open,
.owner = THIS_MODULE,
.read = seq_read,
.release = single_release,
};
static int myinit(void)
{
kthread = kthread_create(work_func, NULL, "mykthread");
wake_up_process(kthread);
debugfs_file = debugfs_create_file("lkmc_params", S_IRUSR, NULL, NULL, &fops);
return 0;
}
static void myexit(void)
{
kthread_stop(kthread);
debugfs_remove(debugfs_file);
}
module_init(myinit)

View File

@@ -23,8 +23,3 @@ These programs can also be compiled and used on host.
.. x86_64
... link:rdtsc.c[]
... link:ring0.c[]
. Module tests
.. link:anonymous_inode.c[]
.. link:ioctl.c[]
.. link:netlink.c[]
.. link:poll.c[]

View File

@@ -1,3 +1,5 @@
/* https://github.com/cirosantilli/linux-kernel-module-cheat#kernel-module-parameters#myinsmod */
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>

View File

@@ -1,10 +1,4 @@
/*
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>
*/
/* https://github.com/cirosantilli/linux-kernel-module-cheat#vermagic */
#include <linux/module.h>
#include <linux/kernel.h>
@@ -12,7 +6,9 @@ TODO how to get the vermagic from running kernel from userland?
static int myinit(void)
{
pr_info(__FILE__ "\n");
pr_info("VERMAGIC_STRING = " VERMAGIC_STRING "\n");
/* Nice try, but it is not a member. */
/*pr_info("THIS_MODULE->vermagic = %s\n", THIS_MODULE->vermagic);*/
return 0;
}

View File

@@ -1,17 +1,4 @@
/*
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.
*/
/* https://github.com/cirosantilli/linux-kernel-module-cheat#vermagic */
#include <linux/module.h>
#include <linux/kernel.h>