1. 程式人生 > >設計一個模組,功能是列出系統中所有核心執行緒的程式名、PID號和程序狀態。

設計一個模組,功能是列出系統中所有核心執行緒的程式名、PID號和程序狀態。

一、Linux的核心模組

核心模組是Linux核心向外部提供的一個插口,其全稱為動態可載入核心模組(Loadable Kernel Module,LKM),簡稱模組。Linux核心之所以提供模組機制,是因為它本身是一個單核心(monolithic kernel)。單核心的最大優點是效率高,因為所有的內容都整合在一起,但其缺點是可擴充套件性和可維護性相對較差,模組機制就是為了彌補這一缺陷。 

模組是具有獨立功能的程式,它可以被單獨編譯,但不能獨立執行。它在執行時被連結到核心作為核心的一部分在核心空間執行,這與執行在使用者空間的程序是不同的。模組通常由一組函式和資料結構組成,用來實現一種檔案系統、一個驅動程式或其他核心上層的功能。

總之,模組是一個為核心(從某種意義上來說,核心也是一個模組)或其他核心模組提供使用功能的程式碼塊。

1.  利用核心模組的動態裝載性的優點: 

將核心映象的尺寸保持在最小,並具有最大的靈活性;便於檢驗新的核心程式碼,而不需重新編譯核心並重新引導。 

2.  核心模組的缺點:

裝入的核心模組和其他核心部分一樣,具有相同的訪問許可權,因此,差的核心模組會導致系統崩潰;為了使核心模組訪問所有核心資源,核心必須維護符號表,並在裝入和解除安裝模組時修改這些符號表;有些模組要求利用其他模組的功能,因此,核心要維護模組之間的依賴性。核心必須能夠在解除安裝模組時通知模組,並且要釋放分配給模組的記憶體和中斷等資源;核心版本和模組版本的不相容,也可能導致系統崩潰。

 相關操作說明:

a、必需模組函式

載入函式    module_init(hello_init);  

解除安裝函式    module_exit(hello_exit);    

b、可選模組函式

MODULE_LICENSE(“*******”);    許可證申明

MODULE_AUTHOR(“********”);    作者申明

MODELE_DESCRIPTION(“***”);    模組描述

MODULE_VERSION(“V1.0”);       模組版本

MODULE_ALIAS("*********");    模組別名

c、載入核心模組

載入模組使用insmod命令:

#insmod hello.ko

解除安裝核心模組使用rmmod命令:

#rmmod hello

d、檢視載入模組是否成功

   dmesg可以看到系統的核心模組資訊。

三、與本次試驗相關的核心程式碼:

1.  程序控制塊的相關內容:

linux/sched.h檔案中:

#define TASK_RUNNING 0

#define TASK_INTERRUPTIBLE 1

#define TASK_UNINTERRUPTIBLE 2

#define __TASK_STOPPED 4

#define __TASK_TRACED 8

#define EXIT_ZOMBIE 16

#define EXIT_DEAD 32

#define TASK_DEAD 64

#define TASK_WAKEKILL 128

#define TASK_WAKING 256

#define TASK_PARKED 512

struct task_struct {

volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */

struct list_head tasks;

struct mm_struct *mm;

pid_t pid;

pid_t tgid;

struct task_struct __rcu *real_parent; /* real parent process */

struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */

char comm[TASK_COMM_LEN]; /* executable name excluding path */

}

2.  for_each_process(p)巨集:

巨集for_each_process(p)的功能是掃描整個程序連結串列

#define for_each_process(p) \ for (p = &init_task ; (p = next_task(p)) != &init_task ; )

使用方法:

struct task_struct *p;

for_each_process(p){

//p指向的程序描述符進行操作

}