操作系统 --- shell和system call
Operating System Structure
命令行和shell — Command line and shell
- GUI: 比如双击文件夹图标打开一个文件夹
- command line: 在terminal中使用open命令打开文件夹
- command interpreter 被叫做 shell
- 有不同的shell系统: bash, zsh, csh, ksh等, 其中bash最为常用
- 系统通过command interpreter(shell) 来执行terminal中的shell command或者shell脚本
- shell也是一段程序:/bin/sh, 在系统初始化时运行
- /bin/sh的主要代码: 是一个while死循环(不段出现在屏幕上等待用户输入),通过系统调用找到命令对应的程序(后面会讲)
while(1) {
scanf("%s", cmd);
if (!fork()) {
exec(cmd);
}
else {
wait();
}
}
内核态和用户态 (Kernel mode and User mode)
- 为了防止应用程序随意抓取内核中的重要信息(如root密码等), Unix将内存地址分为内核态和用户态
- 用户态的程序不能jmp到内核态的内存中, 也就是不能访问内核数据,但是内核态程序可以访问任何内存数据
- 操作系统通过段寄存器 (CS) 中的最低两位表示目前程序(指令) 是什么态 (CPL)
- 0代表内核态,3代表用户态
如何从用户态进入内核态 — Interrupt
- 在Intel x86中, 用interrupt 进入内核
- int指令将cs中的CPL改为0, 由此实现进入内核
- 这是用户程序发起的调用内核代码的唯一方式
系统调用 ---- System Call
什么是system call
- 以上是主要的操作系统service, 属于内核态程序
- kernel (内核) 提供interface实现以上的系统服务, 这些interface就是system call
- system call由c/c++或者汇编代码实现
- 用户程序通过system call对kernel服务进行操作
system call是如何被调用的
- 用户程序首先调用Library API,然后LibraryAPI再去调用真正的system call, Example: 在Unix/Linux中, 这个Library API叫做 “libc”
- Library API函数会通过 int 0x80 指令调用 interrupt table中的system_call (Interrupt函数) 进入内核态
- system_call 函数通过 system call number 在 _sys_call_table 找到对应的system call函数, 如write对应sys_write函数
- 以下是Windows和UNIX系统的一些Library API,这些api会调用真正的system call