設計一個模組,功能是列出系統中所有核心執行緒的程式名、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指向的程序描述符進行操作
}