实验目标:
1、将带有参数的新系统调用添加到linux内核中
2、新的系统调用将把所有进程信息返回到用户模式
注意:
看此内容,需要先提前了解并熟悉Linux内核添加新的系统调用教程。因为此内容是接着上篇来讲解的。如果你不先去了解上篇内容,此篇你是看不懂的。
由于不是在本人电脑上,我就用朋友的电脑来简单的讲解一下。下面我就直接开始了,讲重点了。基础的东西上篇已经讲过了。
下面就开始讲 如何“在Linux内核添加新的系统调用来列出所有进程”教程。
1、修改 linux-5.14.14 中 include/linux/syscalls.h 文件,添加新系统调用的定义函数:
asmlinkage long sys_alcall(int cmd, char* buf);
2、修改 linux-5.14.14 中 kernel/sys.c 文件。添加如下参考代码框架,可自行更改。
SYSCALL_DEFINE1(alcall,int,cmd,char*,buf)
{
struct task_struct *p;
printk("Hello new system call alcall (%d,%x)!\n",cmd,buf);
print("%-20s %-6s %-6s\n","Name","Pid","Stat");
for (p = &init_task; (p = next_task(p)) != &init_task;)
printk("%-20s %-6d %-6ld\n",p->comm,p->pid,p->state);
return 0;
}
3、修改 linux-5.14.14 中 arch/x86/entry/syscalls/syscall_64.tbl 文件,添加类似如下:
449 common alcall __x64_sys_alcall
4、重新配置并编译内核,执行命令如下:
这里我就不重新配置了,用默认的就可以了,我就直接进入编译安装内核了吧!
make clean
make -j5
sudo make modules_install
sudo make install
5、用新内核重新启动,在用户模式下编写一个测试程序并运行,如下:
listprocess_test.c
#include<stdio.h>
#include<stdlib.h>
#include<dirent.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
int main(int argc, char* argv[]){
pid_t pid;
char * sourceDir, * destDir;
DIR * dir;
struct dirent * ptr;
int processCnt = 0;
if(argc != 3){
fprintf(stderr, "Wrong arguments");
exit(-1);
} else {
sourceDir = argv[1];
destDir = argv[2];
}
if(NULL == opendir(destDir)){ // make parent directory
mkdir(destDir, 0777);
}
dir = opendir(sourceDir); //open dir
while((ptr = readdir(dir)) != NULL){ // read dir entry
/*printf("pid: %d d_name : %s", pid, ptr->d_name);
if(ptr->d_type == DT_DIR){
printf("\tDir");
}
printf("\n");
*/
if(strcmp(ptr->d_name,".") == 0 || strcmp(ptr->d_name,"..") == 0){
continue;
}
pid = fork(); // fork child process
if(pid < 0) { // error occured
fprintf(stderr, "In parent process: fork failed");
exit(-1);
} else if(pid == 0){ // child process to copy one directory or file
char fromDir[256], toDir[256];
strcpy(fromDir, sourceDir);
strcpy(toDir, destDir);
strcat(strcat(fromDir,"/\0"), ptr->d_name);
strcat(strcat(toDir,"/\0"), ptr->d_name);
execlp("/bin/cp", "cp", "-r", "-p", fromDir, toDir, NULL);
}
processCnt++;
}
while(processCnt--){ // parent will wait for the child to complete
// printf("In parent: Waiting the child %d\n", processCnt);
wait(NULL);
}
closedir(dir); //close dir
exit(0);
}
总结:
此篇文章按理说去年就应该发表的,结果没想到定时发布失败了,一直也没有去看,现在才正式发表。不过也没有什么关系,主要是来练习,熟悉一下Linux内核相关的东西。
如果此篇内容有什么不懂的,一定要仔细去看上篇文章“Linux内核添加新的系统调用教程”,那里步骤讲得会更加的详细。