mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-29 21:14:27 +01:00
Workqueue works! QEMU CLI mode with -n for panic
This commit is contained in:
@@ -27,6 +27,10 @@ We use `printk` a lot, and it shows on the QEMU terminal by default. If that ann
|
|||||||
|
|
||||||
See also: <https://superuser.com/questions/351387/how-to-stop-kernel-messages-from-flooding-my-console>
|
See also: <https://superuser.com/questions/351387/how-to-stop-kernel-messages-from-flooding-my-console>
|
||||||
|
|
||||||
|
When your kernel starts crashing, get the full trace with:
|
||||||
|
|
||||||
|
./run -n
|
||||||
|
|
||||||
1. [Introduction](introduction.md)
|
1. [Introduction](introduction.md)
|
||||||
1. [Build](build.md)
|
1. [Build](build.md)
|
||||||
1. [kmod](kmod.md)
|
1. [kmod](kmod.md)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Usage:
|
|||||||
|
|
||||||
Creates a separate thread. So init_module can return, but some work will still get done.
|
Creates a separate thread. So init_module can return, but some work will still get done.
|
||||||
|
|
||||||
TODO why can't call this workqueue.ko?
|
Can't call this just workqueue.c because there is already a built-in with that name:
|
||||||
https://unix.stackexchange.com/questions/364956/how-can-insmod-fail-with-kernel-module-is-already-loaded-even-is-lsmod-does-not
|
https://unix.stackexchange.com/questions/364956/how-can-insmod-fail-with-kernel-module-is-already-loaded-even-is-lsmod-does-not
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -19,14 +19,15 @@ MODULE_LICENSE("GPL");
|
|||||||
|
|
||||||
static struct workqueue_struct *queue;
|
static struct workqueue_struct *queue;
|
||||||
|
|
||||||
static void worker_func(struct work_struct *work)
|
static void work_func(struct work_struct *work)
|
||||||
{
|
{
|
||||||
printk(KERN_INFO "worker\n");
|
printk(KERN_INFO "worker\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECLARE_WORK(work, work_func);
|
||||||
|
|
||||||
int init_module(void)
|
int init_module(void)
|
||||||
{
|
{
|
||||||
DECLARE_WORK(work, worker_func);
|
|
||||||
queue = create_singlethread_workqueue("myworkqueue");
|
queue = create_singlethread_workqueue("myworkqueue");
|
||||||
queue_work(queue, &work);
|
queue_work(queue, &work);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -34,5 +35,9 @@ int init_module(void)
|
|||||||
|
|
||||||
void cleanup_module(void)
|
void cleanup_module(void)
|
||||||
{
|
{
|
||||||
|
/* TODO why is this needed? Why flush_workqueue doesn't work? (re-insmod panics)
|
||||||
|
* http://stackoverflow.com/questions/37216038/whats-the-difference-between-flush-delayed-work-and-cancel-delayed-work-sync */
|
||||||
|
/*flush_workqueue(queue);*/
|
||||||
|
cancel_work_sync(&work);
|
||||||
destroy_workqueue(queue);
|
destroy_workqueue(queue);
|
||||||
}
|
}
|
||||||
|
|||||||
9
rootfs_overlay/workqueue_cheat.sh
Executable file
9
rootfs_overlay/workqueue_cheat.sh
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Got a few kernel crashes after insert / remove, so let's do this a few times.
|
||||||
|
insmod /workqueue_cheat.ko
|
||||||
|
rmmod workqueue_cheat
|
||||||
|
insmod /workqueue_cheat.ko
|
||||||
|
rmmod workqueue_cheat
|
||||||
|
insmod /workqueue_cheat.ko
|
||||||
|
rmmod workqueue_cheat
|
||||||
22
run
22
run
@@ -1,5 +1,24 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
# CLI handling.
|
||||||
|
nographic=false
|
||||||
|
while getopts n OPT; do
|
||||||
|
case "$OPT" in
|
||||||
|
n)
|
||||||
|
nographic=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
if $nographic; then
|
||||||
|
extra_append='console=ttyS0'
|
||||||
|
extra_flags='-nographic'
|
||||||
|
else
|
||||||
|
extra_append=''
|
||||||
|
extra_flags=''
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Work.
|
||||||
cd buildroot
|
cd buildroot
|
||||||
make BR2_EXTERNAL="$(pwd)/../kernel_module" qemu_x86_64_defconfig
|
make BR2_EXTERNAL="$(pwd)/../kernel_module" qemu_x86_64_defconfig
|
||||||
echo '
|
echo '
|
||||||
@@ -11,9 +30,10 @@ BR2_ROOTFS_OVERLAY="../rootfs_overlay"
|
|||||||
env -u LD_LIBRARY_PATH make BR2_JLEVEL="$(($(nproc) - 2))" kernel_module-rebuild all
|
env -u LD_LIBRARY_PATH make BR2_JLEVEL="$(($(nproc) - 2))" kernel_module-rebuild all
|
||||||
qemu-system-x86_64 \
|
qemu-system-x86_64 \
|
||||||
-M pc \
|
-M pc \
|
||||||
-append 'root=/dev/vda' \
|
-append "root=/dev/vda $extra_append" \
|
||||||
-drive file=output/images/rootfs.ext2,if=virtio,format=raw \
|
-drive file=output/images/rootfs.ext2,if=virtio,format=raw \
|
||||||
-kernel output/images/bzImage \
|
-kernel output/images/bzImage \
|
||||||
-net nic,model=virtio \
|
-net nic,model=virtio \
|
||||||
-net user \
|
-net user \
|
||||||
|
$extra_flags \
|
||||||
;
|
;
|
||||||
|
|||||||
Reference in New Issue
Block a user