杭电(杭州电子科技大学)操作系统实验二:Linux内核模块编程

实验内容

(1)设计一个模块,要求列出系统中所有内核线程的程序名、PID、进程状态、进程优先级、父进程的PID。
(2)设计一个带参数的模块,其参数为某个进程的PID号,模块的功能是列出该进程的家族信息,包括父进程、兄弟进程和子进程的程序名、PID号及进程状态。

实验一

前排提醒
可能问到的问题:
①输出的进程号是什么含义(1和1026分别代表什么状态)?
调研task_struct结构体
看↑这篇文章就够了,1026表示1024+2,其中1024是系统无可运行进程的状态
②优先级的含义(为什么输出100和120,分别是什么含义)?
进程优先级
看↑这篇文章就够了,0-99是实时进程,100-139是普通进程
③p->mm的含义
对于内核线程,mm为NULL;对于普通线程,mm为指向虚拟地址空间的用户空间

module1.c

#include 
#include 
#include 
#include 
#include 

// 初始化函数
static int hello_init(void)
{
    struct task_struct *p;  //Linux内核的进程控制块是task_struct结构体,所有运行在系统中的进程都以task_struct链表的形式存在内核中
    printk(KERN_ALERT"            名称\t进程号\t状态  \t优先级\t父进程号\t");
    for_each_process(p)  //for_each_process是一个宏,在sched.h里面定义: 是从init_task开始遍历系统所有进程,init_task是进程结构链表头。
    {
        if(p->mm == NULL){ //对于内核线程,mm为NULL
            printk(KERN_ALERT"%16s\t%-6d\t%-6ld\t%-6d\t%-6d\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");  

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

实验二

前排提醒
可能问到的问题:
①list for each:看书p343就行
②list entry :看书p343就行
③if(sibling_p->pid != current_p->pid)为什么要用这句:因为它自己不是自己的兄弟进程

module2.c

#include
#include
#include
#include
#include 

static pid_t pid=1;

module_param(pid,int,0644);

static int test2_init(void) {

    struct task_struct *current_p;
    struct task_struct *parent_p;
    struct task_struct *sibling_p;
    struct task_struct *children_p;

    struct list_head *sibling_head;
    struct list_head *children_head;

    current_p = pid_task(find_vpid(pid), PIDTYPE_PID);
    
    parent_p = current_p->parent;
    
    printk("current:%-21s%-10d%-10ld\n", current_p->comm, current_p->pid, current_p->state);

    if(parent_p == NULL) {
        printk("No Parent!\n");
    }
    else {     
        printk("Parent:%-22s%-10d%-10ld\n", parent_p->comm, parent_p->pid, parent_p->state);
    }
    
    list_for_each(sibling_head, &parent_p->children) {
        sibling_p = list_entry(sibling_head, struct task_struct, sibling);
	if(sibling_p->pid != current_p->pid) {
            printk("Sibling:%-20s%-10d%-10ld\n", sibling_p->comm, sibling_p->pid, sibling_p->state);
	}
    }
    list_for_each(children_head, ¤t_p->children) {
        children_p = list_entry(children_head, struct task_struct, sibling);
        printk("Children:%-20s%-10d%-10ld\n", children_p->comm, children_p->pid, children_p->state);
    }


    return 0;
}

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

module_init(test2_init);
module_exit(test2_exit);

MODULE_LICENSE("GPL");

Makefile

obj-m:=module2.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

你可能感兴趣的:(杭电,操作系统,linux)