Linux kernel module programming (lists the program name, PID number, process status and process priority of all kernel threads in the system, and the PID of the parent process)

(1) Design a module to list the program name, PID number, process status and process priority of all kernel threads in the system, and the PID of the parent process.

1. First, we start to write the module code, which is the core code of Linux kernel programming, the code is as follows:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init_task.h>
// 初始化函数
static int hello_init(void)
{
    struct task_struct *p;
    p = NULL;
    p = &init_task;
    printk(KERN_ALERT"名称\t进程号\t状态\t优先级\t父进程号\t");
    for_each_process(p)
    {
        if(p->mm == NULL){ //内核线程的mm成员为空
            printk(KERN_ALERT"%s\t%d\t%ld\t%d\n",p->comm,p->pid, p->state,p->normal_prio,p->parent->pid);
        }
    }
    return 0;
}
// 清理函数
static void hello_exit(void)
{
    printk(KERN_ALERT"goodbye!\n");
}

// 函数注册
module_init(hello_init);  
module_exit(hello_exit);  

// 模块许可申明
MODULE_LICENSE("GPL");

2. The declaration of the header file, module.h contains the definitions of a large number of functions and symbols needed to load the module; init.h contains the definitions of the module initialization and cleanup functions. Modules should also include the moduleparam.h header file if the module is loaded to allow users to pass parameters.

3. Next, we need to initialize the function. The task_struct structure is defined in /usr/src/linux4.4.19/include/linux/sched.h, so we also need to add this library to the header file, and this structure also contains what we need to use The value like PID can be called directly. Of course, these two articles can better understand this structure:

https://blog.csdn.net/npy_lp/article/details/7292563

https://blog.csdn.net/npy_lp/article/details/7335187

Next, we need to initialize the pointer to the structure p we defined, otherwise the pointer will be generated and the file will report an error. Therefore, we need to use init_task and add the init_task.h library to the header file.

4. Then, we use for_each_process to traverse each of our processes and output the process information we need to get.

5. Finally, the function registration has the module permission statement, which must be added.

6. Compile Makefile

obj-m:=module1.o    
KDIR:= /lib/modules/$(shell uname -r)/build
PWD:= $(shell pwd) 

default:
    $(MAKE) -C $(KDIR) M=$(PWD) modules  
clean:
    $(MAKE) -C $(KDIR) M=$(PWD) clean

7. Use insmod to add modules after make

8.dmesg shows usage, mine is as shown.

VirtualBox_Ubuntu_21_04_2018_10_16_25

(2) Design a module with parameters, whose parameter is the PID number of a certain process. The function of this module is to list the family information of the process, including the program name and PID number of the parent process, sibling process and child process.

1. My code is as follows:

#include<linux/init.h>
#include<linux/module.h>
#include<linux/kernel.h>
#include <linux/sched.h>
#include <linux/moduleparam.h>

static pid_t pid=1;
module_param(pid,int,0644);

static int hello_init(void)
{
    struct task_struct *p;
    struct list_head *pp;
    struct task_struct *psibling;

    // 当前进程的 PID
    p = pid_task(find_vpid(pid), PIDTYPE_PID);
    printk("me: %d %s\n", p->pid, p->comm);

    // 父进程
    if(p->parent == NULL) {
        printk("No Parent\n");
    }
    else {
        printk("Parent: %d %s\n", p->parent->pid, p->parent->comm);
    }

    // 兄弟进程
    list_for_each(pp, &p->parent->children)
    {
        psibling = list_entry(pp, struct task_struct, sibling);
        printk("sibling %d %s \n", psibling->pid, psibling->comm);
    }

    // 子进程
    list_for_each(pp, &p->children)
    {
        psibling = list_entry(pp, struct task_struct, sibling);
        printk("children %d %s \n", psibling->pid, psibling->comm);
    }

    return 0;
}

static void hello_exit(void)
{
    printk(KERN_ALERT"goodbye!\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");

2. View the parent process of the current process

if(p->parent == NULL) {
    printk("No Parent\n");
}
else {
    printk("Parent: %d %s\n", p->parent->pid, p->parent->comm);
}

3. Find the sibling process of the current process

list_for_each(pp, &p->parent->children)
{
     psibling = list_entry(pp, struct task_struct, sibling);
     printk("sibling %d %s \n", psibling->pid, psibling->comm);
}

4. Find the child process of the current process

list_for_each(pp, &p->children)
{
    psibling = list_entry(pp, struct task_struct, sibling);
    printk("children %d %s \n", psibling->pid, psibling->comm);
}

5. The next process is basically the same as the first experiment. The following picture is my result:

VirtualBox_Ubuntu_21_04_2018_10_24_17

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324661700&siteId=291194637
Recommended