From f2bf644cfdd341aba82a44cb81f704c96d9f110a Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Mon, 9 Jul 2018 10:58:18 +0100 Subject: [PATCH] Review and link kernel_module/user examples to README --- README.adoc | 90 +++++++++++++------ kernel_module/user/anonymous_inode.c | 2 + kernel_module/user/common.h | 28 +++++- kernel_module/user/ctrl_alt_del.c | 2 + .../user/{eigen_hello.cpp => eigen.cpp} | 4 +- kernel_module/user/eigen_svd.cpp | 24 ----- kernel_module/user/libdrm_modeset.c | 3 +- kernel_module/user/m5ops.c | 2 + kernel_module/user/mmap.c | 2 + kernel_module/user/myinsmod.c | 2 +- kernel_module/user/myrmmod.c | 2 + kernel_module/user/openblas.c | 23 ++--- kernel_module/user/openmp.c | 2 + kernel_module/user/poll.c | 2 + kernel_module/user/rdtsc.c | 7 +- 15 files changed, 121 insertions(+), 74 deletions(-) rename kernel_module/user/{eigen_hello.cpp => eigen.cpp} (56%) delete mode 100644 kernel_module/user/eigen_svd.cpp diff --git a/README.adoc b/README.adoc index 54a86cc..34bf922 100644 --- a/README.adoc +++ b/README.adoc @@ -4863,9 +4863,6 @@ sendkey shift-pgdown ===== Ctrl Alt Del -* https://superuser.com/questions/193652/does-linux-have-a-ctrlaltdel-equivalent/1324415#1324415 -* https://unix.stackexchange.com/questions/42573/meaning-and-commands-for-ctrlaltdel/444969#444969 - Reboot guest: .... @@ -4952,9 +4949,12 @@ ever reaches the kernel tty layer, and it's up to the program to decide what to do with it. .... -===== SysRq +Bibliography: -https://en.wikipedia.org/wiki/Magic_SysRq_key +* https://superuser.com/questions/193652/does-linux-have-a-ctrlaltdel-equivalent/1324415#1324415 +* https://unix.stackexchange.com/questions/42573/meaning-and-commands-for-ctrlaltdel/444969#444969 + +===== SysRq We cannot test these actual shortcuts on QEMU since the host captures them at a lower level, but from: @@ -5004,6 +5004,8 @@ The bitmask is documented at: less linux/Documentation/admin-guide/sysrq.rst .... +Bibliography: https://en.wikipedia.org/wiki/Magic_SysRq_key + ==== TTY In order to play with TTYs, do this: @@ -5076,6 +5078,8 @@ Identify the current TTY with the command: tty .... +Bibliography: + * https://unix.stackexchange.com/questions/270272/how-to-get-the-tty-in-which-bash-is-running/270372 * https://unix.stackexchange.com/questions/187319/how-to-get-the-real-name-of-the-controlling-terminal * https://unix.stackexchange.com/questions/77796/how-to-get-the-current-terminal-name @@ -5133,7 +5137,7 @@ insmod /kthread.ko and switch between virtual terminals, to understand that the dmesg goes to whatever current virtual terminal you are on, but not the others, and not to the serial terminals. -See also: +Bibliography: * https://serverfault.com/questions/119736/how-to-enable-multiple-virtual-consoles-on-linux * https://github.com/mirror/busybox/blob/1_28_3/examples/inittab#L60 @@ -5197,7 +5201,7 @@ Instead, the shell appears on `/dev/tty7`. If you run in <>, then you get a Penguin image for <> above the console! https://askubuntu.com/questions/80938/is-it-possible-to-get-the-tux-logo-on-the-text-based-boot -This is due to the `CONFIG_LOGO=y` option which we enable by default. +This is due to the link:https://github.com/torvalds/linux/blob/v4.17/drivers/video/logo/Kconfig#L5[`CONFIG_LOGO=y`] option which we enable by default. `reset` on the terminal then kills the poor penguins. @@ -5350,7 +5354,7 @@ When I build it on Ubuntu 18.04 host, it does not generate any executable, so I' === Linux kernel testing -https://stackoverflow.com/questions/3177338/how-is-the-linux-kernel-tested +Bibliography: https://stackoverflow.com/questions/3177338/how-is-the-linux-kernel-tested ==== LTP @@ -5417,8 +5421,6 @@ Some QEMU specific features to play with and limitations to cry over. === Snapshot -https://stackoverflow.com/questions/40227651/does-qemu-emulator-have-checkpoint-function/48724371#48724371 - QEMU allows us to take snapshots at any time through the monitor. You can then restore CPU, memory and disk state back at any time. @@ -5493,6 +5495,8 @@ And the output is `0`. Our setup does not allow for snapshotting while using <>. +Bibliography: https://stackoverflow.com/questions/40227651/does-qemu-emulator-have-checkpoint-function/48724371#48724371 + ==== Snapshot internals Snapshots are stored inside the `.qcow2` images themselves. @@ -5918,8 +5922,6 @@ Rationale: we found out that the kernels that build for `qemu -M versatilepb` do At the same time, we also found out that Versatile Express (`vexpress`) does support armv7, so maybe we could port it over, but I had lost interest at that point, and decided to just go with the simpler `-M virt` machine instead. -https://stackoverflow.com/questions/28315265/how-to-add-a-new-device-in-qemu-source-code/44612957#44612957 - Uses: * `hw/misc/lkmc_platform_device.c` minimal device added in our QEMU fork to `-M versatilepb` @@ -5951,6 +5953,8 @@ The IRQ number `34` was found by on the dmesg after: insmod /platform_device.ko .... +Bibliography: https://stackoverflow.com/questions/28315265/how-to-add-a-new-device-in-qemu-source-code/44612957#44612957 + ==== gem5 educational hardware models TODO get some working! @@ -5963,8 +5967,6 @@ This protocol allows sharing a mountable filesystem between guest and host. With networking, it's boring, we can just use any of the old tools like sshfs and NFS. -https://superuser.com/questions/628169/how-to-share-a-directory-with-the-host-without-networking-in-qemu - One advantage of this method over NFS is that can run without `sudo` on host, or having to pass host credentials on guest for sshfs. TODO performance compared to NFS. @@ -6011,7 +6013,10 @@ security_model=mapped + writes from guest failed due to user mismatch problems: https://serverfault.com/questions/342801/read-write-access-for-passthrough-9p-filesystems-with-libvirt-qemu -The feature is documented at: https://wiki.qemu.org/Documentation/9psetup +Bibliography: + +* https://superuser.com/questions/628169/how-to-share-a-directory-with-the-host-without-networking-in-qemu +* https://wiki.qemu.org/Documentation/9psetup ==== 9P gem5 @@ -6093,8 +6098,6 @@ We us this exact procedure to connect to <>. ===== ssh into guest -https://unix.stackexchange.com/questions/124681/how-to-ssh-from-host-to-guest-using-qemu/307557#307557 - Not enabled by default due to the build / runtime overhead. To enable, build with: .... @@ -6115,6 +6118,8 @@ And finally on host: ssh root@localhost -p 45456 .... +Bibliography: https://unix.stackexchange.com/questions/124681/how-to-ssh-from-host-to-guest-using-qemu/307557#307557 + ===== gem5 host to guest networking Could not do port forwarding from host to guest, and therefore could not use `gdbserver`: https://stackoverflow.com/questions/48941494/how-to-do-port-forwarding-from-guest-to-host-in-gem5 @@ -6133,9 +6138,7 @@ gives: Could not open guest forwarding device 'guestfwd.tcp.45456' .... -Related: - -* https://serverfault.com/questions/769874/how-to-forward-a-port-from-guest-to-host-in-qemu-kvm +Bibliography: https://serverfault.com/questions/769874/how-to-forward-a-port-from-guest-to-host-in-qemu-kvm ==== Secondary disk @@ -6967,24 +6970,57 @@ Buildroot supports it, which makes everything just trivial: .... ./build -B 'BR2_PACKAGE_OPENBLAS=y' -k -./run -F '/openblas.out' +./run -F '/openblas.out; echo $?' +.... + +Outcome: the test passes: + +.... +0 .... Source: link:kernel_module/user/openblas.c[] +The test performs a general matrix multiplication: + +.... + | 1.0 -3.0 | | 1.0 2.0 1.0 | | 0.5 0.5 0.5 | | 11.0 - 9.0 5.0 | +1 * | 2.0 4.0 | * | -3.0 4.0 -1.0 | + 2 * | 0.5 0.5 0.5 | = | - 9.0 21.0 -1.0 | + | 1.0 -1.0 | | 0.5 0.5 0.5 | | 5.0 - 1.0 3.0 | +.... + +This can be deduced from the Fortran interfaces at: `out/x86_64/buildroot/build/openblas-*/reference/dgemmf.f`, which we can map to our call as: + +.... +C := alpha*op( A )*op( B ) + beta*C, +SUBROUTINE DGEMMF( TRANA, TRANB, M,N,K, ALPHA,A,LDA,B,LDB,BETA,C,LDC) +cblas_dgemm( CblasColMajor, CblasNoTrans, CblasTrans,3,3,2 ,1, A,3, B,3, 2 ,C,3 ); +.... + ===== Eigen -Header only linear algebra library supported by Buildroot: +Header only linear algebra library with a mainline Buildroot package: .... ./build -B 'BR2_PACKAGE_EIGEN=y' -k -./run -F '/eigen_hello.out;/eigen_svd.out' .... -Source: +Just create an array and print it: -* link:kernel_module/user/eigen.cpp[] -* link:kernel_module/user/eigen_svd.cpp[] +.... +./run -F '/eigen.out' +.... + +Output: + +.... + 3 -1 +2.5 1.5 +.... + +Source: link:kernel_module/user/eigen.cpp[] + +This example just creates a matrix and prints it out. Tested on: link:http://github.com/cirosantilli/linux-kernel-module-cheat/commit/a4bdcf102c068762bb1ef26c591fcf71e5907525[a4bdcf102c068762bb1ef26c591fcf71e5907525] @@ -7658,7 +7694,7 @@ which gives pretty close results, and serve as a nice sanity check that the cycl It is also nice to see that `rdtsc` is a bit smaller than the `stats.txt` value, since the latter also includes the exec syscall for `m5`. -See also: +Bibliography: * https://en.wikipedia.org/wiki/Time_Stamp_Counter * https://stackoverflow.com/questions/9887839/clock-cycle-count-wth-gcc/9887979 diff --git a/kernel_module/user/anonymous_inode.c b/kernel_module/user/anonymous_inode.c index 4f10d8f..6d70bae 100644 --- a/kernel_module/user/anonymous_inode.c +++ b/kernel_module/user/anonymous_inode.c @@ -1,3 +1,5 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#anonymous-inode */ + #define _GNU_SOURCE #include #include diff --git a/kernel_module/user/common.h b/kernel_module/user/common.h index 7c408bf..bf39fb5 100644 --- a/kernel_module/user/common.h +++ b/kernel_module/user/common.h @@ -3,13 +3,17 @@ #define _XOPEN_SOURCE 700 #include /* open */ +#include /* fabs */ #include /* uint64_t */ #include /* size_t */ +#include /* snprintf */ +#include #include /* pread, sysconf */ +#include /* Format documented at: * https://github.com/torvalds/linux/blob/v4.9/Documentation/vm/pagemap.txt - **/ + */ typedef struct { uint64_t pfn : 54; unsigned int soft_dirty : 1; @@ -33,8 +37,12 @@ int pagemap_get_entry(PagemapEntry *entry, int pagemap_fd, uintptr_t vaddr) nread = 0; while (nread < sizeof(data)) { - ret = pread(pagemap_fd, &data, sizeof(data), - (vaddr / sysconf(_SC_PAGE_SIZE)) * sizeof(data) + nread); + ret = pread( + pagemap_fd, + &data, + sizeof(data), + (vaddr / sysconf(_SC_PAGE_SIZE)) * sizeof(data) + nread + ); nread += ret; if (ret <= 0) { return 1; @@ -74,4 +82,18 @@ int virt_to_phys_user(uintptr_t *paddr, pid_t pid, uintptr_t vaddr) return 0; } +bool common_vector_equal(size_t n, double * v1, double * v2, double max_err) +{ + double sum = 0.0; + double diff; + size_t i; + for (i = 0; i < n; ++i) { + diff = v1[i] - v2[i]; + sum += diff * diff; + } + if (sqrt(sum)/n > max_err) + return false; + return true; +} + #endif diff --git a/kernel_module/user/ctrl_alt_del.c b/kernel_module/user/ctrl_alt_del.c index b8b1053..a3f05c9 100644 --- a/kernel_module/user/ctrl_alt_del.c +++ b/kernel_module/user/ctrl_alt_del.c @@ -1,3 +1,5 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#ctrl-alt-del */ + #define _XOPEN_SOURCE 700 #include #include diff --git a/kernel_module/user/eigen_hello.cpp b/kernel_module/user/eigen.cpp similarity index 56% rename from kernel_module/user/eigen_hello.cpp rename to kernel_module/user/eigen.cpp index c7d480a..ee79d86 100644 --- a/kernel_module/user/eigen_hello.cpp +++ b/kernel_module/user/eigen.cpp @@ -1,4 +1,6 @@ -/* Adapted from: https://eigen.tuxfamily.org/dox/GettingStarted.html */ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#eigen + * Adapted from: https://eigen.tuxfamily.org/dox/GettingStarted.html + */ #include #include int main() { diff --git a/kernel_module/user/eigen_svd.cpp b/kernel_module/user/eigen_svd.cpp deleted file mode 100644 index c41e0be..0000000 --- a/kernel_module/user/eigen_svd.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* Adapted from: https://eigen.tuxfamily.org/dox/classEigen_1_1JacobiSVD.html */ - -#include -using std::cout; -using std::endl; - -#include -#include -using Eigen::ComputeThinU; -using Eigen::ComputeThinV; -using Eigen::JacobiSVD; -using Eigen::MatrixXf; -using Eigen::Vector3f; - -int main() { - MatrixXf m = MatrixXf::Random(3,2); - JacobiSVD svd(m, ComputeThinU | ComputeThinV); - Vector3f rhs(1, 0, 0); - cout << "m = " << endl << m << endl << endl; - cout << "svd.singularValues() = " << endl << svd.singularValues() << endl << endl; - cout << "svd.MatrixU() = " << endl << svd.matrixU() << endl << endl; - cout << "svd.MatrixV() = " << endl << svd.matrixV() << endl << endl; - cout << "svd.solve() = " << endl << svd.solve(rhs) << endl << endl; -} diff --git a/kernel_module/user/libdrm_modeset.c b/kernel_module/user/libdrm_modeset.c index b69b0de..69e61eb 100644 --- a/kernel_module/user/libdrm_modeset.c +++ b/kernel_module/user/libdrm_modeset.c @@ -1,4 +1,5 @@ -/* Adapted from: https://github.com/dvdhrm/docs/blob/fad7c3203b14e67053e0fc41d8490138b8ff47dd/drm-howto/modeset.c */ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#drm + * Adapted from: https://github.com/dvdhrm/docs/blob/fad7c3203b14e67053e0fc41d8490138b8ff47dd/drm-howto/modeset.c */ /* * modeset - DRM Modesetting Example diff --git a/kernel_module/user/m5ops.c b/kernel_module/user/m5ops.c index 490d6ab..2c3bfa8 100644 --- a/kernel_module/user/m5ops.c +++ b/kernel_module/user/m5ops.c @@ -1,3 +1,5 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#m5ops-instructions */ + #include #include #include diff --git a/kernel_module/user/mmap.c b/kernel_module/user/mmap.c index 77f17fe..106a6b9 100644 --- a/kernel_module/user/mmap.c +++ b/kernel_module/user/mmap.c @@ -1,3 +1,5 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#mmap */ + #define _XOPEN_SOURCE 700 #include #include diff --git a/kernel_module/user/myinsmod.c b/kernel_module/user/myinsmod.c index 83d6686..2a91670 100644 --- a/kernel_module/user/myinsmod.c +++ b/kernel_module/user/myinsmod.c @@ -1,4 +1,4 @@ -/* https://github.com/cirosantilli/linux-kernel-module-cheat#kernel-module-parameters#myinsmod */ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#myinsmod */ #define _GNU_SOURCE #include diff --git a/kernel_module/user/myrmmod.c b/kernel_module/user/myrmmod.c index 32a0975..e4d68b0 100644 --- a/kernel_module/user/myrmmod.c +++ b/kernel_module/user/myrmmod.c @@ -1,3 +1,5 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#myinsmod */ + #define _GNU_SOURCE #include #include diff --git a/kernel_module/user/openblas.c b/kernel_module/user/openblas.c index bc40ec0..9f7381f 100644 --- a/kernel_module/user/openblas.c +++ b/kernel_module/user/openblas.c @@ -1,15 +1,16 @@ -/* Adapted from: https://github.com/xianyi/OpenBLAS/wiki/User-Manual/59b62f98e7400270fb03ad1d85fba5b64ebbff2b#call-cblas-interface */ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#blas + * Adapted from: https://github.com/xianyi/OpenBLAS/wiki/User-Manual/59b62f98e7400270fb03ad1d85fba5b64ebbff2b#call-cblas-interface */ +#include "common.h" + +#include #include -#include -int main() { - size_t i = 0; - double A[6] = {1.0,2.0,1.0,-3.0,4.0,-1.0}; - double B[6] = {1.0,2.0,1.0,-3.0,4.0,-1.0}; - double C[9] = {.5,.5,.5,.5,.5,.5,.5,.5,.5}; - cblas_dgemm(CblasColMajor, CblasNoTrans, CblasTrans,3,3,2,1,A, 3, B, 3,2,C,3); - for(i = 0; i < 9; i++) - printf("%f ", C[i]); - printf("\n"); +int main() +{ + double A[6] = {1.0, 2.0, 1.0, -3.0, 4.0, -1.0}; + double B[6] = {1.0, 2.0, 1.0, -3.0, 4.0, -1.0}; + double C[9] = {0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5}; + cblas_dgemm(CblasColMajor, CblasNoTrans, CblasTrans, 3, 3, 2, 1, A, 3, B, 3, 2, C, 3); + assert(common_vector_equal(9, C, (double[]){11.0, -9.0, 5.0, -9.0, 21.0, -1.0, 5.0, -1.0, 3.0}, 1e-6)); } diff --git a/kernel_module/user/openmp.c b/kernel_module/user/openmp.c index 6099cad..2074aa4 100644 --- a/kernel_module/user/openmp.c +++ b/kernel_module/user/openmp.c @@ -1,3 +1,5 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#openmp */ + #include #include #include diff --git a/kernel_module/user/poll.c b/kernel_module/user/poll.c index dca5aad..c15821b 100644 --- a/kernel_module/user/poll.c +++ b/kernel_module/user/poll.c @@ -1,3 +1,5 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#poll */ + #define _XOPEN_SOURCE 700 #include #include /* creat, O_CREAT */ diff --git a/kernel_module/user/rdtsc.c b/kernel_module/user/rdtsc.c index 949ec65..6159271 100644 --- a/kernel_module/user/rdtsc.c +++ b/kernel_module/user/rdtsc.c @@ -1,9 +1,4 @@ -/* -Only works in x86_64. - -- https://en.wikipedia.org/wiki/Time_Stamp_Counter -- https://stackoverflow.com/questions/9887839/clock-cycle-count-wth-gcc/9887979 -*/ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#rdtsc */ #include #include