编写一个内核模块,模块接收用户传递的一个参数n(n为指定要打印的进程控制块的数量);若用户不指定n或是n<0,模块则打印进程控制块的信息(例如可以打印进程PID、进程的可执行文件名等)。
时间: 2023-06-19 17:08:05 浏览: 74
下面是一个简单的内核模块,它可以接收用户传递的参数n,如果n大于0,则打印前n个进程控制块的信息,否则打印所有进程控制块的信息:
```c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/slab.h>
static int n = -1;
module_param(n, int, S_IRUGO);
static int __init pinfo_init(void)
{
struct task_struct *task;
int i = 0;
if(n < 0)
{
printk(KERN_INFO "Printing all process information\n");
}
else
{
printk(KERN_INFO "Printing first %d process information\n", n);
}
for_each_process(task)
{
if(n < 0 || i < n)
{
printk(KERN_INFO "PID: %d, Command: %s\n", task->pid, task->comm);
}
i++;
}
return 0;
}
static void __exit pinfo_exit(void)
{
printk(KERN_INFO "Process information module exit.\n");
}
module_init(pinfo_init);
module_exit(pinfo_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your name");
MODULE_DESCRIPTION("Process information module");
```
在这个模块中,我们使用了`module_param`宏来定义了一个名为`n`的模块参数。我们也定义了两个函数`pinfo_init`和`pinfo_exit`分别在模块加载时和卸载时调用。在`pinfo_init`函数中,我们使用了`for_each_process`宏来遍历所有进程,然后打印进程的PID和可执行文件名。如果用户传递了n大于0的参数,则只打印前n个进程的信息。如果用户没有传递参数或是传递了n小于等于0的参数,则打印所有进程的信息。
要编译这个模块,我们可以使用以下Makefile:
```Makefile
obj-m += pinfo.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
```
在编译完成后,我们可以使用以下命令来加载模块:
```
sudo insmod pinfo.ko n=10
```
这将打印前10个进程的信息。如果我们想打印所有进程的信息,可以使用以下命令:
```
sudo insmod pinfo.ko
```
我们可以使用以下命令来卸载模块:
```
sudo rmmod pinfo
```
阅读全文