学号末三位:168
下载并编译Linux5.0
1 xz -d linux-5.0.1.tar.xz2
3 tar -xvf linux-5.0.1.tar
4
5 cd linux-5.0.1
View Code
下载完成之后,依次执行:make menuconfig,sudo apt-get install libncurses5-dev libncursesw5-dev,make menuconfig
接着,制作跟系统文件:
1 cd ..2 mkdirrootfs3 git clone https://github.com/mengning/menu.git
4 cd menu5 sudo apt install gcc-multilib6 gcc -pthread -o init linktable.c menu.c test.c -m32 -static7 cd ../rootfs8 cp ../menu/init ./
9 find . | cpio -o -Hnewc | gzip -9 > ../rootfs.img
然后启动menuOS:qemu-system-i386 -kernel bzImage -initrd rootfs.img
一、系统调用
操作系统的主要功能是为管理硬件资源和为应用程序开发人员提供良好的环境来使应用程序具有更好的兼容性,为了达到这个目的,内核提供一系列具备预定功能的多内核函数,通过一组称为系统调用(system call)的接口呈现给用户。系统调用把应用程序的请求传给内核,调用相应的的内核函数完成所需的处理,将处理结果返回给应用程序。
二、系统调用原理
操作系统中的状态分为管态(核心态)和目态(用户态)。特权指令:一类只能在核心态下运行而不能在用户态下运行的特殊指令。不同的操作系统特权指令会有所差异,但是一般来说主要是和硬件相关的一些指令。访管指令:本身是一条特殊的指令,但不是特权指令。(trap指令)。基本功能:“自愿进管”,能引起访管异常。
三、系统调用和普通调用的区别
运行状态不同。系统调用的调用过程和被调用过程运行在不同的状态,而普通的过程调用一般运行在相同的状态。
调用方法不同。系统调用必须通过软中断机制首先进入系统核心,然后才能转向相应的命令处理程序。普通过程调用可以直接由调用过程转向被调用过程。
实验过程描述
首先,从github上更新这次实验要用的新的menuOS镜像。然后我们开始制作根文件系统。
之后系统就成功启动了,我们就会开到熟悉的界面。如果是要跟踪调试系统的话我们可以用这个命令:
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
同样的我们再打开一个窗口然后进入gdb调试模式,然后我们首先是要加载它的符号表,命令是 file linux3.18.6/vmlinux 然后在连接到他,命令是:target remote:1234这样我们就可以开始调试他了。
然后我们添加了一个断点在sys_sgetmask(系统调用号为68)上,然后按c继续执行到,系统停在了相应的位置上。
tips:syst_sgetmark返回当前进程受阻塞的情况,current是一个的类型是struct task_struct*的全局变量,总是指向当前正在执行的进程。
1 int sys_sgetmask()//获取当前进程阻塞的信号
2 {3 returncurrent->blocked;4 }
qemu中输出的内容:
测试程序:
1 #include
2 #include
3 #include
4 #include
5
6 int main(void)7{8 long pid = 0;9 pid = syscall(68);10 printf("%ld\n",pid);11 return 0;12 }
View Code
总结:
我们知道操作系统为在用户态运行的进程与硬件设备进行交互提供了一组几口。在应用程序与硬件之间设置一个额外的层实际上是有很多优点的——所谓的系统调用。首先这使得编程更加容易,把用户从学习硬件设备的低级编程特性中解放出来。其次,着极大的提高了系统的安全性,因为内核在试图满足某个请求之前在接口级别上就可以检查这种请求是否是正确的合法的。最后更为重要的是,这些接口是的程序更具有可以执行,因为只要内核所提供的一组接口相同,那么在任意一个内核之上就可以正确的编译和执行我们编写的程序了。
Linux系统就是通过内核发出的系统调用(system call)实现了用户态进程和硬件设备之间的大部分接口。