From fa0a7e150dae5202ecf264fca7662372a975dea8 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Mon, 13 Nov 2017 14:25:24 +0000 Subject: [PATCH] Less converstaion --- README.md | 13 ++-- build.md | 31 --------- getting-started.md | 25 ------- introduction.md | 60 ----------------- kernel_module/README.md | 5 +- kernel_module/vermagic.c | 21 ++++++ kernel_module/vermagic_fail.c | 30 +++++++++ kmod.md | 119 ++++++---------------------------- modprobe.md | 35 ++++++++++ vermagic.md | 27 -------- 10 files changed, 116 insertions(+), 250 deletions(-) delete mode 100644 build.md delete mode 100644 introduction.md create mode 100644 kernel_module/vermagic.c create mode 100644 kernel_module/vermagic_fail.c create mode 100644 modprobe.md delete mode 100644 vermagic.md diff --git a/README.md b/README.md index 31f0272..ac0c375 100644 --- a/README.md +++ b/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) diff --git a/build.md b/build.md deleted file mode 100644 index 0d17591..0000000 --- a/build.md +++ /dev/null @@ -1,31 +0,0 @@ -# Build - -The module building system. - -Explained at: - -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. diff --git a/getting-started.md b/getting-started.md index 0ddc0e3..66b8f82 100644 --- a/getting-started.md +++ b/getting-started.md @@ -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: - -- -- - -`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: - ## 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. diff --git a/introduction.md b/introduction.md deleted file mode 100644 index f8ac727..0000000 --- a/introduction.md +++ /dev/null @@ -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 diff --git a/kernel_module/README.md b/kernel_module/README.md index 1e6e716..38a670b 100644 --- a/kernel_module/README.md +++ b/kernel_module/README.md @@ -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) diff --git a/kernel_module/vermagic.c b/kernel_module/vermagic.c new file mode 100644 index 0000000..d4baff1 --- /dev/null +++ b/kernel_module/vermagic.c @@ -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? +*/ + +#include +#include +#include + +static int myinit(void) +{ + pr_info(VERMAGIC_STRING "\n"); + return 0; +} + +static void myexit(void) {} + +module_init(myinit) +module_exit(myexit) +MODULE_LICENSE("GPL"); diff --git a/kernel_module/vermagic_fail.c b/kernel_module/vermagic_fail.c new file mode 100644 index 0000000..3c7618d --- /dev/null +++ b/kernel_module/vermagic_fail.c @@ -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 +#include + +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"); diff --git a/kmod.md b/kmod.md index 234ec25..784f573 100644 --- a/kmod.md +++ b/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: +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: ## 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`: - -- -- - -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 diff --git a/modprobe.md b/modprobe.md new file mode 100644 index 0000000..54fa5c2 --- /dev/null +++ b/modprobe.md @@ -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: + +- +- + +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 diff --git a/vermagic.md b/vermagic.md deleted file mode 100644 index 73d4826..0000000 --- a/vermagic.md +++ /dev/null @@ -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? - -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.