mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-27 20:14:27 +01:00
Build userland examples separately
This commit is contained in:
72
README.adoc
72
README.adoc
@@ -1602,7 +1602,7 @@ We can set and get which cores the Linux kernel allows a program to run on with
|
||||
./run --cpus 2 --eval-busybox '/sched_getaffinity.out'
|
||||
....
|
||||
|
||||
Source: link:packages/kernel_modules/user/sched_getaffinity.c[]
|
||||
Source: link:packages/kernel_modules/userland/sched_getaffinity.c[]
|
||||
|
||||
Sample output:
|
||||
|
||||
@@ -2108,7 +2108,7 @@ Sources:
|
||||
|
||||
* link:packages/kernel_modules/ring0.c[]
|
||||
* link:packages/kernel_modules/ring0.h[]
|
||||
* link:packages/kernel_modules/user/ring0.c[]
|
||||
* link:packages/kernel_modules/userland/ring0.c[]
|
||||
|
||||
In both cases, we attempt to run the exact same code which is shared on the `ring0.h` header file.
|
||||
|
||||
@@ -2258,7 +2258,7 @@ but why not just use our minimal `/poweroff.out` and be done with it?
|
||||
./run --eval '/poweroff.out'
|
||||
....
|
||||
|
||||
Source: link:packages/kernel_modules/user/poweroff.c[]
|
||||
Source: link:packages/kernel_modules/userland/poweroff.c[]
|
||||
|
||||
This also illustrates how to shutdown the computer from C: https://stackoverflow.com/questions/28812514/how-to-shutdown-linux-using-c-or-qt-without-call-to-system
|
||||
|
||||
@@ -2270,7 +2270,7 @@ I dare you to guess what this does:
|
||||
./run --eval '/sleep_forever.out'
|
||||
....
|
||||
|
||||
Source: link:packages/kernel_modules/user/sleep_forever.c[]
|
||||
Source: link:packages/kernel_modules/userland/sleep_forever.c[]
|
||||
|
||||
This executable is a convenient simple init that does not panic and sleeps instead.
|
||||
|
||||
@@ -2363,7 +2363,7 @@ TERM=linux
|
||||
asdf=qwer
|
||||
....
|
||||
|
||||
Source: link:packages/kernel_modules/user/init_env_poweroff.c[].
|
||||
Source: link:packages/kernel_modules/userland/init_env_poweroff.c[].
|
||||
|
||||
==== init environment args
|
||||
|
||||
@@ -2790,8 +2790,8 @@ which teaches you how it is done from C code.
|
||||
|
||||
Source:
|
||||
|
||||
* link:packages/kernel_modules/user/myinsmod.c[]
|
||||
* link:packages/kernel_modules/user/myrmmod.c[]
|
||||
* link:packages/kernel_modules/userland/myinsmod.c[]
|
||||
* link:packages/kernel_modules/userland/myrmmod.c[]
|
||||
|
||||
The Linux kernel offers two system calls for module insertion:
|
||||
|
||||
@@ -4763,7 +4763,7 @@ Sources:
|
||||
|
||||
* link:packages/kernel_modules/ioctl.c[]
|
||||
* link:packages/kernel_modules/ioctl.h[]
|
||||
* link:packages/kernel_modules/user/ioctl.c[]
|
||||
* link:packages/kernel_modules/userland/ioctl.c[]
|
||||
* link:rootfs_overlay/ioctl.sh[]
|
||||
|
||||
`ioctl` is one of the most important methods of communication with real device drivers, which often take several fields as input.
|
||||
@@ -4811,7 +4811,7 @@ Outcome: the test passes:
|
||||
Sources:
|
||||
|
||||
* link:packages/kernel_modules/mmap.c[]
|
||||
* link:packages/kernel_modules/user/mmap.c[]
|
||||
* link:packages/kernel_modules/userland/mmap.c[]
|
||||
* link:rootfs_overlay/mmap.sh[]
|
||||
|
||||
In this example, we make a tiny 4 byte kernel buffer available to user-space, and we then modify it on userspace, and check that the kernel can see the modification.
|
||||
@@ -4848,7 +4848,7 @@ Sources:
|
||||
|
||||
* link:packages/kernel_modules/anonymous_inode.c[]
|
||||
* link:packages/kernel_modules/anonymous_inode.h[]
|
||||
* link:packages/kernel_modules/user/anonymous_inode.c[]
|
||||
* link:packages/kernel_modules/userland/anonymous_inode.c[]
|
||||
* link:rootfs_overlay/anonymous_inode.sh[]
|
||||
|
||||
This example gets an anonymous inode via <<ioctl>> from a debugfs entry by using `anon_inode_getfd`.
|
||||
@@ -4876,7 +4876,7 @@ Sources:
|
||||
|
||||
* link:packages/kernel_modules/netlink.c[]
|
||||
* link:packages/kernel_modules/netlink.h[]
|
||||
* link:packages/kernel_modules/user/netlink.c[]
|
||||
* link:packages/kernel_modules/userland/netlink.c[]
|
||||
* link:rootfs_overlay/netlink.sh[]
|
||||
|
||||
Launch multiple user requests in parallel to stress our socket:
|
||||
@@ -5354,7 +5354,7 @@ First get a virtual address to play with:
|
||||
/virt_to_phys_test.out &
|
||||
....
|
||||
|
||||
Source: link:packages/kernel_modules/user/virt_to_phys_test.c[]
|
||||
Source: link:packages/kernel_modules/userland/virt_to_phys_test.c[]
|
||||
|
||||
Sample output:
|
||||
|
||||
@@ -5381,7 +5381,7 @@ Sample output physical address:
|
||||
0x7c7b800
|
||||
....
|
||||
|
||||
Source: link:packages/kernel_modules/user/virt_to_phys_user.c[]
|
||||
Source: link:packages/kernel_modules/userland/virt_to_phys_user.c[]
|
||||
|
||||
Now we can verify that `virt_to_phys_user.out` gave the correct physical address in the following ways:
|
||||
|
||||
@@ -5498,7 +5498,7 @@ vaddr pfn soft-dirty file/shared swapped present library
|
||||
7ffff78ec000 1fd4 0 1 0 1 /lib/libuClibc-1.0.30.so
|
||||
....
|
||||
|
||||
Source: link:packages/kernel_modules/user/pagemap_dump.c[]
|
||||
Source: link:packages/kernel_modules/userland/pagemap_dump.c[]
|
||||
|
||||
Adapted from: https://github.com/dwks/pagemap/blob/8a25747bc79d6080c8b94eac80807a4dceeda57a/pagemap2.c
|
||||
|
||||
@@ -5593,7 +5593,7 @@ a
|
||||
#
|
||||
....
|
||||
|
||||
Source: link:packages/kernel_modules/user/proc_events.c[]
|
||||
Source: link:packages/kernel_modules/userland/proc_events.c[]
|
||||
|
||||
TODO: why `exit: tid=79` shows after `exit: tid=80`?
|
||||
|
||||
@@ -6003,7 +6003,7 @@ UIO interface in a nutshell:
|
||||
|
||||
Sources:
|
||||
|
||||
* link:packages/kernel_modules/user/uio_read.c[]
|
||||
* link:packages/kernel_modules/userland/uio_read.c[]
|
||||
* link:rootfs_overlay/uio_read.sh[]
|
||||
|
||||
Bibliography:
|
||||
@@ -6134,7 +6134,7 @@ Minimal example:
|
||||
./run --kernel-cli 'init=/ctrl_alt_del.out' --graphic
|
||||
....
|
||||
|
||||
Source: link:packages/kernel_modules/user/ctrl_alt_del.c[]
|
||||
Source: link:packages/kernel_modules/userland/ctrl_alt_del.c[]
|
||||
|
||||
When you hit `Ctrl-Alt-Del` in the guest, our tiny init handles a `SIGINT` sent by the kernel and outputs to stdout:
|
||||
|
||||
@@ -6444,11 +6444,12 @@ Looks like a recompile is needed to modify the image...
|
||||
DRM / DRI is the new interface that supersedes `fbdev`:
|
||||
|
||||
....
|
||||
./build-buildroot --buildroot-config 'BR2_PACKAGE_LIBDRM=y' --kernel-modules
|
||||
./build-buildroot --buildroot-config 'BR2_PACKAGE_LIBDRM=y'
|
||||
./build-userland --has-package libdrm -- libdrm_modeset
|
||||
./run --eval-busybox '/libdrm_modeset.out' --graphic
|
||||
....
|
||||
|
||||
Source: link:packages/kernel_modules/user/libdrm_modeset.c[]
|
||||
Source: link:packages/kernel_modules/userland/libdrm_modeset.c[]
|
||||
|
||||
Outcome: for a few seconds, the screen that contains the terminal gets taken over by changing colors of the rainbow.
|
||||
|
||||
@@ -8409,7 +8410,7 @@ and then feed `bst_vs_heap.dat` into: https://github.com/cirosantilli/cpp-cheat/
|
||||
Sources:
|
||||
|
||||
* link:bst-vs-heap[]
|
||||
* link:packages/kernel_modules/user/bst_vs_heap.cpp[]
|
||||
* link:packages/kernel_modules/userland/bst_vs_heap.cpp[]
|
||||
|
||||
===== OpenMP
|
||||
|
||||
@@ -8419,15 +8420,16 @@ Implemented by GCC itself, so just a toolchain configuration, no external libs,
|
||||
/openmp.out
|
||||
....
|
||||
|
||||
Source: link:packages/kernel_modules/user/openmp.c[]
|
||||
Source: link:packages/kernel_modules/userland/openmp.c[]
|
||||
|
||||
===== BLAS
|
||||
|
||||
Buildroot supports it, which makes everything just trivial:
|
||||
|
||||
....
|
||||
./build-buildroot --buildroot-config 'BR2_PACKAGE_OPENBLAS=y' --kernel-modules
|
||||
./run --eval-busybox '/openblas.out; echo $?'
|
||||
./build-buildroot --buildroot-config 'BR2_PACKAGE_OPENBLAS=y'
|
||||
./build-userland --has-package openblas -- openblas_hello
|
||||
./run --eval-busybox '/openblas_hello.out; echo $?'
|
||||
....
|
||||
|
||||
Outcome: the test passes:
|
||||
@@ -8436,7 +8438,7 @@ Outcome: the test passes:
|
||||
0
|
||||
....
|
||||
|
||||
Source: link:packages/kernel_modules/user/openblas.c[]
|
||||
Source: link:packages/kernel_modules/userland/openblas.c[]
|
||||
|
||||
The test performs a general matrix multiplication:
|
||||
|
||||
@@ -8465,13 +8467,14 @@ cblas_dgemm( CblasColMajor, CblasNoTrans, CblasTrans,3,3,2 ,1, A,3, B,
|
||||
Header only linear algebra library with a mainline Buildroot package:
|
||||
|
||||
....
|
||||
./build-buildroot --buildroot-config 'BR2_PACKAGE_EIGEN=y' --kernel-modules
|
||||
./build-buildroot --buildroot-config 'BR2_PACKAGE_EIGEN=y'
|
||||
./build-userland --has-package eigen -- eigen_hello
|
||||
....
|
||||
|
||||
Just create an array and print it:
|
||||
|
||||
....
|
||||
./run --eval-busybox '/eigen.out'
|
||||
./run --eval-busybox '/eigen_hello.out'
|
||||
....
|
||||
|
||||
Output:
|
||||
@@ -8481,7 +8484,7 @@ Output:
|
||||
2.5 1.5
|
||||
....
|
||||
|
||||
Source: link:packages/kernel_modules/user/eigen.cpp[]
|
||||
Source: link:packages/kernel_modules/userland/eigen_hello.cpp[]
|
||||
|
||||
This example just creates a matrix and prints it out.
|
||||
|
||||
@@ -9167,8 +9170,8 @@ The executable `/m5ops.out` illustrates how to hard code with inline assembly th
|
||||
|
||||
Sources:
|
||||
|
||||
* link:packages/kernel_modules/user/m5ops.h[]
|
||||
* link:packages/kernel_modules/user/m5ops.c[]
|
||||
* link:packages/kernel_modules/userland/m5ops.h[]
|
||||
* link:packages/kernel_modules/userland/m5ops.c[]
|
||||
|
||||
That executable is of course a subset of <<m5>> and useless by itself: its goal is only illustrate how to hardcode some <<m5ops>> yourself as one-liners.
|
||||
|
||||
@@ -9310,13 +9313,14 @@ system.cpu.dtb.inst_hits
|
||||
Let's have some fun and try to correlate the gem5 cycle count `system.cpu.numCycles` with the link:https://en.wikipedia.org/wiki/Time_Stamp_Counter[x86 `rdtsc` instruction] that is supposed to do the same thing:
|
||||
|
||||
....
|
||||
./build-buildroot --gem5 --kernel-modules && \
|
||||
./build-buildroot --gem5 && \
|
||||
./build-userland -- rdtsc && \
|
||||
./run --eval '/rdtsc.out;m5 exit;' --gem5 && \
|
||||
./gem5-stat && \
|
||||
:;
|
||||
....
|
||||
|
||||
Source: link:packages/kernel_modules/user/rdtsc.c[]
|
||||
Source: link:packages/kernel_modules/userland/rdtsc.c[]
|
||||
|
||||
`rdtsc` outputs a cycle count which we compare with gem5's `gem5-stat`:
|
||||
|
||||
@@ -11024,8 +11028,8 @@ hello cpp
|
||||
|
||||
Sources:
|
||||
|
||||
* link:packages/kernel_modules/user/hello.c[]
|
||||
* link:packages/kernel_modules/user/hello_cpp.c[]
|
||||
* link:packages/kernel_modules/userland/hello.c[]
|
||||
* link:packages/kernel_modules/userland/hello_cpp.c[]
|
||||
|
||||
==== rand_check.out
|
||||
|
||||
@@ -11035,7 +11039,7 @@ Print out several parameters that normally change randomly from boot to boot:
|
||||
./run --eval-busybox '/rand_check.out;/poweroff.out'
|
||||
....
|
||||
|
||||
Source: link:packages/kernel_modules/user/rand_check.c[]
|
||||
Source: link:packages/kernel_modules/userland/rand_check.c[]
|
||||
|
||||
This can be used to check the determinism of:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user