栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

【Linux系列】添加系统调用

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Linux系列】添加系统调用

【Linux系列】添加系统调用最新教程

编译环境修改任务

基础任务进阶任务 修改准备修改源码

添加系统调用号修改系统调用头文件修改系统调用函数定义 编译安装内核编写主程序进阶任务总结

编译环境

虚拟机操作系统: ubuntu-20.04.3-desktop-amd64原系统内核版本:5.11.0-46-generic内核源码版本:5.11.1 修改任务 基础任务

采用内核编译法增加两个系统调用一个系统调用把用户输入的字符串保存到 text.txt 中一个系统调用把 text.txt 中的字符串读出写个主程序调用两个系统调用 进阶任务

用户可以指定用户输入字符串保存的位置和文件名程序可以将系统调用读取出的字符串打印到用户终端 修改准备

下载内核源码掌握内核编译 修改源码

所需修改的文件(路径默认从源码目录开始)如下:

arch/x86/entry/syscalls/syscall_64.tbl      //设置系统调用号,如果是32位就用syscall_32.tbl

include/linux/syscalls.h                     //系统调用的头文件

kernel/sys.c                                 //定义系统调用函数

添加系统调用号

使用 gedit 打开 syscall_64.tbl 文件

sudo gedit arch/x86/entry/syscalls/syscall_64.tbl

根据规则在后面添加自己的系统调用号和系统调用名,如下图所示

这里我添加了两个系统调用分别是读和写 修改系统调用头文件

使用 gedit 打开 syscalls.h 文件

sudo gedit include/linux/syscalls.h 

添加对应系统调用的函数声明,如下图

asmlinkage long sys_fwrite(int strcount,char __user* string);
asmlinkage long sys_fread(void);

修改系统调用函数定义

使用 gedit 打开 sys.c 文件

sudo gedit kernel/sys.c

添加对应系统调用的函数定义,内容如下:

//写文件系统调用
SYSCALL_DEFINE2(fwrite,int,strcount,char __user *,string)
{
        printk("fwrite executing");
        struct file *filp;
        char* filename="/usr/src/text.txt";


        printk("open file");

        filp = filp_open(filename, O_RDWR|O_TRUNC, 0755);
        if(IS_ERR(filp))
        {
                printk("open error...n");
                return -1;
        }

        printk("writingn");
        char* buf;
        buf = (char *)kmalloc(sizeof(char) * strcount, GFP_KERNEL);
        if(!copy_from_user(buf, string, strcount))
        {
                printk("input is %s n", buf);
        }

        kernel_write(filp, buf, strlen(buf),&filp->f_pos);

        filp_close(filp,NULL);
        printk("fwrite endn");
        return 0;

}
// 读文件系统调用
SYSCALL_DEFINE0(fread)
{
        printk("fread executing");
        struct file *filp;
        struct inode *inode;
        const char* filename="/usr/src/text.txt";
        off_t fsize;
        char *buf;
        unsigned long magic;
        
        
        printk("start....n");
        filp=filp_open(filename,O_RDONLY,0);
        inode=file_inode(filp);

        magic=inode->i_sb->s_magic;

        printk("file system magic:%li n",magic);
        printk("super blocksize:%li n",inode->i_sb->s_blocksize);
        printk("inode %li n",inode->i_ino);

        fsize=inode->i_size;
        printk("file size:%i n",(int)fsize);
        buf=(char *) kmalloc(fsize+1,GFP_ATOMIC);
        printk("buf correctn");


        kernel_read(filp,buf,fsize,&(filp->f_pos));
        buf[fsize]='';
        printk("The File Content is:n");
        printk("%sn",buf);


        filp_close(filp,NULL);
        printk("fread endn");
        return 0;
}

将两个函数定义写在 sys.c 文件的尾部
其中 SYSCALL_DEFINE 为系统定义,之后的数字代表系统调用参数的个数,其中第一个参数为系统调用函数的名称,需要与调用号定义(调用号定义第三个参),声明(sys_xxx中xxx部分)一致。注意系统调用定义时的参数书写格式。 编译安装内核

#编译内核
sudo make -j4

#安装内核模块
sudo make modules_install

#安装内核
sudo make install

#重启
reboot
编写主程序

在指定目录下新建文件 text.txt

sudo touch /usr/src/text.txt

新建 readAndWrite.c 文件,内容如下

#include
#include
#include
#include
#include
int main()
{
	long int a;
		
	printf("this is testwr executionn");
	

	char string[120];
	scanf("%s",string);
	int length=strlen(string)+1;
	

	a = syscall(442,length,string);
	
	printf("a=%lin",a);

	printf("testwr endn");
	
	printf("this is testwr executionn");

 	a = syscall(443);

	printf("a=%lin",a);

	printf("testwr endn");
	return 0;
	
}

编译

gcc readAndWrite.c -o readAndWrite.o

执行

sudo ./readAndWrite.o

执行结果,如下图

至此基础任务完成,接下来完成进阶任务

进阶任务

重新添加新的系统调用

添加系统调用号

添加系统调用函数声明

asmlinkage long sys_fsize(int pathcount,char __user * path);
asmlinkage long sys_fwrite_advance(int strcount,char __user * string,int pathcount,char __user * path);
asmlinkage long sys_fread_advance(char __user * res,int pathcount,char __user * path);

添加系统调用函数定义

//获取文件大小系统调用
SYSCALL_DEFINE2(fsize,int,pathcount,char __user *,path)
{
        printk("fsize executing");
        struct file *filp;
        struct inode *inode;

        off_t fsize;
        unsigned long magic;
        
        char* pathbuf;
        pathbuf = (char *)kmalloc(sizeof(char) * pathcount, GFP_KERNEL);
        if(!copy_from_user(pathbuf, path, pathcount))
        {
                printk("input path is %s n", pathbuf);
        }
        
        printk("start....n");
        filp=filp_open(pathbuf,O_RDONLY,0);
        inode=file_inode(filp);

        magic=inode->i_sb->s_magic;

        printk("file system magic:%li n",magic);
        printk("super blocksize:%li n",inode->i_sb->s_blocksize);
        printk("inode %li n",inode->i_ino);

        fsize=inode->i_size;
        printk("file size:%i n",(int)fsize);

        filp_close(filp,NULL);
        printk("fsize endn");
        return fsize+1;
}
//写文件系统调用
SYSCALL_DEFINE4(fwrite_advance,int,strcount,char __user *,string,int,pathcount,char __user *,path)
{
        printk("fwrite_advance executing");
        struct file *filp;

        
        char* pathbuf;
        pathbuf = (char *)kmalloc(sizeof(char) * pathcount, GFP_KERNEL);
        if(!copy_from_user(pathbuf, path, pathcount))
        {
                printk("input path is %s n", pathbuf);
        }
        
        printk("%s",pathbuf);
        printk("open file");

        filp = filp_open(pathbuf, O_RDWR|O_TRUNC, 0755);
        if(IS_ERR(filp))
        {
                printk("open error...n");
                return -1;
        }

        printk("writingn");
        char* buf;
        buf = (char *)kmalloc(sizeof(char) * strcount, GFP_KERNEL);
        if(!copy_from_user(buf, string, strcount))
        {
                printk("input is %s n", buf);
        }

        kernel_write(filp, buf, strlen(buf),&filp->f_pos);
        filp_close(filp,NULL);
        printk("fwrite_advance endn");
        return 0;

}
//读文件系统调用
SYSCALL_DEFINE3(fread_advance,char __user *,res,int,pathcount,char __user *,path)
{
        printk("fread_advance executing");
        struct file *filp;
        struct inode *inode;

        off_t fsize;
        char *buf;
        unsigned long magic;
        
        char* pathbuf;
        pathbuf = (char *)kmalloc(sizeof(char) * pathcount, GFP_KERNEL);
        if(!copy_from_user(pathbuf, path, pathcount))
        {
                printk("input path is %s n", pathbuf);
        }
        
        printk("start....n");
        filp=filp_open(pathbuf,O_RDONLY,0);
        inode=file_inode(filp);

        magic=inode->i_sb->s_magic;

        printk("file system magic:%li n",magic);
        printk("super blocksize:%li n",inode->i_sb->s_blocksize);
        printk("inode %li n",inode->i_ino);

        fsize=inode->i_size;
        printk("file size:%i n",(int)fsize);
        buf=(char *) kmalloc(fsize+1,GFP_ATOMIC);
        printk("buf correctn");




        kernel_read(filp,buf,fsize,&(filp->f_pos));
        buf[fsize]='';
        printk("The File Content is:n");
        printk("%sn",buf);

	if(!copy_to_user(res, buf, fsize+1))
        {
                printk("output success");
        }
        filp_close(filp,NULL);
        printk("fread_advance endn");
        return 0;
}

编译安装内核修改主程序

#include
#include 
#include
#include
#include
#include
int main()
{
	long int a;
		
	printf("this is testwr executionn");
	
	char *res;
	char string[120];
	char path[120];
	scanf("%s",string);
	scanf("%s",path);
	int length=strlen(string)+1;
	int plength=strlen(path)+1;
	

	a = syscall(444,length,string,plength,path);
	
	printf("a=%lin",a);

	printf("testwr endn");
	
	printf("this is testwr executionn");
	a = syscall(446,plength,path);
	printf("a=%lin",a);

	res = malloc(sizeof(char)*a);
 	a = syscall(445,res,plength,path);
 	
 	printf("%sn",res);

	printf("a=%lin",a);

	printf("testwr endn");
	return 0;
	
}

在所需目录下新建所需文件编译运行,结果如下

总结

增加系统调用主要是修改三个文件,分别添加系统调用号、系统调用函数声明和系统调用函数定义增加文件读写系统调用的核心函数是:filp_open、filp_close、kernel_read、kernel_write、copy_from_user、copy_to_user关于文件读写和系统调用传参最大且最容易出现的问题往往是字符指针和字符数组的问题

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/706152.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号