title:Create threads keywords:kernel,linux,threads # Create threads ## Starting point __Makefile__ ```Makefile obj-m += create_thread.o KDIR ?= /lib/modules/$(shell uname -r)/build all: make -C $(KDIR) M=$(PWD) modules clean: make -C $(KDIR) M=$(PWD) clean ``` __create_thread.c__ ```c #include /* Needed by all modules */ #include int create_thread_init( void ) { printk(KERN_DEBUG "Hello Thread!\n"); return 0; } void create_thread_exit( void ) { printk(KERN_DEBUG "Exit Thread!\n"); } module_init( create_thread_init ); module_exit( create_thread_exit ); MODULE_LICENSE("GPL"); ``` ## Create empty thread Lets create kernel thread that will start and exit straight away ```c #include static struct task_struct *task; static int run_task(void *data) { int i=0; while(!kthread_should_stop()) { pr_info("run task%d\n", i++); msleep(1000); } return 0; } int create_thread_init( void ) { ... task = kthread_create(run_task, NULL, "special task"); if(task) { wake_up_process(task); } else { printk(KERN_ERR "Cannot create kthread\n"); } ... } ``` ## Kernel threads states State of kernel thread - include/linux/sched.h ```c /* Used in tsk->state: */ #define TASK_RUNNING 0x00000000 #define TASK_INTERRUPTIBLE 0x00000001 #define TASK_UNINTERRUPTIBLE 0x00000002 #define __TASK_STOPPED 0x00000004 #define __TASK_TRACED 0x00000008 /* Used in tsk->exit_state: */ #define EXIT_DEAD 0x00000010 #define EXIT_ZOMBIE 0x00000020 #define EXIT_TRACE (EXIT_ZOMBIE | EXIT_DEAD) /* Used in tsk->state again: */ #define TASK_PARKED 0x00000040 #define TASK_DEAD 0x00000080 #define TASK_WAKEKILL 0x00000100 #define TASK_WAKING 0x00000200 #define TASK_NOLOAD 0x00000400 #define TASK_NEW 0x00000800 #define TASK_RTLOCK_WAIT 0x00001000 #define TASK_FREEZABLE 0x00002000 #define __TASK_FREEZABLE_UNSAFE (0x00004000 * IS_ENABLED(CONFIG_LOCKDEP)) #define TASK_FROZEN 0x00008000 #define TASK_STATE_MAX 0x00010000 #define TASK_ANY (TASK_STATE_MAX-1) ``` ## List of kernel thread functions used | Function name | Note | |---|---| | | | | wake_up_proces | | | kthread_create | | ## Final result __create_thread.c__ ```c #include /* Needed by all modules */ #include #include #include #include #include #include #include static struct task_struct *task; static int run_task(void *data) { int i=0; while(!kthread_should_stop()) { pr_info("run task %d\n", i++); msleep(1000); } return 0; } int create_thread_init( void ) { printk(KERN_DEBUG "Hello Thread!\n"); task = kthread_create(run_task, NULL, "special task"); if(task) { wake_up_process(task); } else { printk(KERN_ERR "Cannot create kthread\n"); } return 0; } void create_thread_exit( void ) { printk(KERN_DEBUG "Exit Thread!\n"); } module_init( create_thread_init ); module_exit( create_thread_exit ); MODULE_LICENSE("GPL"); ``` ## Links https://www.linuxtoday.com/blog/kernel-threads/ http://www.embeddedlinux.org.cn/EssentialLinuxDeviceDrivers/final/ch03lev1sec1.html https://embetronicx.com/tutorials/linux/device-drivers/linux-device-drivers-tutorial-kernel-thread https://elixir.bootlin.com/linux/v6.1.21/source/include/linux/sched.h https://elixir.bootlin.com/linux/v6.1.21/source/kernel/sysctl.c https://girishjoshi.io/post/creating-linux-kernel-threads/ https://tuxthink.blogspot.com/2011/02/kernel-thread-creation-1.html https://elixir.bootlin.com/linux/v6.1.21/source/include/linux/kthread.h#L27