Less converstaion

This commit is contained in:
Ciro Santilli
2017-11-13 14:25:24 +00:00
parent 9ec43c4e88
commit fa0a7e150d
10 changed files with 116 additions and 250 deletions

View File

@@ -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)

View File

@@ -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.

View File

@@ -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.

View File

@@ -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

View File

@@ -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
View 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");

View 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
View File

@@ -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
View 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

View File

@@ -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.