移动操作系统内核分析--Linux系统调用

    一 、实验目的

  1. 了解Linux系统调用的工作机制
  2. 掌握Linux系统调用的实现方法
  • 二、 实验内容

  1. 实现一个新的“Hello World”系统调用。
  2. 验证系统调用
    1. 创建一个用户程序来调用“Hello World”系统调用:
    2. 将用户程序编译后,放入rootfs.img根文件系统中。
    3. 启动qemu虚拟机,在虚拟机中运行用户程序。成功时将能看到“Hello World!”在虚拟机终端输出
  • 三 、实验过程及结果

            一、首先在系统调用表中添加新的系统调用编号,如图所示

      二、实现系统调用程序文件路径

                                        

    三、重新编译内核

        执行make -j4命令来编译内核,由于之前涉及到makefile,所以这次编译的时间编译的时间比较短

  四、验证系统调用

   Ⅰ、这一部分的话,在一个文件夹里面添加一个hello.c文件,内容如图所示

                            

                  

Ⅲ、将第二步骤编写出的a.out文件move到根文件系统中,在这之前要把之前的根文件系统重新挂载起来,等到move到根文件系统后再取消挂载。

Ⅳ、启动qemu虚拟机,在虚拟机中运行用户程序

   1)在这一步的时候可能会出现login的问题,只要把之前根文件系统的/etc/inittab里面变成::respawn:-/bin/sh ,即可解决有login的问题

   2)启动qemu虚拟机,在虚拟机中运行用户程序

                         

思考题:

                   

                  为了向用户空间写入数据,内核提供了copy_to_user(),他需要三个参数,第一个参数是进程空间中的目的内存地                  址,第二个是内核空间内的源地址,第三个参数是需要拷贝的数据的长度(字节数)。

 

        为了从用户空间读取数据,内核提供了copy_from_user(),他和copy_to_user()相似,该函数把第二个参数指定位置上      的数据拷贝到第一个参数指定的位置上,拷贝的数据的长度由第三个参数指定。

        如果执行失败,这两个函数返回的都是没能完成拷贝的数据的字节数。如果成功,则返回0。当出现上述错误的时候,系统调用返回标准-EFAULT。

          copy_to_user()和copy_from_user()函数都有可能引起阻塞。如果用户空间的数据地址是个非法的地址,或是超出用户  空间的范围,当包含用户数据的页被换出到硬盘上而不是在物理内存上的时候,这种情况就会发生进程就会休眠,知道缺页处理程序将该页从硬盘换回到物理内存。或是那些地址还没有被映射到,都可能对内核产生很大的影响。

                 如果成功则调用__copy_from_user函数开始拷贝数据了,如果失败的话,就把从to指针指向的内核空间地址到to+size        范围填充   

    这里先判断要拷贝的字节大小,如果是8,16,32大小的话,则调用__get_user_size来拷贝数据.

 

  • 四、总结

         系统调用有open,read ,write等。一般的话,使用SYSCALL_DEFINEx来定义系统调用,但是本质上还是sys_xxx的模式。系统调用在用户态,最终都会调用到同样的一组接口,从_syscall0到_syscall6。这一组接口基本都是类似的,只不过向内核传递的参数个数不一样。_syscall后面的数字就代表传递参数的个数。可以看到只有_syscall6多了栈操作,是因为系统调用前5个参数是通过%ebx, %ecx, %edx, %esi, %edi,五个寄存器传递的,超过五个参数,就只能通过栈来传递参数了,实验做完之后了解了linux系统的调用过程,以及用户空间写入数据和读出数据的过程。

发布了12 篇原创文章 · 获赞 2 · 访问量 1559

猜你喜欢

转载自blog.csdn.net/hongweisong666/article/details/102769541