mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
Move debugfs, rootfs and procfs documentation to README
This commit is contained in:
117
README.adoc
117
README.adoc
@@ -2879,13 +2879,6 @@ You should then look up if there is a branch that supports that kernel. Staying
|
||||
|
||||
Pseudo filesystems are filesystems that don't represent actual files in a hard disk, but rather allow us to do special operations on filesystem-related system calls.
|
||||
|
||||
Some notable examples include:
|
||||
|
||||
* procfs, often mounted at: `/proc`
|
||||
* sysfs, often mounted at: `/sys`
|
||||
* devtmpfs, often mounted at: `/dev`
|
||||
* debugfs, often mounted at: `/sys/kernel/debug/`
|
||||
|
||||
What each pseudo-file does for each related system call does is defined by its <<file-operations>>.
|
||||
|
||||
Bibliography:
|
||||
@@ -2893,6 +2886,110 @@ Bibliography:
|
||||
* https://superuser.com/questions/1198292/what-is-a-pseudo-file-system-in-linux
|
||||
* https://en.wikipedia.org/wiki/Synthetic_file_system
|
||||
|
||||
==== debugfs
|
||||
|
||||
In guest:
|
||||
|
||||
....
|
||||
/debugfs.sh
|
||||
echo $?
|
||||
....
|
||||
|
||||
Outcome: the test passes:
|
||||
|
||||
....
|
||||
0
|
||||
....
|
||||
|
||||
Sources:
|
||||
|
||||
* link:kernel_module/debugfs.c[]
|
||||
* link:rootfs_overlay/debugfs.sh[]
|
||||
|
||||
Debugfs is the simplest pseudo filesystem to play around with, as it is made specifically to help test kernel stuff. Just mount, set <<file-operations>>, and we are done.
|
||||
|
||||
For this reason, it is the filesystem that we use whenever possible in our tests.
|
||||
|
||||
`debugfs.sh` explicitly mounts a debugfs at a custom location, but the most common mount point is `/sys/kernel/debug`.
|
||||
|
||||
This mount not done automatically by the kernel however: we, like most distros, do it from userland with our link:rootfs_overlay/etc/fstab[fstab].
|
||||
|
||||
Debugfs support requires the kernel to be compiled with `CONFIG_DEBUG_FS=y`.
|
||||
|
||||
Only the more basic file operations can be implemented in debugfs, e.g. `mmap` never gets called:
|
||||
|
||||
* https://patchwork.kernel.org/patch/9252557/
|
||||
* https://github.com/torvalds/linux/blob/v4.9/fs/debugfs/file.c#L212
|
||||
|
||||
Bibliography: https://github.com/chadversary/debugfs-tutorial
|
||||
|
||||
==== procfs
|
||||
|
||||
In guest:
|
||||
|
||||
....
|
||||
/procfs.sh
|
||||
echo $?
|
||||
....
|
||||
|
||||
Outcome: the test passes:
|
||||
|
||||
....
|
||||
0
|
||||
....
|
||||
|
||||
Sources:
|
||||
|
||||
* link:kernel_module/procfs.c[]
|
||||
* link:rootfs_overlay/procfs.sh[]
|
||||
|
||||
Just another fops entry point.
|
||||
|
||||
Bibliography: https://stackoverflow.com/questions/8516021/proc-create-example-for-kernel-module/18924359#18924359
|
||||
|
||||
==== sysfs
|
||||
|
||||
In guest:
|
||||
|
||||
....
|
||||
/sysfs.sh
|
||||
echo $?
|
||||
....
|
||||
|
||||
Outcome: the test passes:
|
||||
|
||||
....
|
||||
0
|
||||
....
|
||||
|
||||
Sources:
|
||||
|
||||
* link:kernel_module/sysfs.c[]
|
||||
* link:rootfs_overlay/sysfs.sh[]
|
||||
|
||||
Vs procfs:
|
||||
|
||||
* https://unix.stackexchange.com/questions/4884/what-is-the-difference-between-procfs-and-sysfs
|
||||
* https://stackoverflow.com/questions/37237835/how-to-attach-file-operations-to-sysfs-attribute-in-platform-driver
|
||||
|
||||
This example shows how sysfs is more restricted, as it does not take an arbitrary `file_operations`.
|
||||
|
||||
So you basically can only do `open`, `close`, `read`, `write`, and `lseek` on sysfs files.
|
||||
|
||||
It is similar to a `seq_file` file operation, except that write is also implemented.
|
||||
|
||||
TODO: what are those `kobject` structs? Make a more complex example that shows what they can do.
|
||||
|
||||
Bibliography:
|
||||
|
||||
* https://github.com/t3rm1n4l/kern-dev-tutorial/blob/1f036ef40fc4378f5c8d2842e55bcea7c6f8894a/05-sysfs/sysfs.c
|
||||
* https://www.kernel.org/doc/Documentation/kobject.txt
|
||||
* https://www.quora.com/What-are-kernel-objects-Kobj
|
||||
* http://www.makelinux.net/ldd3/chp-14-sect-1
|
||||
* https://www.win.tue.nl/~aeb/linux/lk/lk-13.html
|
||||
|
||||
=== Pseudo files
|
||||
|
||||
==== File operations
|
||||
|
||||
In guest:
|
||||
@@ -2919,7 +3016,7 @@ File operations is the main method of userland driver communication.
|
||||
|
||||
No, there no official documentation: http://stackoverflow.com/questions/15213932/what-are-the-struct-file-operations-arguments
|
||||
|
||||
==== Character device
|
||||
==== Character devices
|
||||
|
||||
In guest:
|
||||
|
||||
@@ -2940,7 +3037,7 @@ Sources:
|
||||
* link:rootfs_overlay/mknoddev.sh[]
|
||||
* link:kernel_module/character_device.c[]
|
||||
|
||||
Charcter device files are created with:
|
||||
Character device files are created with:
|
||||
|
||||
....
|
||||
mknod </dev/path_to_dev> c <major> <minor>
|
||||
@@ -2967,7 +3064,7 @@ which means:
|
||||
* `c` (first letter): this is a character device. Would be `b` for a block device.
|
||||
* `1, 9`: the major number is `1`, and the minor `9`
|
||||
|
||||
To avoid device number conflicts when registring the driver we:
|
||||
To avoid device number conflicts when registering the driver we:
|
||||
|
||||
* ask the kernel to allocate a free major number for us with: `register_chrdev(0`
|
||||
* find ouf which number was assigned by grepping `/proc/devices` for the kernel module name
|
||||
|
||||
@@ -20,14 +20,11 @@
|
||||
... link:dep2.c[]
|
||||
. Pseudo filesystems
|
||||
.. link:anonymous_inode.c[]
|
||||
.. link:debugfs.c[]
|
||||
.. link:ioctl.c[]
|
||||
.. link:mmap.c[]
|
||||
.. link:poll.c[]
|
||||
.. link:procfs.c[]
|
||||
.. link:seq_file.c[]
|
||||
.. link:seq_file_inode.c[]
|
||||
.. link:sysfs.c[]
|
||||
. Asynchronous
|
||||
.. link:irq.c[]
|
||||
.. link:kthread.c[]
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#character-devices */
|
||||
|
||||
#include <linux/fs.h> /* register_chrdev, unregister_chrdev */
|
||||
#include <linux/module.h>
|
||||
#include <linux/seq_file.h> /* seq_read, seq_lseek, single_release */
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#automatically-create-character-device-file-on-insmod */
|
||||
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h> /* register_chrdev, unregister_chrdev */
|
||||
|
||||
@@ -1,17 +1,4 @@
|
||||
/*
|
||||
Adapted from: https://github.com/chadversary/debugfs-tutorial/blob/47b3cf7ca47208c61ccb51b27aac6f9f932bfe0b/example1/debugfs_example1.c
|
||||
|
||||
Usage:
|
||||
|
||||
/debugfs.sh
|
||||
|
||||
Requires `CONFIG_DEBUG_FS=y`.
|
||||
|
||||
Only the more basic fops can be implemented in debugfs, e.g. mmap is never called:
|
||||
|
||||
- https://patchwork.kernel.org/patch/9252557/
|
||||
- https://github.com/torvalds/linux/blob/v4.9/fs/debugfs/file.c#L212
|
||||
*/
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#debugfs */
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
@@ -1,15 +1,4 @@
|
||||
/*
|
||||
Yet another fops entrypoint.
|
||||
|
||||
https://stackoverflow.com/questions/8516021/proc-create-example-for-kernel-module
|
||||
|
||||
insmod /procfs.ko
|
||||
cat /proc/lkmc_procfs
|
||||
|
||||
Output:
|
||||
|
||||
abcd
|
||||
*/
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#procfs */
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
@@ -1,24 +1,4 @@
|
||||
/*
|
||||
Adapted from: https://github.com/t3rm1n4l/kern-dev-tutorial/blob/1f036ef40fc4378f5c8d2842e55bcea7c6f8894a/05-sysfs/sysfs.c
|
||||
|
||||
Vs procfs:
|
||||
|
||||
- https://unix.stackexchange.com/questions/4884/what-is-the-difference-between-procfs-and-sysfs
|
||||
- https://stackoverflow.com/questions/37237835/how-to-attach-file-operations-to-sysfs-attribute-in-platform-driver
|
||||
|
||||
This example shows how sysfs is more restricted, as it does not take a file_operations.
|
||||
|
||||
So you basically can only do open, close, read, write, and lseek on sysfs files.
|
||||
|
||||
It is kind of similar to a seq_file file_operations, except that write is also implemented.
|
||||
|
||||
TODO: what are those kobject structs? Make a more complex example that shows what they can do.
|
||||
|
||||
- https://www.kernel.org/doc/Documentation/kobject.txt
|
||||
- https://www.quora.com/What-are-kernel-objects-Kobj
|
||||
- http://www.makelinux.net/ldd3/chp-14-sect-1
|
||||
- https://www.win.tue.nl/~aeb/linux/lk/lk-13.html
|
||||
*/
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#sysfs */
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kobject.h>
|
||||
|
||||
@@ -1,22 +1,13 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
set -e
|
||||
d=/debugfs
|
||||
mkdir -p "$d"
|
||||
# We also added a fstab entry that mounts this under /sys/kernel/debug autmoatically.
|
||||
# That is the most common place to mount it.
|
||||
# The /sys/kernel/debug directory gets created automatically when debugfs is
|
||||
# compiled into the kernel, but it does not get mounted automatically.
|
||||
mount -t debugfs none /debugfs
|
||||
mount -t debugfs none "$d"
|
||||
insmod /debugfs.ko
|
||||
cd "${d}/lkmc_debugfs"
|
||||
|
||||
cat myfile
|
||||
# => 42
|
||||
|
||||
echo 13 > myfile
|
||||
cat myfile
|
||||
# => 13
|
||||
|
||||
[ "$(cat "${d}/lkmc_debugfs/myfile")" = 42 ]
|
||||
echo 13 > "${d}/lkmc_debugfs/myfile"
|
||||
[ "$(cat "${d}/lkmc_debugfs/myfile")" = 13 ]
|
||||
echo 666 > "${d}/lkmc_debugfs_file"
|
||||
cat myfile
|
||||
# => 666
|
||||
[ "$(cat "${d}/lkmc_debugfs/myfile")" = 666 ]
|
||||
rmmod debugfs
|
||||
umount "$d"
|
||||
|
||||
5
rootfs_overlay/procfs.sh
Executable file
5
rootfs_overlay/procfs.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
insmod /procfs.ko
|
||||
[ "$(cat "/proc/lkmc_procfs")" = abcd ]
|
||||
rmmod procfs
|
||||
@@ -1,11 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -x
|
||||
set -e
|
||||
insmod /sysfs.ko
|
||||
cd /sys/kernel/lkmc_sysfs
|
||||
printf 12345 >foo
|
||||
cat foo
|
||||
# => 1234
|
||||
dd if=foo bs=1 count=2 skip=1 status=none
|
||||
# => 23
|
||||
f=/sys/kernel/lkmc_sysfs/foo
|
||||
# write
|
||||
printf 12345 > "$f"
|
||||
# read
|
||||
[ "$(cat "$f")" = 1234 ]
|
||||
# seek
|
||||
[ "$(dd if="$f" bs=1 count=2 skip=1 status=none)" = 23 ]
|
||||
rmmod sysfs
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
#!/bin/sh
|
||||
(
|
||||
set -ex
|
||||
/character_device.sh
|
||||
/character_device_create.sh
|
||||
/fops.sh
|
||||
)
|
||||
if [ "$?" -eq 0 ]; then
|
||||
echo lkmc_test_pass
|
||||
exit 0
|
||||
else
|
||||
echo lkmc_test_fail
|
||||
exit 1
|
||||
fi
|
||||
for test in \
|
||||
/character_device.sh \
|
||||
/character_device_create.sh \
|
||||
/debugfs.sh \
|
||||
/fops.sh \
|
||||
/procfs.sh \
|
||||
/sysfs.sh
|
||||
do
|
||||
if ! "$test"; then
|
||||
echo "lkmc_test_fail: ${test}"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo lkmc_test_pass
|
||||
|
||||
Reference in New Issue
Block a user