mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-27 20:14:27 +01:00
migrate all
This commit is contained in:
227
README.adoc
227
README.adoc
@@ -440,11 +440,11 @@ OK, now time to hack GCC.
|
|||||||
|
|
||||||
For convenience, let's use the <<user-mode-simulation>>.
|
For convenience, let's use the <<user-mode-simulation>>.
|
||||||
|
|
||||||
If we run the program link:userland/gcc_hack.c[]:
|
If we run the program link:userland/c/gcc_hack.c[]:
|
||||||
|
|
||||||
....
|
....
|
||||||
./build-userland --static
|
./build-userland --static
|
||||||
./run --static --userland gcc_hack
|
./run --static --userland c/gcc_hack
|
||||||
....
|
....
|
||||||
|
|
||||||
it produces the normal boring output:
|
it produces the normal boring output:
|
||||||
@@ -496,7 +496,7 @@ Now rebuild GCC, the program and re-run it:
|
|||||||
....
|
....
|
||||||
./build-buildroot -- host-gcc-final-rebuild
|
./build-buildroot -- host-gcc-final-rebuild
|
||||||
./build-userland --static
|
./build-userland --static
|
||||||
./run --static --userland gcc_hack
|
./run --static --userland c/gcc_hack
|
||||||
....
|
....
|
||||||
|
|
||||||
and the new ouptut is now:
|
and the new ouptut is now:
|
||||||
@@ -1003,6 +1003,12 @@ Do a more clean out of tree build and run the program instead:
|
|||||||
"$(./getvar --userland-build-id host userland_build_dir)/hello.out"
|
"$(./getvar --userland-build-id host userland_build_dir)/hello.out"
|
||||||
....
|
....
|
||||||
|
|
||||||
|
If you modify a dependency that is not currently considered such as a header file, force the rebuild with:
|
||||||
|
|
||||||
|
....
|
||||||
|
./build --force-rebuild
|
||||||
|
....
|
||||||
|
|
||||||
===== Userland setup getting started full system
|
===== Userland setup getting started full system
|
||||||
|
|
||||||
First ensure that <<qemu-buildroot-setup>> is working.
|
First ensure that <<qemu-buildroot-setup>> is working.
|
||||||
@@ -1551,7 +1557,7 @@ So once we find the address the first time, we can just reuse it afterwards, as
|
|||||||
Do a fresh boot and get the module:
|
Do a fresh boot and get the module:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --eval-after './pr_debug.sh;insmod fops.ko;./poweroff.out'
|
./run --eval-after './pr_debug.sh;insmod fops.ko;./linux/poweroff.out'
|
||||||
....
|
....
|
||||||
|
|
||||||
The boot must be fresh, because the load address changes every time we insert, even after removing previous modules.
|
The boot must be fresh, because the load address changes every time we insert, even after removing previous modules.
|
||||||
@@ -1585,7 +1591,7 @@ so the offset address is `0x240` and we deduce that the function will be placed
|
|||||||
Now we can just do a fresh boot on shell 1:
|
Now we can just do a fresh boot on shell 1:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --eval 'insmod fops.ko;./poweroff.out' --wait-gdb
|
./run --eval 'insmod fops.ko;./linux/poweroff.out' --wait-gdb
|
||||||
....
|
....
|
||||||
|
|
||||||
and on shell 2:
|
and on shell 2:
|
||||||
@@ -2653,13 +2659,13 @@ This method is not very flexible however, as it is hard to reliably pass multipl
|
|||||||
For this reason, we have created a more robust helper method with the `--eval` option:
|
For this reason, we have created a more robust helper method with the `--eval` option:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --eval 'echo "asdf qwer";insmod hello.ko;./poweroff.out'
|
./run --eval 'echo "asdf qwer";insmod hello.ko;./linux/poweroff.out'
|
||||||
....
|
....
|
||||||
|
|
||||||
It is basically a shortcut for:
|
It is basically a shortcut for:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --kernel-cli 'init=/lkmc/eval_base64.sh - lkmc_eval="insmod hello.ko;./poweroff.out"'
|
./run --kernel-cli 'init=/lkmc/eval_base64.sh - lkmc_eval="insmod hello.ko;./linux/poweroff.out"'
|
||||||
....
|
....
|
||||||
|
|
||||||
Source: link:rootfs_overlay/lkmc/eval_base64.sh[].
|
Source: link:rootfs_overlay/lkmc/eval_base64.sh[].
|
||||||
@@ -2689,7 +2695,7 @@ If the script is large, you can add it to a gitignored file and pass that to `--
|
|||||||
echo '
|
echo '
|
||||||
cd /lkmc
|
cd /lkmc
|
||||||
insmod hello.ko
|
insmod hello.ko
|
||||||
./poweroff.out
|
./linux/poweroff.out
|
||||||
' > data/gitignore.sh
|
' > data/gitignore.sh
|
||||||
./run --eval "$(cat data/gitignore.sh)"
|
./run --eval "$(cat data/gitignore.sh)"
|
||||||
....
|
....
|
||||||
@@ -2700,7 +2706,7 @@ or add it to a file to the root filesystem guest and rebuild:
|
|||||||
echo '#!/bin/sh
|
echo '#!/bin/sh
|
||||||
cd /lkmc
|
cd /lkmc
|
||||||
insmod hello.ko
|
insmod hello.ko
|
||||||
./poweroff.out
|
./linux/poweroff.out
|
||||||
' > rootfs_overlay/lkmc/gitignore.sh
|
' > rootfs_overlay/lkmc/gitignore.sh
|
||||||
chmod +x rootfs_overlay/lkmc/gitignore.sh
|
chmod +x rootfs_overlay/lkmc/gitignore.sh
|
||||||
./build-buildroot
|
./build-buildroot
|
||||||
@@ -2724,19 +2730,19 @@ because BusyBox' `poweroff` tries to do some fancy stuff like killing init, like
|
|||||||
|
|
||||||
But this fails when we are `init` itself!
|
But this fails when we are `init` itself!
|
||||||
|
|
||||||
`poweroff` works more brutally and effectively if you add `-f`:
|
BusyBox' `poweroff` works more brutally and effectively if you add `-f`:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --eval 'poweroff -f'
|
./run --eval 'poweroff -f'
|
||||||
....
|
....
|
||||||
|
|
||||||
but why not just use our minimal `./poweroff.out` and be done with it?
|
but why not just use our minimal `./linux/poweroff.out` and be done with it?
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --eval './poweroff.out'
|
./run --eval './linux/poweroff.out'
|
||||||
....
|
....
|
||||||
|
|
||||||
Source: link:userland/poweroff.c[]
|
Source: link:userland/linux/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
|
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
|
||||||
|
|
||||||
@@ -2745,28 +2751,30 @@ This also illustrates how to shutdown the computer from C: https://stackoverflow
|
|||||||
I dare you to guess what this does:
|
I dare you to guess what this does:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --eval './sleep_forever.out'
|
./run --eval './posix/sleep_forever.out'
|
||||||
....
|
....
|
||||||
|
|
||||||
Source: link:userland/sleep_forever.c[]
|
Source: link:userland/posix/sleep_forever.c[]
|
||||||
|
|
||||||
This executable is a convenient simple init that does not panic and sleeps instead.
|
This executable is a convenient simple init that does not panic and sleeps instead.
|
||||||
|
|
||||||
==== time_boot.out
|
==== time_boot.out
|
||||||
|
|
||||||
Get a reasonable answer to "how long does boot take?":
|
Get a reasonable answer to "how long does boot take in guest time?":
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --eval-after './time_boot.out'
|
./run --eval-after './linux/time_boot.c'
|
||||||
....
|
....
|
||||||
|
|
||||||
Dmesg contains a message of type:
|
Source: link:userland/linux/time_boot.out[]
|
||||||
|
|
||||||
|
That executable writes to `dmesg` directly through `/dev/kmsg` a message of type:
|
||||||
|
|
||||||
....
|
....
|
||||||
[ 2.188242] time_boot.c
|
[ 2.188242] /path/to/linux-kernel-module-cheat/userland/linux/time_boot.c
|
||||||
....
|
....
|
||||||
|
|
||||||
which tells us that boot took `2.188242` seconds.
|
which tells us that boot took `2.188242` seconds based on the dmesg timestamp.
|
||||||
|
|
||||||
Bibliography: https://stackoverflow.com/questions/12683169/measure-time-taken-for-linux-kernel-from-bootup-to-userpace/46517014#46517014
|
Bibliography: https://stackoverflow.com/questions/12683169/measure-time-taken-for-linux-kernel-from-bootup-to-userpace/46517014#46517014
|
||||||
|
|
||||||
@@ -2784,7 +2792,7 @@ After the commands run, you are left on an interactive shell.
|
|||||||
The above command is basically equivalent to:
|
The above command is basically equivalent to:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --kernel-cli-after-dash 'lkmc_eval="insmod hello.ko;./poweroff.out;"'
|
./run --kernel-cli-after-dash 'lkmc_eval="insmod hello.ko;./linux/poweroff.out;"'
|
||||||
....
|
....
|
||||||
|
|
||||||
where the `lkmc_eval` option gets evaled by our default link:rootfs_overlay/etc/init.d/S98[] startup script.
|
where the `lkmc_eval` option gets evaled by our default link:rootfs_overlay/etc/init.d/S98[] startup script.
|
||||||
@@ -2850,7 +2858,7 @@ The annoying dash `-` gets passed as a parameter to `init`, which makes it impos
|
|||||||
Arguments with dots that come after `-` are still treated specially (of the form `subsystem.somevalue`) and disappear, from args, e.g.:
|
Arguments with dots that come after `-` are still treated specially (of the form `subsystem.somevalue`) and disappear, from args, e.g.:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --kernel-cli 'init=/lkmc/init_env_poweroff.out - /lkmc/poweroff.out'
|
./run --kernel-cli 'init=/lkmc/init_env_poweroff.out - /lkmc/linux/poweroff.out'
|
||||||
....
|
....
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
@@ -3399,6 +3407,33 @@ If you modify the userland programs, rebuild simply with:
|
|||||||
./build-userland
|
./build-userland
|
||||||
....
|
....
|
||||||
|
|
||||||
|
==== User mode GDB step debug
|
||||||
|
|
||||||
|
The commands are analogous to full system <<gdb>>, e.g. without tmux:
|
||||||
|
|
||||||
|
....
|
||||||
|
./run \
|
||||||
|
--userland print_argv \
|
||||||
|
--userland-args 'asdf "qw er"' \
|
||||||
|
--wait-gdb \
|
||||||
|
;
|
||||||
|
./run-gdb \
|
||||||
|
--userland print_argv \
|
||||||
|
main
|
||||||
|
;
|
||||||
|
....
|
||||||
|
|
||||||
|
or with <<tmux>>:
|
||||||
|
|
||||||
|
....
|
||||||
|
./run \
|
||||||
|
--userland print_argv \
|
||||||
|
--userland-args 'asdf "qw er"' \
|
||||||
|
--tmux-args main \
|
||||||
|
--wait-gdb \
|
||||||
|
;
|
||||||
|
....
|
||||||
|
|
||||||
==== User mode with host toolchain and QEMU
|
==== User mode with host toolchain and QEMU
|
||||||
|
|
||||||
If you are lazy to built the Buildroot toolchain and QEMU, you can get away on Ubuntu 18.04 with just:
|
If you are lazy to built the Buildroot toolchain and QEMU, you can get away on Ubuntu 18.04 with just:
|
||||||
@@ -3532,7 +3567,7 @@ So programs that rely on those libraries might not compile as GCC can't find the
|
|||||||
For example, if we try to build <<blas>> statically:
|
For example, if we try to build <<blas>> statically:
|
||||||
|
|
||||||
....
|
....
|
||||||
./build-userland --has-package openblas --static -- openblas_hello
|
./build-userland --has-package openblas --static -- libs/openblas_hello
|
||||||
....
|
....
|
||||||
|
|
||||||
it fails with:
|
it fails with:
|
||||||
@@ -3615,7 +3650,7 @@ So let's just play with some static ones:
|
|||||||
|
|
||||||
TODO: how to escape spaces on the command line arguments?
|
TODO: how to escape spaces on the command line arguments?
|
||||||
|
|
||||||
Step debug also works:
|
<<user-mode-gdb-step-debug,GDB step debug>> also works normally on gem5:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run \
|
./run \
|
||||||
@@ -3708,7 +3743,7 @@ QEMU full system:
|
|||||||
time \
|
time \
|
||||||
./run \
|
./run \
|
||||||
--arch arm \
|
--arch arm \
|
||||||
--eval-after 'time dhrystone 100000000;./poweroff.out' \
|
--eval-after 'time dhrystone 100000000;./linux/poweroff.out' \
|
||||||
;
|
;
|
||||||
....
|
....
|
||||||
|
|
||||||
@@ -5128,11 +5163,11 @@ and so it is Read Only as shown by `ro`.
|
|||||||
Disable userland address space randomization. Test it out by running <<rand_check-out>> twice:
|
Disable userland address space randomization. Test it out by running <<rand_check-out>> twice:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --eval-after './rand_check.out;./poweroff.out'
|
./run --eval-after './linux/rand_check.out;./linux/poweroff.out'
|
||||||
./run --eval-after './rand_check.out;./poweroff.out'
|
./run --eval-after './linux/rand_check.out;./linux/poweroff.out'
|
||||||
....
|
....
|
||||||
|
|
||||||
If we remove it from our link:run[] script by hacking it up, the addresses shown by `rand_check.out` vary across boots.
|
If we remove it from our link:run[] script by hacking it up, the addresses shown by `linux/rand_check.out` vary across boots.
|
||||||
|
|
||||||
Equivalent to:
|
Equivalent to:
|
||||||
|
|
||||||
@@ -7525,7 +7560,7 @@ TODO `--arch arm` and `--arch aarch64` does not count firmware instructions prop
|
|||||||
* We can also discount the instructions after `init` runs by using `readelf` to get the initial address of `init`. One easy way to do that now is to just run:
|
* We can also discount the instructions after `init` runs by using `readelf` to get the initial address of `init`. One easy way to do that now is to just run:
|
||||||
+
|
+
|
||||||
....
|
....
|
||||||
./run-gdb-user "$(./getvar userland_build_dir)/poweroff.out" main
|
./run-gdb-user "$(./getvar userland_build_dir)/linux/poweroff.out" main
|
||||||
....
|
....
|
||||||
+
|
+
|
||||||
And get that from the traces, e.g. if the address is `4003a0`, then we search:
|
And get that from the traces, e.g. if the address is `4003a0`, then we search:
|
||||||
@@ -7818,10 +7853,10 @@ echo 0 > /proc/sys/kernel/ctrl-alt-del
|
|||||||
Minimal example:
|
Minimal example:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --kernel-cli 'init=/lkmc/ctrl_alt_del.out' --graphic
|
./run --kernel-cli 'init=/lkmc/linux/ctrl_alt_del.out' --graphic
|
||||||
....
|
....
|
||||||
|
|
||||||
Source: link:userland/ctrl_alt_del.c[]
|
Source: link:userland/linux/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:
|
When you hit `Ctrl-Alt-Del` in the guest, our tiny init handles a `SIGINT` sent by the kernel and outputs to stdout:
|
||||||
|
|
||||||
@@ -8134,11 +8169,11 @@ DRM / DRI is the new interface that supersedes `fbdev`:
|
|||||||
|
|
||||||
....
|
....
|
||||||
./build-buildroot --config 'BR2_PACKAGE_LIBDRM=y'
|
./build-buildroot --config 'BR2_PACKAGE_LIBDRM=y'
|
||||||
./build-userland --has-package libdrm -- libdrm_modeset
|
./build-userland --has-package libdrm -- libs/libdrm_modeset
|
||||||
./run --eval-after './libdrm_modeset.out' --graphic
|
./run --eval-after './libs/libdrm_modeset.out' --graphic
|
||||||
....
|
....
|
||||||
|
|
||||||
Source: link:userland/libdrm_modeset.c[]
|
Source: link:userland/libs/libdrm_modeset.c[]
|
||||||
|
|
||||||
Outcome: for a few seconds, the screen that contains the terminal gets taken over by changing colors of the rainbow.
|
Outcome: for a few seconds, the screen that contains the terminal gets taken over by changing colors of the rainbow.
|
||||||
|
|
||||||
@@ -8148,7 +8183,7 @@ TODO not working for `aarch64`, it takes over the screen for a few seconds and t
|
|||||||
./build-buildroot --config 'BR2_PACKAGE_LIBDRM=y'
|
./build-buildroot --config 'BR2_PACKAGE_LIBDRM=y'
|
||||||
./build-userland --has-package libdrm
|
./build-userland --has-package libdrm
|
||||||
./build-buildroot
|
./build-buildroot
|
||||||
./run --eval-after './libdrm_modeset.out' --graphic
|
./run --eval-after './libs/libdrm_modeset.out' --graphic
|
||||||
....
|
....
|
||||||
|
|
||||||
<<kmscube>> however worked, which means that it must be a bug with this demo?
|
<<kmscube>> however worked, which means that it must be a bug with this demo?
|
||||||
@@ -8173,7 +8208,7 @@ Try creating new displays:
|
|||||||
to see multiple `/dev/dri/cardN`, and then use a different display with:
|
to see multiple `/dev/dri/cardN`, and then use a different display with:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --eval-after './libdrm_modeset.out' --graphic
|
./run --eval-after './libs/libdrm_modeset.out' --graphic
|
||||||
....
|
....
|
||||||
|
|
||||||
Bibliography:
|
Bibliography:
|
||||||
@@ -9204,7 +9239,7 @@ QEMU also has a second trace mechanism in addition to `-trace`, find out the eve
|
|||||||
Let's pick the one that dumps executed instructions, `in_asm`:
|
Let's pick the one that dumps executed instructions, `in_asm`:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --eval './poweroff.out' -- -D out/trace.txt -d in_asm
|
./run --eval './linux/poweroff.out' -- -D out/trace.txt -d in_asm
|
||||||
less out/trace.txt
|
less out/trace.txt
|
||||||
....
|
....
|
||||||
|
|
||||||
@@ -9280,15 +9315,15 @@ This awesome feature allows you to examine a single run as many times as you wou
|
|||||||
|
|
||||||
....
|
....
|
||||||
# Record a run.
|
# Record a run.
|
||||||
./run --eval-after './rand_check.out;./poweroff.out;' --record
|
./run --eval-after './linux/rand_check.out;./linux/poweroff.out;' --record
|
||||||
# Replay the run.
|
# Replay the run.
|
||||||
./run --eval-after './rand_check.out;./poweroff.out;' --replay
|
./run --eval-after './linux/rand_check.out;./linux/poweroff.out;' --replay
|
||||||
....
|
....
|
||||||
|
|
||||||
A convenient shortcut to do both at once to test the feature is:
|
A convenient shortcut to do both at once to test the feature is:
|
||||||
|
|
||||||
....
|
....
|
||||||
./qemu-rr --eval-after './rand_check.out;./poweroff.out;'
|
./qemu-rr --eval-after './linux/rand_check.out;./linux/poweroff.out;'
|
||||||
....
|
....
|
||||||
|
|
||||||
By comparing the terminal output of both runs, we can see that they are the exact same, including things which normally differ across runs:
|
By comparing the terminal output of both runs, we can see that they are the exact same, including things which normally differ across runs:
|
||||||
@@ -9315,7 +9350,7 @@ EXT4-fs (sda): re-mounted. Opts: block_validity,barrier,user_xattr
|
|||||||
TODO replay with network gets stuck:
|
TODO replay with network gets stuck:
|
||||||
|
|
||||||
....
|
....
|
||||||
./qemu-rr --eval-after 'ifup -a;wget -S google.com;./poweroff.out;'
|
./qemu-rr --eval-after 'ifup -a;wget -S google.com;./linux/poweroff.out;'
|
||||||
....
|
....
|
||||||
|
|
||||||
after the message:
|
after the message:
|
||||||
@@ -9334,7 +9369,7 @@ Then, when I tried with <<initrd>> and no disk:
|
|||||||
|
|
||||||
....
|
....
|
||||||
./build-buildroot --arch aarch64 --initrd
|
./build-buildroot --arch aarch64 --initrd
|
||||||
./qemu-rr --arch aarch64 --eval-after './rand_check.out;./poweroff.out;' --initrd
|
./qemu-rr --arch aarch64 --eval-after './linux/rand_check.out;./linux/poweroff.out;' --initrd
|
||||||
....
|
....
|
||||||
|
|
||||||
QEMU crashes with:
|
QEMU crashes with:
|
||||||
@@ -9354,8 +9389,8 @@ TODO get working.
|
|||||||
QEMU replays support checkpointing, and this allows for a simplistic "reverse debugging" implementation proposed at https://lists.gnu.org/archive/html/qemu-devel/2018-06/msg00478.html on the unmerged link:https://github.com/ispras/qemu/tree/rr-180725[]:
|
QEMU replays support checkpointing, and this allows for a simplistic "reverse debugging" implementation proposed at https://lists.gnu.org/archive/html/qemu-devel/2018-06/msg00478.html on the unmerged link:https://github.com/ispras/qemu/tree/rr-180725[]:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --eval-after './rand_check.out;./poweroff.out;' --record
|
./run --eval-after './linux/rand_check.out;./linux/poweroff.out;' --record
|
||||||
./run --eval-after './rand_check.out;./poweroff.out;' --replay --wait-gdb
|
./run --eval-after './linux/rand_check.out;./linux/poweroff.out;' --replay --wait-gdb
|
||||||
....
|
....
|
||||||
|
|
||||||
On another shell:
|
On another shell:
|
||||||
@@ -9381,7 +9416,7 @@ and we are back at `start_kernel`
|
|||||||
TODO: is there any way to distinguish which instruction runs on each core? Doing:
|
TODO: is there any way to distinguish which instruction runs on each core? Doing:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --arch x86_64 --cpus 2 --eval './poweroff.out' --trace exec_tb
|
./run --arch x86_64 --cpus 2 --eval './linux/poweroff.out' --trace exec_tb
|
||||||
./qemu-trace2txt
|
./qemu-trace2txt
|
||||||
....
|
....
|
||||||
|
|
||||||
@@ -9874,8 +9909,8 @@ Buildroot supports it, which makes everything just trivial:
|
|||||||
|
|
||||||
....
|
....
|
||||||
./build-buildroot --config 'BR2_PACKAGE_OPENBLAS=y'
|
./build-buildroot --config 'BR2_PACKAGE_OPENBLAS=y'
|
||||||
./build-userland --has-package openblas -- openblas_hello
|
./build-userland --has-package openblas -- libs/openblas_hello
|
||||||
./run --eval-after './openblas_hello.out; echo $?'
|
./run --eval-after './libs/openblas_hello.out; echo $?'
|
||||||
....
|
....
|
||||||
|
|
||||||
Outcome: the test passes:
|
Outcome: the test passes:
|
||||||
@@ -9884,7 +9919,7 @@ Outcome: the test passes:
|
|||||||
0
|
0
|
||||||
....
|
....
|
||||||
|
|
||||||
Source: link:userland/openblas.c[]
|
Source: link:userland/libs/openblas.c[]
|
||||||
|
|
||||||
The test performs a general matrix multiplication:
|
The test performs a general matrix multiplication:
|
||||||
|
|
||||||
@@ -9914,13 +9949,13 @@ Header only linear algebra library with a mainline Buildroot package:
|
|||||||
|
|
||||||
....
|
....
|
||||||
./build-buildroot --config 'BR2_PACKAGE_EIGEN=y'
|
./build-buildroot --config 'BR2_PACKAGE_EIGEN=y'
|
||||||
./build-userland --has-package eigen -- eigen_hello
|
./build-userland --has-package eigen -- libs/eigen_hello
|
||||||
....
|
....
|
||||||
|
|
||||||
Just create an array and print it:
|
Just create an array and print it:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --eval-after './eigen_hello.out'
|
./run --eval-after './libs/eigen_hello.out'
|
||||||
....
|
....
|
||||||
|
|
||||||
Output:
|
Output:
|
||||||
@@ -9930,7 +9965,7 @@ Output:
|
|||||||
2.5 1.5
|
2.5 1.5
|
||||||
....
|
....
|
||||||
|
|
||||||
Source: link:userland/eigen_hello.cpp[]
|
Source: link:userland/libs/eigen_hello.cpp[]
|
||||||
|
|
||||||
This example just creates a matrix and prints it out.
|
This example just creates a matrix and prints it out.
|
||||||
|
|
||||||
@@ -10104,7 +10139,7 @@ You may also want to test if your patches are still functionally correct inside
|
|||||||
Analogous <<kernel-command-line-parameters,to QEMU>>:
|
Analogous <<kernel-command-line-parameters,to QEMU>>:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --arch arm --kernel-cli 'init=/lkmc/poweroff.out' --emulator gem5
|
./run --arch arm --kernel-cli 'init=/lkmc/linux/poweroff.out' --emulator gem5
|
||||||
....
|
....
|
||||||
|
|
||||||
Internals: when we give `--command-line=` to gem5, it overrides default command lines, including some mandatory ones which are required to boot properly.
|
Internals: when we give `--command-line=` to gem5, it overrides default command lines, including some mandatory ones which are required to boot properly.
|
||||||
@@ -10738,39 +10773,7 @@ system.cpu.dtb.inst_misses
|
|||||||
system.cpu.dtb.inst_hits
|
system.cpu.dtb.inst_hits
|
||||||
....
|
....
|
||||||
|
|
||||||
==== rdtsc
|
For x86, it is interesting to try and correlate `numCycles` with:
|
||||||
|
|
||||||
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-userland -- rdtsc
|
|
||||||
./run --eval './rdtsc.out;m5 exit;' --emulator gem5
|
|
||||||
./gem5-stat
|
|
||||||
....
|
|
||||||
|
|
||||||
Source: link:userland/rdtsc.c[]
|
|
||||||
|
|
||||||
`rdtsc` outputs a cycle count which we compare with gem5's `gem5-stat`:
|
|
||||||
|
|
||||||
* `3828578153`: `rdtsc`
|
|
||||||
* `3830832635`: `gem5-stat`
|
|
||||||
|
|
||||||
which gives pretty close results, and serve as a nice sanity check that the cycle counter is coherent.
|
|
||||||
|
|
||||||
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`.
|
|
||||||
|
|
||||||
Bibliography:
|
|
||||||
|
|
||||||
* https://en.wikipedia.org/wiki/Time_Stamp_Counter
|
|
||||||
* https://stackoverflow.com/questions/9887839/clock-cycle-count-wth-gcc/9887979
|
|
||||||
|
|
||||||
===== pmccntr
|
|
||||||
|
|
||||||
TODO We didn't manage to find a working ARM analogue to <<rdtsc>>: link:kernel_modules/pmccntr.c[] is oopsing, and even it if weren't, it likely won't give the cycle count since boot since it needs to be activate before it starts counting anything:
|
|
||||||
|
|
||||||
* https://stackoverflow.com/questions/40454157/is-there-an-equivalent-instruction-to-rdtsc-in-arm
|
|
||||||
* https://stackoverflow.com/questions/31620375/arm-cortex-a7-returning-pmccntr-0-in-kernel-mode-and-illegal-instruction-in-u/31649809#31649809
|
|
||||||
* https://blog.regehr.org/archives/794
|
|
||||||
|
|
||||||
==== config.ini
|
==== config.ini
|
||||||
|
|
||||||
@@ -11575,6 +11578,42 @@ Getting started at: <<userland-assembly>>.
|
|||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
|
=== rdtsc
|
||||||
|
|
||||||
|
TODO: review this section, make a more controlled userland experiment with <<m5ops>> instrumentation.
|
||||||
|
|
||||||
|
Let's have some fun and try to correlate the gem5 <<stats-txt>> `system.cpu.numCycles` cycle count with the link:https://en.wikipedia.org/wiki/Time_Stamp_Counter[x86 `rdtsc` instruction] that is supposed to do the same thing:
|
||||||
|
|
||||||
|
....
|
||||||
|
./build-userland --static arch/x86_64/c/rdtsc
|
||||||
|
./run --eval './arch/x86_64/c/rdtsc.out;m5 exit;' --emulator gem5
|
||||||
|
./gem5-stat
|
||||||
|
....
|
||||||
|
|
||||||
|
Source: link:userland/rdtsc.c[]
|
||||||
|
|
||||||
|
`rdtsc` outputs a cycle count which we compare with gem5's `gem5-stat`:
|
||||||
|
|
||||||
|
* `3828578153`: `rdtsc`
|
||||||
|
* `3830832635`: `gem5-stat`
|
||||||
|
|
||||||
|
which gives pretty close results, and serve as a nice sanity check that the cycle counter is coherent.
|
||||||
|
|
||||||
|
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`.
|
||||||
|
|
||||||
|
Bibliography:
|
||||||
|
|
||||||
|
* https://en.wikipedia.org/wiki/Time_Stamp_Counter
|
||||||
|
* https://stackoverflow.com/questions/9887839/clock-cycle-count-wth-gcc/9887979
|
||||||
|
|
||||||
|
==== ARM pmccntr
|
||||||
|
|
||||||
|
TODO We didn't manage to find a working ARM analogue to <<rdtsc>>: link:kernel_modules/pmccntr.c[] is oopsing, and even it if weren't, it likely won't give the cycle count since boot since it needs to be activate before it starts counting anything:
|
||||||
|
|
||||||
|
* https://stackoverflow.com/questions/40454157/is-there-an-equivalent-instruction-to-rdtsc-in-arm
|
||||||
|
* https://stackoverflow.com/questions/31620375/arm-cortex-a7-returning-pmccntr-0-in-kernel-mode-and-illegal-instruction-in-u/31649809#31649809
|
||||||
|
* https://blog.regehr.org/archives/794
|
||||||
|
|
||||||
== arm userland assembly
|
== arm userland assembly
|
||||||
|
|
||||||
Getting started at: <<userland-assembly>>.
|
Getting started at: <<userland-assembly>>.
|
||||||
@@ -12700,15 +12739,15 @@ cat "$(./getvar test_boot_benchmark_file)"
|
|||||||
Sample results at 8fb9db39316d43a6dbd571e04dd46ae73915027f:
|
Sample results at 8fb9db39316d43a6dbd571e04dd46ae73915027f:
|
||||||
|
|
||||||
....
|
....
|
||||||
cmd ./run --arch x86_64 --eval './poweroff.out'
|
cmd ./run --arch x86_64 --eval './linux/poweroff.out'
|
||||||
time 8.25
|
time 8.25
|
||||||
exit_status 0
|
exit_status 0
|
||||||
|
|
||||||
cmd ./run --arch x86_64 --eval './poweroff.out' --kvm
|
cmd ./run --arch x86_64 --eval './linux/poweroff.out' --kvm
|
||||||
time 1.22
|
time 1.22
|
||||||
exit_status 0
|
exit_status 0
|
||||||
|
|
||||||
cmd ./run --arch x86_64 --eval './poweroff.out' --trace exec_tb
|
cmd ./run --arch x86_64 --eval './linux/poweroff.out' --trace exec_tb
|
||||||
time 8.83
|
time 8.83
|
||||||
exit_status 0
|
exit_status 0
|
||||||
instructions 2244297
|
instructions 2244297
|
||||||
@@ -12718,10 +12757,10 @@ time 213.39
|
|||||||
exit_status 0
|
exit_status 0
|
||||||
instructions 318486337
|
instructions 318486337
|
||||||
|
|
||||||
cmd ./run --arch arm --eval './poweroff.out'
|
cmd ./run --arch arm --eval './linux/poweroff.out'
|
||||||
time 6.62
|
time 6.62
|
||||||
exit_status 0
|
exit_status 0
|
||||||
cmd ./run --arch arm --eval './poweroff.out' --trace exec_tb
|
cmd ./run --arch arm --eval './linux/poweroff.out' --trace exec_tb
|
||||||
time 6.90
|
time 6.90
|
||||||
exit_status 0
|
exit_status 0
|
||||||
instructions 776374
|
instructions 776374
|
||||||
@@ -12736,11 +12775,11 @@ time 2250.40
|
|||||||
exit_status 0
|
exit_status 0
|
||||||
instructions 151981914
|
instructions 151981914
|
||||||
|
|
||||||
cmd ./run --arch aarch64 --eval './poweroff.out'
|
cmd ./run --arch aarch64 --eval './linux/poweroff.out'
|
||||||
time 4.94
|
time 4.94
|
||||||
exit_status 0
|
exit_status 0
|
||||||
|
|
||||||
cmd ./run --arch aarch64 --eval './poweroff.out' --trace exec_tb
|
cmd ./run --arch aarch64 --eval './linux/poweroff.out' --trace exec_tb
|
||||||
time 5.04
|
time 5.04
|
||||||
exit_status 0
|
exit_status 0
|
||||||
instructions 233162
|
instructions 233162
|
||||||
@@ -13567,10 +13606,10 @@ We try to keep as much as possible in those files. It bloats builds a little, bu
|
|||||||
Print out several parameters that normally change randomly from boot to boot:
|
Print out several parameters that normally change randomly from boot to boot:
|
||||||
|
|
||||||
....
|
....
|
||||||
./run --eval-after './rand_check.out;./poweroff.out'
|
./run --eval-after './linux/rand_check.out;./linux/poweroff.out'
|
||||||
....
|
....
|
||||||
|
|
||||||
Source: link:userland/rand_check.c[]
|
Source: link:userland/linux/rand_check.c[]
|
||||||
|
|
||||||
This can be used to check the determinism of:
|
This can be used to check the determinism of:
|
||||||
|
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ set -eu
|
|||||||
git submodule update --recursive
|
git submodule update --recursive
|
||||||
cd ../..
|
cd ../..
|
||||||
./build-qemu --arch aarch64 --qemu-build-id bisect
|
./build-qemu --arch aarch64 --qemu-build-id bisect
|
||||||
./run --arch aarch64 --kernel-cli 'init=/poweroff.out' --qemu-build-id bisect
|
./run --arch aarch64 --kernel-cli 'init=/lkmc/linux/poweroff.out' --qemu-build-id bisect
|
||||||
|
|||||||
@@ -228,6 +228,7 @@ Default: build all examples that have their package dependencies met, e.g.:
|
|||||||
do_build_dir = False
|
do_build_dir = False
|
||||||
else:
|
else:
|
||||||
do_build_dir = False
|
do_build_dir = False
|
||||||
|
in_libs = dirpath_relative_root_components[0] == 'libs'
|
||||||
if do_build_dir:
|
if do_build_dir:
|
||||||
out_dir = os.path.join(
|
out_dir = os.path.join(
|
||||||
build_dir,
|
build_dir,
|
||||||
@@ -235,7 +236,7 @@ Default: build all examples that have their package dependencies met, e.g.:
|
|||||||
)
|
)
|
||||||
common_objs_dir = [common_obj]
|
common_objs_dir = [common_obj]
|
||||||
ccflags_dir = ccflags.copy()
|
ccflags_dir = ccflags.copy()
|
||||||
if dirpath_relative_root_components == ['gcc']:
|
if dirpath_relative_root_components in ('gcc', 'kernel_modules', 'linux'):
|
||||||
cstd = 'gnu11'
|
cstd = 'gnu11'
|
||||||
cxxstd = 'gnu++17'
|
cxxstd = 'gnu++17'
|
||||||
else:
|
else:
|
||||||
@@ -290,31 +291,32 @@ Default: build all examples that have their package dependencies met, e.g.:
|
|||||||
out_dir,
|
out_dir,
|
||||||
in_name + self.env['userland_build_ext']
|
in_name + self.env['userland_build_ext']
|
||||||
)
|
)
|
||||||
pkg_key = in_name.split('_')[0]
|
|
||||||
ccflags_file = ccflags_dir.copy()
|
ccflags_file = ccflags_dir.copy()
|
||||||
ccflags_after = []
|
ccflags_after = []
|
||||||
if pkg_key in pkgs:
|
if in_libs:
|
||||||
if pkg_key not in has_packages:
|
pkg_key = in_name.split('_')[0]
|
||||||
continue
|
if pkg_key in pkgs:
|
||||||
pkg = pkgs[pkg_key]
|
if pkg_key not in has_packages:
|
||||||
if 'ccflags' in pkg:
|
continue
|
||||||
ccflags_file.extend(pkg['ccflags'])
|
pkg = pkgs[pkg_key]
|
||||||
else:
|
if 'ccflags' in pkg:
|
||||||
pkg_config_output = subprocess.check_output([
|
ccflags_file.extend(pkg['ccflags'])
|
||||||
self.env['buildroot_pkg_config'],
|
else:
|
||||||
'--cflags',
|
pkg_config_output = subprocess.check_output([
|
||||||
pkg_key
|
self.env['buildroot_pkg_config'],
|
||||||
]).decode()
|
'--cflags',
|
||||||
ccflags_file.extend(self.sh.shlex_split(pkg_config_output))
|
pkg_key
|
||||||
if 'ccflags_after' in pkg:
|
]).decode()
|
||||||
ccflags_file.extend(pkg['ccflags_after'])
|
ccflags_file.extend(self.sh.shlex_split(pkg_config_output))
|
||||||
else:
|
if 'ccflags_after' in pkg:
|
||||||
pkg_config_output = subprocess.check_output([
|
ccflags_file.extend(pkg['ccflags_after'])
|
||||||
self.env['buildroot_pkg_config'],
|
else:
|
||||||
'--libs',
|
pkg_config_output = subprocess.check_output([
|
||||||
pkg_key
|
self.env['buildroot_pkg_config'],
|
||||||
]).decode()
|
'--libs',
|
||||||
ccflags_after.extend(self.sh.shlex_split(pkg_config_output))
|
pkg_key
|
||||||
|
]).decode()
|
||||||
|
ccflags_after.extend(self.sh.shlex_split(pkg_config_output))
|
||||||
error = thread_pool.submit({
|
error = thread_pool.submit({
|
||||||
'in_path': in_path,
|
'in_path': in_path,
|
||||||
'out_path': out_path,
|
'out_path': out_path,
|
||||||
|
|||||||
@@ -705,9 +705,9 @@ Valid emulators: {}
|
|||||||
env['linux_image'] = env['lkmc_linux_image']
|
env['linux_image'] = env['lkmc_linux_image']
|
||||||
env['linux_config'] = join(env['linux_build_dir'], '.config')
|
env['linux_config'] = join(env['linux_build_dir'], '.config')
|
||||||
if env['emulator']== 'gem5':
|
if env['emulator']== 'gem5':
|
||||||
env['userland_quit_cmd'] = '/gem5_exit.sh'
|
env['userland_quit_cmd'] = './gem5_exit.sh'
|
||||||
else:
|
else:
|
||||||
env['userland_quit_cmd'] = '/poweroff.out'
|
env['userland_quit_cmd'] = './poweroff.out'
|
||||||
env['ramfs'] = env['initrd'] or env['initramfs']
|
env['ramfs'] = env['initrd'] or env['initramfs']
|
||||||
if env['ramfs']:
|
if env['ramfs']:
|
||||||
env['initarg'] = 'rdinit'
|
env['initarg'] = 'rdinit'
|
||||||
|
|||||||
14
file_properties.py
Normal file
14
file_properties.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
class FileProperties:
|
||||||
|
def __init__(
|
||||||
|
more_than_1s=False,
|
||||||
|
exits_nonzero=False,
|
||||||
|
interactive=False,
|
||||||
|
):
|
||||||
|
self.more_than_1s = more_than_1s
|
||||||
|
self.exits_nonzero = exits_nonzero
|
||||||
|
|
||||||
|
executable_properties = {
|
||||||
|
'userland/arch/x86_64/c/ring0.c': ExecutableProperties(exits_nonzero=True),
|
||||||
|
}
|
||||||
@@ -3,27 +3,26 @@
|
|||||||
#ifdef THIS_MODULE
|
#ifdef THIS_MODULE
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
typedef u64 T;
|
typedef u64 LkmcRing0RegsType;
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
typedef u32 T;
|
typedef u32 LkmcRing0RegsType;
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
typedef uint64_t T;
|
typedef uint64_t LkmcRing0RegsType;
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
typedef uint32_t T;
|
typedef uint32_t LkmcRing0RegsType;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
T cr0;
|
LkmcRing0RegsType cr0;
|
||||||
T cr2;
|
LkmcRing0RegsType cr2;
|
||||||
T cr3;
|
LkmcRing0RegsType cr3;
|
||||||
} Ring0Regs;
|
} LkmcRing0Regs;
|
||||||
|
|
||||||
void ring0_get_control_regs(Ring0Regs *ring0_regs)
|
void lkmc_ring0_get_control_regs(LkmcRing0Regs *ring0_regs) {
|
||||||
{
|
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
"mov %%cr0, %%rax;"
|
"mov %%cr0, %%rax;"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#pmccntr */
|
/* https://github.com/cirosantilli/linux-kernel-module-cheat#arm-pmccntr */
|
||||||
|
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/errno.h> /* EFAULT */
|
#include <linux/errno.h> /* EFAULT */
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
static int myinit(void)
|
static int myinit(void)
|
||||||
{
|
{
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
Ring0Regs ring0_regs;
|
LkmcRing0Regs ring0_regs;
|
||||||
ring0_get_control_regs(&ring0_regs);
|
lkmc_ring0_get_control_regs(&ring0_regs);
|
||||||
pr_info("cr0 = 0x%8.8llX\n", (unsigned long long)ring0_regs.cr0);
|
pr_info("cr0 = 0x%8.8llX\n", (unsigned long long)ring0_regs.cr0);
|
||||||
pr_info("cr2 = 0x%8.8llX\n", (unsigned long long)ring0_regs.cr2);
|
pr_info("cr2 = 0x%8.8llX\n", (unsigned long long)ring0_regs.cr2);
|
||||||
pr_info("cr3 = 0x%8.8llX\n", (unsigned long long)ring0_regs.cr3);
|
pr_info("cr3 = 0x%8.8llX\n", (unsigned long long)ring0_regs.cr3);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -ex
|
set -ex
|
||||||
./rand_check.out
|
./linux/rand_check.out
|
||||||
|
|
||||||
# Check if network is being replayed.
|
# Check if network is being replayed.
|
||||||
# https://superuser.com/questions/635020/how-to-know-current-time-from-internet-from-command-line-in-linux
|
# https://superuser.com/questions/635020/how-to-know-current-time-from-internet-from-command-line-in-linux
|
||||||
@@ -9,4 +9,4 @@ set -ex
|
|||||||
|
|
||||||
# busybox's poweroff panics, TODO why. Likely tries to kill shell.
|
# busybox's poweroff panics, TODO why. Likely tries to kill shell.
|
||||||
# So just use our super raw command.
|
# So just use our super raw command.
|
||||||
./poweroff.out
|
./linux/poweroff.out
|
||||||
|
|||||||
2
run
2
run
@@ -109,7 +109,7 @@ timestamps.
|
|||||||
Pass an extra Linux kernel command line options, and place them before
|
Pass an extra Linux kernel command line options, and place them before
|
||||||
the dash separator `-`. Only options that come before the `-`, i.e.
|
the dash separator `-`. Only options that come before the `-`, i.e.
|
||||||
"standard" options, should be passed with this option.
|
"standard" options, should be passed with this option.
|
||||||
Example: `./run --arch arm --kernel-cli 'init=/poweroff.out'`
|
Example: `./run --arch arm --kernel-cli 'init=/lkmc/poweroff.out'`
|
||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
|
|||||||
14
userland/arch/x86_64/c/rdtsc.c
Normal file
14
userland/arch/x86_64/c/rdtsc.c
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/* https://github.com/cirosantilli/linux-kernel-module-cheat#rdtsc */
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <x86intrin.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
uintmax_t val;
|
||||||
|
val = __rdtsc();
|
||||||
|
printf("%ju\n", val);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
12
userland/arch/x86_64/c/ring0.c
Normal file
12
userland/arch/x86_64/c/ring0.c
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/* https://github.com/cirosantilli/linux-kernel-module-cheat#ring0 */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <include/ring0.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
LkmcRing0Regs ring0_regs;
|
||||||
|
lkmc_ring0_get_control_regs(&ring0_regs);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
3
userland/libs/README.adoc
Normal file
3
userland/libs/README.adoc
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Examples in this directory rely on non-libc libraries.
|
||||||
|
|
||||||
|
Each example is prefixed by an identifier of the library it depends on.
|
||||||
1
userland/libs/build
Symbolic link
1
userland/libs/build
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../build
|
||||||
@@ -7,8 +7,8 @@
|
|||||||
int main(void) {
|
int main(void) {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
fp = fopen("/dev/kmsg", "w");
|
fp = fopen("/dev/kmsg", "w");
|
||||||
fputs(__FILE__ "\n", fp);
|
fputs(__FILE__ "\n", fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
while (1)
|
while (1)
|
||||||
sleep(0xFFFFFFFF);
|
sleep(0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
@@ -13,49 +13,49 @@
|
|||||||
#define finit_module(fd, param_values, flags) syscall(__NR_finit_module, fd, param_values, flags)
|
#define finit_module(fd, param_values, flags) syscall(__NR_finit_module, fd, param_values, flags)
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
const char *params;
|
const char *params;
|
||||||
int fd, use_finit;
|
int fd, use_finit;
|
||||||
size_t image_size;
|
size_t image_size;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
void *image;
|
void *image;
|
||||||
|
|
||||||
/* CLI handling. */
|
/* CLI handling. */
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
puts("Usage ./prog mymodule.ko [args="" [use_finit=0]");
|
puts("Usage ./prog mymodule.ko [args="" [use_finit=0]");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
params = "";
|
params = "";
|
||||||
} else {
|
} else {
|
||||||
params = argv[2];
|
params = argv[2];
|
||||||
}
|
}
|
||||||
if (argc < 4) {
|
if (argc < 4) {
|
||||||
use_finit = 0;
|
use_finit = 0;
|
||||||
} else {
|
} else {
|
||||||
use_finit = (argv[3][0] != '0');
|
use_finit = (argv[3][0] != '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Action. */
|
/* Action. */
|
||||||
fd = open(argv[1], O_RDONLY);
|
fd = open(argv[1], O_RDONLY);
|
||||||
if (use_finit) {
|
if (use_finit) {
|
||||||
puts("finit");
|
puts("finit");
|
||||||
if (finit_module(fd, params, 0) != 0) {
|
if (finit_module(fd, params, 0) != 0) {
|
||||||
perror("finit_module");
|
perror("finit_module");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
} else {
|
} else {
|
||||||
puts("init");
|
puts("init");
|
||||||
fstat(fd, &st);
|
fstat(fd, &st);
|
||||||
image_size = st.st_size;
|
image_size = st.st_size;
|
||||||
image = malloc(image_size);
|
image = malloc(image_size);
|
||||||
read(fd, image, image_size);
|
read(fd, image, image_size);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (init_module(image, image_size, params) != 0) {
|
if (init_module(image, image_size, params) != 0) {
|
||||||
perror("init_module");
|
perror("init_module");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
free(image);
|
free(image);
|
||||||
}
|
}
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,13 +12,13 @@
|
|||||||
#define delete_module(name, flags) syscall(__NR_delete_module, name, flags)
|
#define delete_module(name, flags) syscall(__NR_delete_module, name, flags)
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
puts("Usage ./prog mymodule");
|
puts("Usage ./prog mymodule");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
if (delete_module(argv[1], O_NONBLOCK) != 0) {
|
if (delete_module(argv[1], O_NONBLOCK) != 0) {
|
||||||
perror("delete_module");
|
perror("delete_module");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
puts(__FILE__);
|
puts(__FILE__);
|
||||||
while (1)
|
while (1)
|
||||||
sleep(0xFFFFFFFF);
|
sleep(0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#rdtsc */
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
|
||||||
#include <x86intrin.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
uintmax_t val;
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
|
||||||
val = __rdtsc();
|
|
||||||
#else
|
|
||||||
val = 0;
|
|
||||||
#endif
|
|
||||||
printf("%ju\n", val);
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#ring0 */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "../include/ring0.h"
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
|
||||||
Ring0Regs ring0_regs;
|
|
||||||
ring0_get_control_regs(&ring0_regs);
|
|
||||||
#endif
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user