Linux-0.11操作系统实验2-系统调用

实验环境:实验楼之系统调用

本文仅记录实验操作步骤,原理省略

内核层面的修改:

  1. 修改kernel/system_call.s 文件

    nr_system_calls = 74  # 新增2个系统调用
    
  2. 修改 include/linux/sys.h 文件,进行extern声明,以及添加新的系统调用函数指针

    extern int sys_whoami();
    extern int sys_iam();
    

    如下图所示:
    在这里插入图片描述

  3. 修改添加 kernel/who.c 文件 编写实现 sys_iam函数和sys_whoami函数

    #include <string.h>
    #include <errno.h>
    #include <asm/segment.h>
    
    char msg[24]; //23个字符 +'\0' = 24
    
    int sys_iam(const char * name)
    /***
    function:将name的内容拷贝到msg,name的长度不超过23个字符
    return:拷贝的字符数。如果name的字符个数超过了23,则返回“­-1”,并置errno为EINVAL。
    ****/
    {
    	int i;
    	//临时存储 输入字符串 操作失败时不影响msg
    	char tmp[30];
    	for(i=0; i<30; i++)
    	{
    		//从用户态内存取得数据
    		tmp[i] = get_fs_byte(name+i);
    		if(tmp[i] == '\0') break;  //字符串结束
    	}
    	//printk(tmp);
    	i=0;
    	while(i<30&&tmp[i]!='\0') i++;
    	int len = i;
    	// int len = strlen(tmp);
    	//字符长度大于23个
    	if(len > 23)
    	{
    		// printk("String too long!\n");
    		return -(EINVAL);  //置errno为EINVAL  返回“­-1”  具体见_syscalln宏展开
    	}
    	strcpy(msg,tmp);
    	//printk(tmp);
    	return i;
    }
    
    int sys_whoami(char* name, unsigned int size)
    /***
    function:将msg拷贝到name指向的用户地址空间中,确保不会对name越界访存(name的大小	由size说明)
    return: 拷贝的字符数。如果size小于需要的空间,则返回“­-1”,并置errno为EINVAL。
    ****/
    { 	
    	//msg的长度大于 size
    	int len = 0;
    	for(;msg[len]!='\0';len++);
    	if(len > size)
    	{
    		return -(EINVAL);
    	}
    	int i = 0;
    	//把msg 输出至 name
    	for(i=0; i<size; i++)
    	{
    		put_fs_byte(msg[i],name+i);
    		if(msg[i] == '\0') break; //字符串结束
    	}
    	return i;
    }
    
    
  4. 修改Makefile ,将 who.c 编译进内核
    在这里插入图片描述

  5. 进入linux-0.11目录,内核重新编译,出现sync就成功了

应用层面的修改:

  1. 在ubuntu下实现iam.c和whoami.c的文件编写
    注意
    (1). 在linux0.11系统中的应用程序中,注释不能写//,必须要写/* */
    (2). 不能在中间对变量定义,比如使用循环时的i要在开始定义,所有变量都必须要在一开始统一定义。

    #include <errno.h>
    #define __LIBRARY__
    #include <unistd.h>
    #include <stdio.h>
    
    _syscall1(int, iam, const char*, name);
    
    int main(int argc,char ** argv)
    {
    	iam(argv[1]);
    	return 0;
    }
    
    #include <errno.h>
    #define __LIBRARY__
    #include <unistd.h>
    
    _syscall2(int, whoami,char*,name,unsigned int,size);
    
    int main()
    {
    	char s[30];
    	whoami(s,30);
    	printf("%s",s);
    	return 0;
    }
    
  2. 进行文件交换前,先不启动linux-0.11内核,执行挂载命令,拷贝对应文件,然后卸载

    sudo ./mount-hdc
    cp ./iam.c whoami.c ./hdc/usr/root/
    sudo umount hdc
    
  3. 启动0.11内核,就发现/usr/root/目录下有对应的文件,然后进行编译之前先修改/usr/include/unistd.h文件(可以使用0.11带的vi进行修改,也可以退出0.11系统,通过./mount-hdc挂载后在ubuntu在./hdc/usr/include/unistd.h进行修改)
    对 __NR_whoami 和 __NR_iam 两个宏进行定义

    /* 添加系统调用号 */
    #define __NR_whoami 72 
    #define __NR_iam    73
    

    编译:

    gcc -o whoami whoami.c 
    
    gcc -o ami ami.c
    
  4. 测试

    $ ./iam lizhijun
    
    $ ./whoami
    
    lizhijun 
    

参考文章:哈工大李治军老师操作系统实验-系统调用

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值