微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

xv6 Shell & OS organization

Shell & OS organization

主题
内核系统调用API
参考:https://pdos.csail.mit.edu/6.828/2017/lec/l-shell.txt
对内核进行讲解并将homework shell进行说明

概述图

用户态如何连接内核态

应用程序 - > printf() - > write ) - > SYstem CALL  - > sys_write() - > ... 

用户级库是应用程序的私有业务

内核内部函数不能由用户调用

进程的状态,进程和线程区别是什么??

process=address space + thread(s)??

计算机系统进程由以下资源组成(或被称为拥有):

与程序关联的可执行机器码的图像。

内存(通常是虚拟内存的某个区域); 其中包括可执行代码,特定于
进程的数据(输入和输出),调用堆栈(用于跟踪活动子例程和/或其
他事件)以及用于保存在运行时产生的中间计算数据的堆。

分配给进程的资源的操作系统描述符,例如文件描述符(Unix术语)或句柄(Windows)以及数据源和接收器。

安全属性,例如进程所有者和进程的权限集(允许的操作)。

处理器状态(上下文),如寄存器内容和物理内存寻址。

进程和线程的一个简单解释

系统调用

xv6有几十个系统调用,而今天的Linux系统有几百个系统调用

让我们回顾家庭作业2(sh.c)

为什么两个execv()参数?

execv 函数原型:execv(char cmd,char argv[]);
execv()用来执行参数path 字符串所代表的文件路径,与execl()不同的地方在于execve()只需两个参数,第二个参数利用数组指针来传递给执行文件.

/* 执行/bin/ls -al /etc/passwd */
#include <unistd.h>
main()
{
    char * argv[] = {"ls","-al","/etc/passwd",(char*)};
    execv("/bin/ls",argv);
}

返回值:如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno 中.

重定向

以下是可以用来重定向的命令的完整列表:

pgm > file  pgm输出重定向文件
pgm pgm 程序从文件度它的输入
pgm >> file pgm输出添加文件
n > file    带有描述符 n 的输出重定向文件
n >> file   带有描述符 n 的输出添加文件
n >& m  合并流 n 和 流 m 的输出

标准输入从开始行的下一个标记开始。
| 从一个程序或进程获取输入,并将其发送到另一个程序或进程。
需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

管道

ls | wc -l 


如果ls产生的输出比wc消耗的更快呢?
如果ls比wc慢,该怎么办?
每个命令如何决定何时退出?
如果读者没有关闭写入结束呢?[尝试一下]
如果作者没有关闭阅读结束呢?
内核如何知道何时释放管道缓冲区?

shell如何知道管道何时完成?

例如:
ls | sort | tail -l
通过递归调用解决先后完成的层次逻辑。
parsepipe(char **ps,char *es)
{
  struct cmd *cmd;
  cmd = parseexec(ps,es);
  if(peek(ps,es,"|")){
    gettoken(ps,0,0);
    cmd = pipecmd(cmd,parsepipe(ps,es));
  }
  return cmd;
}

UNIX系统调用观察

fork / exec拆分看起来很浪费 - fork()拷贝memory而exec()丢弃。

为什么不使用 pid = forkexec(path,argv,fd0,fd1) ?
fork / exec 分割是有用的:
fork(); I/O redirection; exec()
or fork(); complex nested command; exit.
如( cmd1 ; cmd2 ) | cmd3
fork() alone: parallel processing
exec() alone: /bin/login … exec(“/bin/sh”)
fork对于小程序来说很便宜 - 在我的机器上:
fork + exec需要400微秒(2500 /秒)
fork只需要80微秒12000 /秒)

文件描述符设计:

  • FDs是一个间接的等级

    • a process’s real I/O environment is hidden in the kernel
    • preserved over fork and exec
    • separates I/O setup from use
    • imagine writefile(filename,offset,buf size)

    • FDs help make programs more general purpose: don’t need special cases for files vs console vs pipe

Philosophy:小概念上简单的调用结合起来,

  • 系统调用函数,方便程序员使用

    例如fork(),open(),dup(),exec()
    command-line design has a similar approach
    ls | wc -l

为什么必须内核支持管道 - 为什么不用shell来模拟它们,

  • 例如:

    ls> tempfile; wc -l <​​tempfile

猜测:如果用sh代替管道 执行的指令数,空间,时间都会变多。

系统调用接口简单,只是中断和字符缓冲区。为什么不用open()函数返回一个指向内核文件对象的指针?

ps:如果返回指针则能从用户层直接修改内核对象

核心的UNIX系统调用是古老的; 他们保持得好吗?

一方面来讲是非常成功的,历经多年的发展
  :设计迎合了命令行和命令行开发
    命令行用户,如命名文件,管道,
    对于开发,调试,服务器维护都很重要
但另一方面UNIX思路并不完美:
    系统调用API,程序员使用库通常不是很有价值,例如,隐藏sys调用细节的Python,
    或者在智能手机上 应用程序可能与文件&c一些UNIX抽象是不是非常有效
      而且fork()对于多GB进程是非常慢的
      FDs隐藏的细节可能是重要的,
        例如块大小的磁盘上的文件,
        例如时间和网络消息的大小,
所以有很多将来的计划工作:
  新的抽象的系统调用对于已有的系统调用

OS组织

如何实现一个系统调用接口?

为什么不是使用一个库?

即没有内核,只需在硬件上直接运行app +库即可。
灵活:应用程序可以绕过库,如果不正确的
应用程序可以直接与硬件交互
图书馆可以为一个单一目的的设备,
但如果计算机用于多个活动?

内核的关键要求:

隔离
多路复用
交互

helpful approach: abstract resources rather than raw hardware

File system,not raw disk
Processes,not raw cpu/memory
TCP,not ethernet packets
abstractions often ease isolation,multiplexing and interaction
also more convenient and portable

从隔离开始,因为这往往是最严格的要求。

隔离目标:

应用程序不能直接与硬件交互
应用程序不能损害操作系统
应用程序不能直接影响对方
应用程序只能通过操作系统界面与世界进行交互

处理器提供帮助隔离的机制

硬件提供用户模式和内核模式
有些功能只能在内核模式下执行
设备访问,处理器配置,隔离机制
*硬件禁止应用程序执行特权指令
- 而不是陷入内核模式
- 内核可以清理(例如,终止进程)
*硬件允许内核模式配置用户模式的各种约束
最关键的是:页表将用户的权限限制在自己的地址空间

内核构建在硬件隔离机制上

操作系统以内核模式运行
内核是一个大型的程序
服务:进程,文件,系统网络
低层设备,虚拟内存
所有的内核运行全硬件特权(方便)

应用程序运行在用户模式
- 内核设置每个进程隔离的地址空间
- 系统调用用户和内核模式之间切换
应用程序执行一个特殊的指令进入内核,
硬件切换到内核模式
但只在内核指定的入口点

内核里要放什么?

  • xv6遵循传统的设计:操作系​​统的所有内容都以内核模式运行

    • 一个带有文件系统,驱动程序和c的大型程序
    • 这种设计称为单核内核
    • 内核接口==系统调用接口
    • 优点:子系统可以很容易地配合
      一个文件系统和虚拟内存共享的缓存

    • 缺点:交互复杂
      会导致内核中没有隔离错误

微内核设计

- 许多操作系统服务作为普通用户程序
  在文件服务器
- 内核实现在用户空间运行服务的最小机制 
  使用内存进程间通信(IPC)
- 内核接口!=系统调用接口      
-优点:多个隔离
-缺点:可能很难获得好的性能

外核:没有抽象

apps can use hardware semi-directly,but O/S isolates
应用程序可以读/写自己的页表,但是需要O / S审核
应用程序可以读/写磁盘块,但是O / S是块的所有者是
优点:对要求苛刻的应用程序有更多的灵活性
jos将是微内核和exokernel的混合

Next Lecture:x86硬件的隔离机制和xv6如何使用他们

参考:
重定向命令
shell&系统组织
进程和线程的一个简单解释
H-W shell

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2280端口映射到公网,发现经常被暴力破解,自己写了个临时封禁ip功能的脚本,实现5分钟内同一个ip登录密码错误10次就封禁这个ip5分钟,并且进行邮件通知使用步骤openwrt为19.07.03版本,其他版本没有测试过安装bashmsmtpopkg
#!/bin/bashcommand1&command2&wait从Shell脚本并行运行多个程序–杨河老李(kviccn.github.io)
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/phpls-ls 2.编辑修改.bash_profile文件(没有.bash_profile文件的情况下回自动创建)sudovim~/.bash_profile在文件的最后输入以下信息,然后保存退出exportPATH="/Applications/MAMP/bin/php/php7.2.20/b
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如zh_CN之类的语言包,进行中文语言包装:apt-getinstalllanguage-pack-zh-hans3、安装好后我们可以进行临时修改:然后添加中文支持: locale-genzh_CN.UTF-8临时修改> export LC_ALL='zh_CN.utf8'> locale永久
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexadecimalbash2#[0~1]0[0~7]0x[0~f]or0X[0~f]perl0b[0~1]0[0~7]0x[0~f]tcl0b[0~1]0o[0~7]0x[0~f]bashdifferentbaserepresntationreference2.StringlengthLanguageStr
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全命令补全方法:yum-yinstallbash-completionsource/usr/share/bash-completion/bash_completionsource<(kubectlcompletionbash)echo"source<(kubectlcompletionbash)">>~/.bashrc 
参考这里启动jar包shell脚本修改过来的#!/bin/bash#默认应用名称defaultAppName='./gadmin'appName=''if[[$1&&$1!=0]]thenappName=$1elseappName=$defaultAppNamefiecho">>>>>>本次重启的应用:$appName<
#一个数字的行#!/bin/bashwhilereadlinedon=`echo$line|sed's/[^0-9]//g'|wc-L`if[$n-eq1]thenecho$linefidone<1.txt#日志切割归档#!/bin/bashcd/data/logslog=1.logmv_log(){[-f$1]&&mv$1$2
#文件增加内容#!/bin/bashn=0cat1.txt|whilereadlinedon=[$n+1]if[$n-eq5]thenecho$lineecho-e"#Thisisatestfile.\n#Testinsertlineintothisfile."elseecho$linefidone#备份/etc目录#
# su - oraclesu: /usr/bin/ksh: No such file or directory根据报错信息:显示无法找到文件 /usr/bin/ksh果然没有该文件,但是发现存在文件/bin/ksh,于是创建了一个软连接,可以规避问题,可以成功切换到用户下,但无法执行系统自带命令。$. .bash_profile-ksh: .: .b