采用编译内核法,在Linux中增加两个系统调用。

  • 设计目的与要求

采用编译内核法,在Linux中增加两个系统调用。

  • 设计内容
  1. 系统调用实现的功能:
    a.一个系统调用把输入的字符串保存到test.txt中;b.另一个系统调用读取test.txt中的内容。

(2)另外写一个程序进行调用。

  • 设计设备与环境

8G内存笔记本电脑,VMware Workstation Pro,VMware-workstation-full-16.1.0-17198959,Linux-5.11.1。

  • 报告正文
    1. 分析与设计思路

本题目需要更改Linux内核系统调用来实现对字符串在文件中的读和写,就需要更改或添加原有的系统调用来实现功能。要将系统调用号,系统调用函数声明和自定义的系统调用函数添加进入相应的文件中。

    1. 详细设计
  1. 首先下载并安装VMware Workstation Pro和VMware-workstation-full-16.1.0,运行虚拟机。
  2. 下载Linux内核Linux-5.11.1。
  3. 自定义系统调用函数,/usr/src/linux-5.1.11/kernel/sys.c。
  4. 添加系统调用函数申明, /usr/src/linux-5.1.1/include/linux/syscalls.h。
  5. 添加系统调用号,用 gedit 打开 /usr/src/linux-5.11.1/arch/x86/entry/syscalls/syscall_64.tbl
  6. 完成添加系统调用操作后,进行几个小时的内核编译,成功以后重启。
  7. 将.c文件编译并执行,查看txt文件内容,再用dmesg命令查看系统日志,就可以查看到文件读写的具体执行信息。
    1. 编程实现
  1. 自定义系统调用函数:

SYSCALL_DEFINE0(testread)

{

        printk("testread executing");

        struct file *filp;

        struct inode *inode;

        const char* filename="/usr/src/test.txt\0";

        //mm_segment_t fs;

        off_t fsize;

        char *buf;

        unsigned long magic;

        printk("<1>start....\n");

        filp=filp_open(filename,O_RDONLY,0);

        inode=file_inode(filp);

        magic=inode->i_sb->s_magic;

        printk("<1>file system magic:%li \n",magic);

        printk("<1>super blocksize:%li \n",inode->i_sb->s_blocksize);

        printk("<1>inode %li \n",inode->i_ino);

        fsize=inode->i_size;

        printk("<0>file size:%i \n",(int)fsize);

        buf=(char *) kmalloc(fsize+1,GFP_ATOMIC);

        printk("buf correct\n");

        //fs=get_fs();

        printk("get_fs correct\n");

        //set_fs(KERNEL_DS);

        printk("set_fs correct\n");

        

        kernel_read(filp,buf,fsize,&(filp->f_pos));

        //set_fs(fs);

        buf[fsize]='\0';

        printk("<1>The File Content is:\n");

        printk("<1>%s\n",buf);

        filp_close(filp,NULL);

        printk("testread end\n");

        return 0;

}

SYSCALL_DEFINE2(testwrite,int,count,char __user *,string)

{

        printk("testwrite executing");

        struct file *filp;

        char* filename="/usr/src/test.txt\0";

        //mm_segment_t fs;

        filp = filp_open(filename, O_RDWR|O_TRUNC, 0755);

        if(IS_ERR(filp))

        {

                printk("open error...\n");

                //return;

        }

        //fs=get_fs();

        //set_fs(KERNEL_DS);

        printk("writing\n");

        char* buf;

        buf = (char *)kmalloc(sizeof(char) * count, GFP_KERNEL);

        if(!copy_from_user(buf, string, count))

        {

                printk("input is %s \n", buf);

        }

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

        //set_fs(fs);

        filp_close(filp,NULL);

        printk("testwrite end\n");

        return 0;

}

  1. 添加系统调用函数申明:

asmlinkage long sys_testread(void);

asmlinkage long sys_testwrite(int count,char __user* string);

  1. 添加系统调用号:

442     common  testread               sys_testread

443     common  testwrite              sys_testwrite

  1. .c文件:

#include<unistd.h>

#include<stdio.h>

#include<string.h>

#include<sys/syscall.h>

#include<linux/kernel.h>

int main()

{

long int a;

printf("this is testwr execution\n");

char string[120];

scanf("%s",string);

int length=strlen(string)+1;

a = syscall(443,length,string);

printf("a=%li\n",a);

printf("testwr end\n");

printf("this is testwr execution\n");

         a = syscall(442);

         printf("a=%li\n",a);

         printf("testwr end\n");

         return 0;

}

    1. 测试结果与分析

(1)执行.c文件,并且输入字符串:

 

  1. 执行dmesg命令:

 

可看出文件读写系统调用执行的详细信息。

  1. 查看test.txt文件内容:

 

程序执行正确。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值