xv6 Shell OS organization

2024-03-14 09:38
文章标签 shell os xv6 organization

本文主要是介绍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, es, 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

这篇关于xv6 Shell OS organization的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/807990

相关文章

jenkins 插件执行shell命令时,提示“Command not found”处理方法

首先提示找不到“Command not found,可能我们第一反应是查看目标机器是否已支持该命令,不过如果相信能找到这里来的朋友估计遇到的跟我一样,其实目标机器是没有问题的通过一些远程工具执行shell命令是可以执行。奇怪的就是通过jenkinsSSH插件无法执行,经一番折腾各种搜索发现是jenkins没有加载/etc/profile导致。 【解决办法】: 需要在jenkins调用shell脚

站长常用Shell脚本整理分享(全)

站长常用Shell脚本整理分享 站长常用Shell脚本整理分享1-10 站长常用Shell脚本整理分享11-20 站长常用Shell脚本整理分享21-30 站长常用Shell脚本整理分享31-40 站长常用Shell脚本整理分享41-50 站长常用Shell脚本整理分享51-59 长期更新

Shell脚本实现自动登录服务器

1.登录脚本 login_server.sh #!/bin/bash# ReferenceLink:https://yq.aliyun.com/articles/516347#show all host infos of serverList.txtif [[ -f ./serverList.txt ]]thenhostNum=`cat ./serverList.txt | wc -l`e

[轻笔记]ubuntu shell脚本切换conda环境

source /home/yourhostname/anaconda3/etc/profile.d/conda.sh # 关键!!!conda activate env_name

[轻笔记] ubuntu Shell脚本实现监视指定进程的运行状态,并能在程序崩溃后重启动该程序

根据网上博客实现,发现只能监测进程离线,然后对其进行重启;然而,脚本无法打印程序正常状态的信息。自己通过不断修改测试,发现问题主要在重启程序的命令上(需要让重启的程序在后台运行,不然会影响监视脚本进程,使其无法正常工作)。具体程序如下: #!/bin/bashwhile [ 1 ] ; dosleep 3if [ $(ps -ef|grep exe_name|grep -v grep|

Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.B

一个bug日志 FATAL EXCEPTION: main03-25 14:24:07.724: E/AndroidRuntime(4135): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.syyx.jingubang.ky/com.anguotech.android.activity.Init

adb shell 执行后台程序后断开adb后台进程被结束的解决办法

环境:Android 版本 Android8 通常让程序后台执行就是在命令 最后加上 &即可,但是在Android 8上实验发现,程序的确后台了,但是拔掉USB线再连接上发现进程已结束。不确定Android早期版本是否存在此问题。 参考网上一些Linux方法,如加nohup 仍然无效,还是会结束。看来Android adb shell 与 Linux shell 还是有一定区别。 后来在网上

shell脚本中变量中字符串替换的测试 /和//的区别

test_char=abbbcbbbf echo "bf:test_char = " $test_char test_char=${test_char/bbb/ddd} echo "af:test_char = " $test_char 输出: bf:test_char =  abbbcbbbf af:test_char =  adddcbbbf 只匹配第一个

shell循环sleep while例子 条件判断

i=1# 小于5等于时候才执行while [ ${i} -le 5 ]doecho ${i}i=`expr ${i} + 1`# 休眠3秒sleep 3doneecho done 参考 http://c.biancheng.net/cpp/view/2736.html

Linus常用的快捷键与shell常用通配符

一,常用快捷键: Ctrl+c这一个快捷键在Linux下的作用是强行终止当前程序(但不退出终端),其实在其他一些软件,比如MATLAB中,Ctrl+c也有终止程序的作用,如果你的程序进入了死循环,就可以用Ctrl+c来终止程序。 除了最普遍的Ctrl+c之外,还有以下快捷键:   按键  作用Ctrl+d 键盘输入结束或退出终端 Ctrl+s 暂定当前程序,暂停后