操作系统原理与设计实现 课件全套 第1-13章 操作系统概念及其发展概述 -图形子系统_第1页
操作系统原理与设计实现 课件全套 第1-13章 操作系统概念及其发展概述 -图形子系统_第2页
操作系统原理与设计实现 课件全套 第1-13章 操作系统概念及其发展概述 -图形子系统_第3页
操作系统原理与设计实现 课件全套 第1-13章 操作系统概念及其发展概述 -图形子系统_第4页
操作系统原理与设计实现 课件全套 第1-13章 操作系统概念及其发展概述 -图形子系统_第5页
已阅读5页,还剩529页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

操作系统OperatingSystem第1章操作系统概念及其发展概述Chapter1:Introduction什么是操作系统?所处的“位置”决定着承担的“任务”大多数受过高等教育的人都知道…第一步:去电子商场购买、组装一台机器硬件操作系统应用软件CPU、内存、磁盘、显示器、键盘…Windows,Linux…第二步:找光盘,给这台机器装上操作系统第三步:在操作系统上安装应用软件,开始使用Word,Matlab…使计算机更好用!这是操作系统的根本要义!!为什么操作系统放在那里?如果那里没有操作系统操作系统可以:屏蔽细节、统一管理硬件、防止违法操作…硬件应用软件硬件操作系统应用软件用户需要直接操作硬件。需要知道显存位置、知道扫描码…应用软件需要知道很多硬件信息。需要知道被的应用已经占有哪些内存…使计算机的使用更加方便、简单、高效…使计算机更好用—屏蔽复杂性Windows使得PC机进入了许多家庭…计算机是一个很复杂的系统:由许多设备组成:CPU、内存、硬盘、显示器、键盘、鼠标、8259、8042…每种设备有很多参数、类型:1M内存、256M内存、64G内存、PentiumCPU、ARMCPU…让用户(应用程序开发者)掌握上述内容是不可能的!

操作系统负责管理这些硬件设备:将设备变成一些直观的概念展现给用户,或者根本不让用户知道

使计算机更好用—使硬件高效工作打开一个文件,当1G内存的Pentium比一个16M内存的586还要慢时…可能吗?打开一个2G大小的文件!一个要从磁盘读入1G数据,另一个要读入16M数据!可以让1G内存也只读入16M文件(部分文件)吗?应该可以,其他内存空间呢(1G-16M)?可以放别的东西用户需要时刻注意,千万别有错误的jmp和mov,否则会导致:前面的工作白费、误导的结果…你也许宁愿选择前面的情况…什么是操作系统?操作系统是管理硬件的软件…“目录”管理的是什么硬件?操作系统是解释执行用户命令的控制软件…操作系统是,还是…硬盘某个扇区校验出错要不要管?这么多是还能成为一个合适定义吗?描述操作系统做什么比是什么更有意义操作系统就是操作系统,操作系统没必要定义操作系统要做什么?管理所有硬件资源伟大的冯诺依曼认为,计算机由五大部件组成:输入设备、输出设备、存储器、运算器、控制器硬件操作系统应用软件OS需要管理CPU(运算器、控制器)OS需要管理memory(内存)OS需要管理disk(外存)OS需要管理IO(输入/输出设备)进程管理内存管理文件系统I/O系统课程核心内容操作系统要做什么?管理OS中出现的软件资源硬件速度不匹配现象常见缓存区硬件操作系统应用软件缓存管理,如磁盘缓存等!课程内容按照硬件管理组织,软件资源的管理渗透在各个章节中GDT、函数表等OS用树管理大量信息典型的如目录管理OS要抽象要完成逻辑到物理的映射OS中会出现许多数据结构链表、队列、散链表等操作系统要做什么?向用户和应用软件提供使用接口用户输入ls时,OS需要将当前目录下的文件列出硬件操作系统应用软件可以看出,都是一些细节,它们会让计算机更好用。这些内容也渗透到各章节中监控用户对计算机的使用应用程序调用malloc()时,OS需要分配内存用户按下ctrl+c时,该用户的当前任务将被kill用户写一个文件时,OS需检查是否有权限等等……等等……“操作系统做什么”是动态变化的操作系统的任务会随环境而变化如实时操作系统—任务响应需满足一定的时限要求需要多读、多看,开阔眼界:SOSP,OSDI某些场合要求很严格的时限,如导弹控制某些场合要求不能太久,如键盘响应硬实时软实时某些场合没有时限要求,如屏保不需要考虑实时三种场合下OS所做的工作会有很大差别…操作系统的任务会随时间而变化Moore定律表明:设备体积迅速变小、能力迅速增强出现了嵌入式设备和嵌入式操作系统能源管理模块对EOS很重要本课程集中学习构成OS的基本模块进程管理、内存管理、文件系统、IO系统、系统服务五大块UNIX的整体式OS结构函数库系统调用接口文件系统进程管理存储管理字符设备块设备设备驱动硬件抽象用户系统服务“微内核”式操作系统结构压缩内核:将文件系统、设备驱动等部分从操作系统中移出…怎么调用这些功能?将文件读写变成服务(C/S),内核提供通信内核Win32程序Win32服务器POSIX程序POSIX服务器微内核UNIX模拟器DOS模拟器…用户空间程序程序程序Mach不是微内核也可以借鉴该思想(WindowsNT)“虚拟机”式操作系统结构使用硬件最复杂的地方就是多个任务(程序)共同使用,从而互相影响如果让一个程序独占整个机器,复杂度大幅降低一台虚拟机器VM/370采用虚拟机结构会话监控(CMS)即VM1+OS内核VM/370即虚拟机实现—完成虚到实的映射370裸机会话监控(CMS)即VM2+OS内核会话监控(CMS)即VM3+OS内核程序程序程序系统调用I/O指令该思想在OS中非常常见另外,各部分的设计和实现也多种多样硬件在发展、应用在扩展,实现技术也得跟上早期的计算机非常昂贵…(1948-1970)计算机使用原则:尽量让计算机满载此时操作系统的典型特征:批处理(Batchsystem)JOB1JOB2JOB3操作系统用户空间输出结果loadexecute各部分设计都以执行作业的数量的最大化为目标:如内存管理应尽量简单CPU尽量忙才能尽可能多的完成作业但操作I/O设备时CPU会等待很长时间(如读作业)处理办法:等待I/O设备时CPU去执行别的作业前提是内存中有多个作业:多道程序(Multiprogamming)Multics:1963年开始开发,1969使用操作系统JOB1JOB2JOB3输出结果调度执行多个程序“同时执行”需要进程调度、内存管理、磁盘存储等多个部分的配合(操作系统大幅改变)批处理操作系统使用在现在的大型机上硬件不断发展,越来越便宜1970-1985,$1000能买一个便宜的终端用户可以坐在终端设备前思考问题了此时计算机能响应用户,典型特征:交互(Interactive)怎么才能做到及时响应?分时操作系统也常使用在现在的带有多个终端的大型机上(如银行)分时系统将时间分成时间片。分时影响了进程调度和时钟处理操作系统JOB1JOB2JOB3响应用户调度执行时间硬件非常便宜、而人力昂贵1981-,$1K:1个计算机,$100K/year:1人计算机只要能使人力的效率提高1%就值得!个人计算(personalcomputing)方便用户(人机交互接口)成为了关键GUI(图形用户接口)mice,windowsMicrosoftWindows:Win1.0(1985)Win3.1(1990)Win95(1995)WinNT(1993)Win2000(2000)WinXP(2001)人机交互成了OS一个重要内容网络已逐渐成为生活基础设施1990-,出现了LAN,WAN,Internet…支持网络成为了OS的一个重要功能分布式计算(distributedcomputing)分布式文件共享:FTP,fileserverWeb信息服务:HTTP,webserver,IE…电子邮件服务:POP,mailserver,Outlook…还有因为网络病毒造成的防火墙,OS安全模块…这些内容使OS的文件系统,设备驱动,进程管理进一步发展出现了能力很强、支持网络的手持设备1995-,出现了手持设备Laptops,PDA等…这种设备的显著特点:移动性移动计算(mobilecomputing)需要支持无线通信:蓝牙、红外、无线电…Web信息服务:HTTP,webserver,IE…用户在任何位置的服务获取:Ubiquitous(普适)…手持、移动、个人:上下文感知计算…使OS的通信支持,设备驱动,安全保护(如私密性)进一步发展…正在实现的宏伟蓝图…ClustersMassiveClusterGigabitEthernetASocietalScaleInformationSystemPeer-to-peernetwork“计算机”的各部分分布在全球SensornetworkUbiquitous

serviceGridsystem“操作系统”的各部分分布在全球OS和网络没有界限操作系统的特点有许多概念、并不断涌现新的概念伴随着概念的涌现,各种技术曾出不穷以抽象为目的,结果却是实实在在的东西批处理、分时、实时、GUI、普适、P2P、Grid…进程管理,内存管理,文件系统,设备管理总是基础Xwindow是一个应用程序,Windows中的GUI工作在内核态(所以速度很快)CPU

进程;磁盘

文件;显示器

窗口…完成这些抽象的OS是一个实际存在的软件,你的不当操作会导致它崩溃…怎么学习操作系统?掌握适当的概念是必要的本课程采用的教材AbrahamSilberschatz,Galvin,Gagne等著,郑扣根译,操作系统概念(OperatingSystemConcepts),高等教育出版社数量适当,抓住最重要的,并梳理清楚什么都想知道,反而会导致没有任何意义操作系统是使计算机好用,如果塞了一堆概念在里面,计算机还能好用吗?完整的实践一个操作系统是最重要的引用Stanford操作系统课程中的一句话:“LearnOSconceptsbycodingthem!”OS中有很多并不深刻的概念(如分时、实时等),记住这些概念没有意义,实现这些概念才是最重要的OS是一个实实在在的“黑盒子”,就算明白了这个盒子的概念,它仍然是一个“黑盒子”OS是最复杂、最基础的软件系统,codingthem是计算机专业的学生的责任!纸上得来终决浅

绝知此事要躬行操作系统OperatingSystem第2章系统启动Chapter2:PowerOn操作系统课,我们希望学会什么?所有目标都要从“明白操作系统”开始控制器纸带0111010明白操作系统从“明白系统启动”开始打开电源开关后发生了什么?打开电源

计算机开始工作计算机怎么工作?又是谁决定了计算机是那样工作的?计算模型1936年,英国数学家A.C.图灵提出了一种模型人笔纸伟大的创举往往都是从朴素的想法开始的!从图灵机到通用图灵机控制器纸带0111010图灵机通用图灵机一个会做一道菜的厨师舀2大碗面放入盆中打6个鸡蛋放入盆中盆中加入500克水将盆中的物质搅拌均匀做成等厚度的饼状物大火蒸15分钟一个能看懂菜谱的厨师将这个过程描述:菜谱厨师菜谱1菜肴1菜肴2菜谱2这样的厨师才具有竞争力控制器纸带数据对象设置控制器动作修改控制器控制器状态处理从通用图灵机到计算机伟大想法的工程实现…又一个伟大的发明:冯·诺依曼存储程序思想movax,[100]……100:0

IPmovax,[100]IRax0存储器运算器、控制器就是那个读写指针1946年提出存储程序的主要思想:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制下一步一步进行处理计算机由五大部件组成:输入设备、输出设备、存储器、运算器、控制器打开电源,计算机发生了什么?可以打开电源了…计算模型我们要关注指针IP及其指向的内容计算机刚打开电源时,IP=?由硬件设计者决定!看看x86PCx86PC刚开机时CPU处于实模式开机时,CS=0xFFFF;IP=0x0000寻址0xFFFF0(ROMBIOS映射区)检查RAM,键盘,显示器,软硬磁盘将磁盘0磁道0扇区读入0x7c00处设置cs=0x07c0,ip=0x0000和保护模式对应,实模式的寻址CS:IP(CS左移4位+IP),和保护模式不一样!ROMBIOS0x000000000xFFFFFFFF0xF00000x100000ROMBIOS映射区0x7c00处存放的代码就是从磁盘引导扇区读入的那512个字节引导扇区就是启动设备的第一个扇区启动设备信息被设置在CMOS中…开机时按住del键可进入启动设备设置界面,可以设置为光盘启动!CMOS:互补金属氧化物半导体(64B-128B)。用来存储实时钟和硬件配置信息。因此,硬盘的第一个扇区上存放着开机后执行的第一段我们可以控制的程序。操作系统的故事从这里开始…引导扇区代码:bootsect.s

.globlbegtext,begdata,begbss,endtext,enddata,endbss.text//文本段begtext:.data//数据段begdata:.bss//未初始化数据段begbss:.textentrystart//关键字entry告诉链接器“程序入口”start:movax,#BOOTSEGmovds,axmovax,#INITSEGmoves,axmovcx,#256subsi,sisubdi,direpmovwjmpigo,INITSEG.text等是伪操作符,告诉编译器产生文本段,.text用于标识文本段的开始位置。此处的.text、.data、.bss表明这3个段重叠,不分段!此条语句就是0x7c00处存放的语句!BOOTSEG=0x07c0INITSEG=0x9000SETUPSEG=0x9020将0x07c0:0x0000处的256个字移动到0x9000:0x0000处jmpigo,INITSEG

go:movax,cs//cs=0x9000movds,axmoves,axmovss,axmovsp,#0xff00load_setup://载入setup模块

movdx,#0x0000movcx,#0x0002movbx,#0x0200movax,#0x0200+SETUPLENint0x13//BIOS中断

jncok_load_setupmovdx,#0x0000movax,#0x0000//复位

int0x13jload_setup//重读jmpi(jumpintersegment段间跳转):cs=INITSEG,ip=go为call做准备!启动盘boot扇区setup的4个扇区system模块(OS代码)0x13是BIOS读磁盘扇区的中断:ah=0x02-读磁盘,al=扇区数量(SETUPLEN=4),ch=柱面号,cl=开始扇区,dh=磁头号,dl=驱动器号,es:bx=内存地址读入setup模块后:ok_load_setup

Ok_load_setup://载入setup模块

movdl,#0x00movax,#0x0800//ah=8获得磁盘参数

int0x13movch,#0x00movsectors,cxmovah,#0x03xorbh,bhint0x10//读光标

movcx,#24movbx,#0x0007movbp,#msg1movax,#1301int0x10//显示字符

movax,#SYSSEG//SYSSEG=0x1000moves,ax

callread_it//读入system模块

jmpi0,SETUPSEG7是显示属性!bootsect.s中的数据//在文件末尾sectors:.word0//磁道扇区数msg1:.byte13,10.ascii“Loadingsystem...”.byte13,10,13,10显示这24个字符将是大家的第一个“创举”!转入0x9020:0x0000执行setup.sboot的工作:读setup,读system…read_it//读入system模块

read_it:movax,escmpax,#ENDSEGjbok1_readretok1_read:movax,sectorssubax,sread//sread是当前磁道已读扇区数,ax未读扇区数

callread_track//读磁道...system模块可能很大,要跨越磁道!为什么读入system模块还需要定义一个函数?ENDSEG=SYSSEG+SYSSIZESYSSIZE=0x8000//该变量可根据Image大小设定(编译操作系统时)引导扇区的末尾//BIOS用以识别引导扇区.org510.word0xAA55//扇区的最后两个字节否则会打出非引导设备可以转入setup执行了,jmpi0,SETUPSEGsetup模块,即setup.s

根据名字就可以想到:setup将完成OS启动前的设置start:movax,#INITSEGmovds,axmovah,#0x03xorbh,bhint0x10//取光标位置dxmov[0],dx

movah,#0x88int0x15mov[2],ax...cli///不允许中断

movax,#0x0000clddo_move:moves,axaddax,#0x1000cmpax,#0x9000jzend_move

movds,axsubdi,disubsi,simovcx,#0x8000repmovswjmpdo_move取出光标位置(包括其他硬件参数)到0x90000处扩展内存大小内存地址长度名称0x900002光标位置0x900022扩展内存数0x901FC2根设备号0x9000C2显卡参数SYSSEG=0x1000将system模块移到0地址将setup移到0地址处...但0地址处是有重要内容的end_move:movax,#SETUPSEGmovds,axlidtidt_48lgdtgdt_48//设置保护模式下的中断和寻址

进入保护模式的命令...idt_48:.word0.word0,0//保护模式的中断处理函数表gdt_48:.word0x800.word512+gdt,0x9gdt:.word0,0,0,0.word0x07FF,0x0000,0x9A00,0x00C0.word0x07FF,0x0000,0x9200,0x00C0ROMBIOS0x000000000xFFFFFFFF0xF00000x100000ROMBIOS映射区中断向量表前面的int指令才可以使用!以后不调用int指令了吗?因为操作系统要让硬件进入保护模式了…保护模式下intn和cs:ip解释不再和实模式一样又一个函数表将cs:ip变成物理地址保护模式下的地址翻译和中断处理保护模式下的地址翻译保护模式下中断处理函数入口即gdt的作用

t是table,所以实模式下:cs左移4+ip。保护模式下:根据cs查表+ipt仍是table,仿照gdt,通过intn的n进行查表GDTcs:ip物理内存地址IDTintn中断处理函数入口即idt的作用

进入保护模式callempty_8042moval,#0xD1out#0x64,al//8042是键盘控制器,其输出端口P2用来控制A20地址线callempty_8042moval,#0xDFout#0x60,al//选通A20地址线callempty_8042初始化8259(中断控制)//一段非常机械化的程序movax,#0x0001movcr0,axjmpi0,8

empty_8042:.word0x00eb,0x00ebinal,#0x64testal,#2jnzempty_8042ret

跳到下一句指令的机器码!位1=0,输入缓存器为空,不空说明PC机有问题D1表示写数据到8042的P2端口cr0一个非常酷的寄存器PGPE031PE=1启动保护模式,PG=1启动分页jmpi0,8//cs=8用来查gdtjmpi0,8//gdt中的8gdt:.word0,0,0,0.word0x07FF,0x0000,0x9A00,0x00C0.word0x07FF,0x0000,0x9200,0x00C0?GDTcs:ip0816段基址15..0段限长15..004段基址31..24段基址23..16段限长19..16PDPLGGDT表项0310x00C09A00000007FFFjmp到内存0x0000处是system模块!两个gdt表项,都是0x0000,一个只读(代码),一个读写(数据)跳到system模块执行...system模块(目标代码)中的第一部分代码?head.sdisk:Imageddbs=8192if=Imageof=/dev/PS0Image:boot/bootsectboot/setuptools/systemtools/buildtools/buildboot/bootsectboot/setuptools/system>Imagetools/system:boot/head.oinit/main.o$(DRIVERS)…

$(LD)boot/head.oinit/main.o$(DRIVERS)…-otools/systemsystem由许多文件编译而成,为什么是head.s?linux/Makefileif=inputfile/dev/PS0是软驱A明白为什么head.s就这样一个名字了吧?head.s//一段在保护模式下运行的代码setup是进入保护模式,head是进入之后的初始化stratup_32:movl$0x10,%eaxmov%ax,%dsmov%ax,%esmov%as,%fsmov%as,%gs//指向gdt的0x10项(数据段)lss_stack_start,%esp//设置栈(系统栈)callsetup_idtcallsetup_gdtxorl%eax,%eax1:incl%eaxmovl%eax,0x000000cmpl%eax,0x100000je1b//0地址处和1M地址处相同(A20没开启),就死循环

jmpafter_page_tables//页表,什么东东?setup_idt:leaignore_int,%edx

movl$0x00080000,%eaxmovw%dx,%axlea_idt,%edimovl%eax,(%edi)

和前面的代码不一样了?因为是32位汇编代码!struct{long*a;shortb;}stack_start={&user_stack[PAGE_SIZE>>2],0x10};

idt_48:.word0word0,0_idt:.fill256,8,0现在忽略中断关于汇编…head.s的汇编和前面不一样?movax,cs//csax,目标操作数在前

(1)as86汇编:能产生16位代码的Intel8086(386)汇编(2)GNUas汇编:产生32位代码,使用AT&T系统V语法AT&T美国电话电报公司,包含贝尔实验室等,1983年AT&TUNIX支持组发布了系统Vmovlvar,%eax//(var)%eaxmovb-4(%ebp),%al//取出一字节(3)内嵌汇编,gcc编译x.c会产生中间结果as汇编文件x.s__asm__(“汇编语句”:输出:输入:破坏部分描述);

__asm__(“movb%%fs:%2,%%al”:”=a”(_res):”0”(seg),”m”(*(addr)));a表示使用eax,并编号%0%2表示addr,m表示使用内存0或空表示使用与相应输出一样的寄存器after_page_tables//设置了页表之后setup是进入保护模式,head是进入之后的初始化after_page_tables:pushl$0pushl$0pushl$0pushl$L6pushl$_mainjmpset_pagingL6:jmpL6setup_paging:设置页表

ret将来学到!简单的几句程序,控制流却很复杂setup_paging执行ret后?会执行函数main()p3p2p1返回地址C执行func(p1,p2,p3)进入main()后的栈为0,0,0,L6main()函数的三个参数是0,0,0main()函数返回时进入L6,死循环...进入main函数为什么是void?在init/main.c中voidmain(void){mem_init();trap_init();blk_dev_init();chr_dev_init();tty_init();time_init();sched_init();buffer_init();hd_init();floppy_init();sti();

move_to_user_mode();if(!fork()){init();}}000L6执行main开始C语言程序了!三个参数分别是envp,argv,argc但此处main并没使用此处的main只保留传统main的形式和命名main表示C语言函数的入口!mian的工作就是xx_init:内存、中断、设备、时钟、CPU等内容的初始化…?开始系统服务操作系统生态由形形色色的服务构成main()函数内调用系统启动脚本,进一步systemd服务启动脚本systemd服务(以http服务为例)系统启动总结学习操作系统根本目标:认识、编写一个操作系统认识操作系统揭开操作系统神秘面纱把黑屏背后的东西展现给大家从开启电源后的黑屏开始打开电源CS:IP=0xFFFF0进入BIOSBIOS自检BIOS根据COMS找到启动盘将其0扇区读入0x7c00处CS=0x07c0,IP=0x0000开始执行引导扇区bootsect.ssetup启动保护模式(设置cr0)后调用system的head.sbootsect将setup模块和system模块读入转入setuphead.s完成idt,gdt等设置调用main()进行OS初始化操作系统OperatingSystem第3章系统接口Chapter3:Interface系统接口—用户通过它来使用操作系统对大多数用户来说,操作系统是一个“黑盒子”操作系统键盘命令鼠标点击网络数据屏幕输出文件改变……引导告诉了我们这个盒子是怎么放入内存的?在“打开这个盒子”之前要“了解盒子的入口”操作系统接口Interface:electricalcircuitlinkingonedevicewithanotherandenablingdatacodedinoneformattobetransmittedinanother(出自牛津辞典)

OS为什么要执行这些转换?用户操作系统保护操作系统、应用程序可以移植、让用户觉得简单方便…这也是“接口”(将复杂转换为简单)普遍具有的优点学习转换—从转换之前开始用户使用操作系统(计算机系统)基本方式命令行图形用户接口(GUI)应用程序命令行是怎么回事?命令是什么?命令输入后发生了什么?#include<stdio.h>intmain(intargc,char*argv[]){printf(“ECHO:%s\n”,argv[1]);}gcc–ooutputoutput.c./output“hello”命令,一段程序而已intmain(intargc,char*argv[]){charcmd[20];while(1){scanf(“%s”,cmd);

if(!fork()){exec(cmd);}else{wait();}}//while(1)}也是一段程序:shell,即/bin/sh命令得以工作的原因:OS提供了printf,fork,exec等函数(接口)使GUI工作,OS提供消息框架和相关API硬件输入Windows应用程序iGUI是怎么回事?鼠标点击OUTPUT以后…voidCOutputDlg::OnOK(){GetDlgItemText(IDC_EDIT1,m_outStr);FILE*fp=fopen("d:\\out.txt","w");

fprintf(fp,m_outStr,m_outStr.GetLength());fclose(fp);}系统消息队列消息循环WinMain()WM_MOUSEDOWN应用消息队列iWinProc1WinProc2OUTPUT按钮的WinProc(){caseWM_MOUSEDOWN:OnOK();}总结其中最重要的概念系统调用用户使用计算机总结:应用操作系统提供的接口编写程序;应用这些程序解决问题命令行:命令程序+shell+字符显示GUI:消息处理程序+消息框架+图形显示应用程序:将上述部分组成一个整体…因此:用户通过OS接口使用计算机;OS接口影响计算机的使用方式这么重要,得起个名字:接口表现为函数调用,又由OS提供,叫系统调用系统调用是学习操作系统的首要任务…系统调用学习转换—提供哪些系统调用?POSIX:将接口统一比较好!PortableOperatingSystemInterfaceofUnix

系统调用由IEEE开发,是一个标准族:

1003.1,2003…分类POSIX定义描述任务管理forkexecl创建一个进程运行一个可执行程序pthread_create创建一个线程文件系统open打开一个文件或目录EACCES返回值,表示没有权限mode_tst_mode文件头结构:文件属性S_ISDIR(m)宏展开,是否为目录文件对于指令跳转也一样实现了隔离…学习转换—怎么实现系统调用?将内核程序和用户程序隔离比较好!区分内核态和用户态:一种处理器“硬件设计”系统调用处理器保护环0123核心态OS服务用户态CPL(CS)RPL(DS)DPL检查DPLCPLDPLRPL当前程序执行在什么态(哪层环)?由于CS:IP是当前指令,所以用CS的最低两位来表示:0是内核态,3是用户态访问的数据段DS的最低两位内核态可以访问任何数据,用户态不能访问内核数据硬件提供了“主动进入内核的方法”对于Intelx86,那就是中断指令intint指令将使CS中的CPL改成0,“进入内核”这是用户程序发起的调用内核代码的唯一方式此时,CPL=3而DPL=0若用户程序想调内核代码:写一段包含int指令的代码系统调用的实现:(1)用户程序中写上一段包含int指令的代码(2)OS写中断处理代码,获取想调程序的编号(3)OS根据编号转去执行相应的代码由谁做?库函数!系统调用编号系统调用的实现调用printf(…)应用程序库函数printf(…)C函数库库函数write(…)系统调用write(…)OS内核显然,库函数write是本图的关键在linux/lib/write.c中#include<unistd.h>_syscall3(int,write,int,fd,constchar*buf,off_t,count)在linux/include/unistd.h中#define_syscall3(type,name,...)typename(...)\{__asm__volatile(“int0x80”\:”=a”(__res)...}Linux系统调用的实现细节!将关于write的故事完整的讲完…

在linux/include/unistd.h中#define_syscall3(type,name,atype,a,btype,b,ctype,c)\typename(atypea,btypeb,ctypec)\{long__res;\__asm__volatile(“int0x80”:”=a”(__res)\:””(__NR_##name),”b”((long)(a)),”c”((long)(b)),\“d”((long)(c))));if(__res>=0)\return(type)__res;errno=-__res;return-1;}显然,__NR_write是系统调用号,放在eax中在linux/include/unistd.h中#define__NR_write4//一堆连续正整数(数组下标,函数表索引)同时eax也存放返回值,ebx,ecx,edx存放3个参数_syscall3表示有3个参数int0x80中断的处理

voidsched_init(void){set_system_gate(0x80,&system_call);}显然,set_system_gate用来设置0x80的中断处理在linux/include/asm/system.h中#defineset_system_gate(n,addr)\_set_gate(&idt[n],15,3,addr);//idt是中断向量表基址#define_set_gate(gate_addr,type,dpl,addr)\__asm__(“movw%%dx,%%ax\n\t”“movw%0,%%dx\n\t”\“movl%%eax,%1\n\t”“movl%%edx,%2”:\:”i”((short)(0x8000+(dpl<<13)+type<<8))),“o”(*((\char*)(gate_addr))),”o”(*(4+(char*)(gate_addr))),\“d”((char*)(addr),”a”(0x00080000))段选择符处理函数入口点偏移04处理函数入口点偏移PDPL01110中断处理程序:system_call

_sys_call_table+4*%eax就是相应系统调用处理函数入口在linux/kernel/system_call.s中nr_system_calls=72.globl_system_call_system_call:cmpl$nr_system_calls-1,%eaxjabad_sys_callpush%dspush%espush%fspushl%edxpushl%ecxpushl%ebx//调用的参数

movl$0x10,%edxmov%dx,%dsmov%dx,%es//内核数据

movl$0x17,%edxmov%dx,%fs//fs可以找到用户数据

call_sys_call_table(,%eax,4)//a(,%eax,4)=a+4*eax

pushl%eax//返回值压栈,留着ret_from_sys_call时用

...//其他代码ret_from_sys_call:popl%eax,其他pop,ireteax中存放的是系统调用号__asm__volatile(“int0x80”:”=a”(__res)在include/linux/sched.h中typedefint(fn_ptr*)();_sys_call_tablecall_sys_call_table(,%eax,4)就是callsys_write在include/linux/sys.h中fn_ptrsys_call_table[]={sys_setup,sys_exit,sys_fork,sys_read,sys_write,...};sys_call_table是一个全局函数数组sys_write对应的数组下标为4,__NR_write=4eax=4,函数入口地址长度也为4用户调用printfprintf展成int0x80中断处理system_call查表sys_call_table__NR_write=4调用sys_write故事结束!用户态内核态系统接口总结对于用户来说操作系统是个“黑盒子”要打开这个盒子先得找到“盒子的入口”系统接口接口:连接两个设备并转换数据系统接口连接用户和OS学习转换转换之前:用户如何使用计算机?命令、GUI、Apps都是应用OS提供的函数接口编程序系统调用有哪些?POSIXOS提供的函数系统调用系统调用有哪些?怎么做?系统调用怎么实现?用户函数展成int指令进入内核printfwriteint0x80(eax=4)system_callsys_write

操作系统OperatingSystem第4章多进程Chapter4:Processes内容回顾计算机系统计算机硬件今天的学习内容管理CPU、让用户使用CPU硬件操作系统应用软件图形控制器总线管理硬件、方便用户使用的软件管理CPU,先要了解CPUCPU的工作原理CPU上电以后发生了什么?发出一个地址:如50

50:movax,[100]

51:movbx,[101]

52:addax,bx……

100:0101:1movax,[100]movax,[100]IRax0CPU怎么工作?自动的取指—执行CPU怎么管理?即PC=50

50:movax,[100]

51:movbx,[101]

52:addax,bx……

100:0101:1管理CPU的最直观方法PCmovax,[100]IRax0movbx,[101]IRPCbx1PCaddax,bxIRax1设好PC初值就完事!把程序读到内存50处,设PC=50,CPU开始干活看看这样做有没有问题?提出问题intmain(intargc,char*argv[]){inti,to,*fp,sum=0;to=atoi(argv[1]);for(i=1;i<=to;i++){sum=sum+i;

fprintf(fp,“%d”,sum);}}fprintf用一条其他计算语句代替有fprintf0.015/1070.859/1035.7

105:1怎么解决?某程序(等待文件输出)(等待文件输出)其他程序(等待)(等待)现在变成了这个样子

50:movax,[100]

51:movbx,[101]

52:addax,bx

53:

启动磁盘读写

54:xxxx

100:0101:1该怎么办?

200:xxxx

201:xxxx

202:xxxx

单道程序与多道程序单道程序:ABCPUDEV1DEV2CPUCPU1015203040

25DEV1CPU3545DEV2CPUDEV2单道程序多道程序CPU利用率40/80=50%40/45=89%DEV1利用率15/80=18.75%15/45=33%DEV2利用率25/80=31.25%25/45=56%BDEV2

CPU

DEV1

DEV2

CPU

5060

70

8065

CPU

DEV1

DEV2

CPU

CPU

A

1015

203040多道程序:40一个CPU如何执行多道程序一个CPU上交替的执行多个程序:并发50:movax,151:

movbx,152:

addax,bx……

程序1200:movax,10201:movbx,10202:addax,bx……

程序2PCPC怎么做到?需要切到另一个程序时,OS修改PC=200修改寄存器PC就行了吗?程序1信息ax21bx53PC50:movax,151:

movbx,152:

addax,bx……

程序1200:movax,10201:movbx,10202:addax,bx……

程序2PCPC切回去怎么办?要记录返回地址,要记录ax…每个程序有了一个存放信息的结构:PCB运行的程序和静态程序不一样了…引入“进程”概念运行的程序和静态程序不一样!进程是进行(执行)中的程序程序+所有这些不一样

一个概念需要描述这些不一样…这些不一样就成了进程概念的外延进程有开始、有结束,程序没有进程需要记录ax,bx,…,程序不用进程会走走停停,走停对程序无意义…………有趣的是:并发技术使“不一样”增加了“取指-执行”CPU的任务为执行程序并发交替执行多个程序执行的程序和静态程序不一样进程CPU管理OS管理多个进程第一件事:OS怎么组织多个进程PCB1RegistersPCB6RegistersHeadTail磁盘等待队列PCB5RegistersPCB8RegistersPCB7RegistersHeadTail就绪队列物理CPUPCB6RegistersPCB4Registers有一个进程在执行有一些进程等待执行有一些进程再等待某事件ProcessControlBlock:用来记录进程信息的数据结构进程状态及状态转换运行等待;运行就绪;就绪运行……运行态阻塞态就绪态新建态终止态该图称为进程状态图它能给出进程生存期的清晰描述它是认识操作系统进程管理的一个窗口第二件事:进程如何交替执行?启动磁盘读写;pCur.state=‘W’;将pCur放到DiskWaitQueue;schedule();schedule(){pNew=getNext(ReadyQueue);switch_to(pCur,pNew);}getNext就是进程调度,一个很深刻的话题优先级该怎么设定?可能会使某些进程饥饿Priority?FIFO显然是公平的策略FIFO?FIFO显然没有考虑进程执行的任务的区别switch_to(pCur,pNew)switch_to(pCur,pNew){pCur.ax=CPU.ax;pCur.bx=CPU.bx;

... pCur.cs=CPU.cs;pCur.retpc=CPU.pc;

CPU.ax=pNew.ax;CPU.bx=pNew.bx;

... CPU.cs=pNew.cs;CPU.retpc=pNew.pc; }PCB2PCB1内存CPU物理CPUPCB1PCB2一段数据(PCB)第三件事:多进程并存会相互影响movax,10100bmov[100],ax……

进程1代码

100:00101……

进程2代码多个进程同时在存在于内存会出现下面的问题解决的办法:限制对地址100的读写100不是实际的内存地址movax,10100bmov[100],ax……

进程1代码780:1(进程1的数据)……

物理内存会影响到操作系统对内存的管理…映射表780进程1根本访问不到其他进程的内容进程1的映射表将访问限制在进程1范围内地址空间:保护进程的基本机制780:1(进程1的数据)……

物理内存1260:0(进程2的数据)……

mov[100],ax进程1100:1StackHeapDataCode0000ffffmov[100],ax进程2100:0StackHeapDataCode0000ffff进程1映射表780进程2映射表1260地址空间和程序执行可以分离吗?mov[100],ax进程那个指令执行序列就是线程进程切换笨重;进程代价昂贵映射表一个地址空间内可以存在多个指令执行序列mov[100],ax

寄存器映像

寄存器映像进程代码、进程数据、进程资源第四件事:多个进程合作一项任务想一想打印工作过程应用程序提交打印任务打印任务被放进打印队列打印进程从队列中取出任务打印进程控制打印机打印待打印文件队列out=4m.docprog.c…w.pdf…4567in=7进程1进程2打印进程生产者

消费者#defineBUFFER_SIZE10typedefstruct{...}item;itembuffer[BUFFER_SIZE];intin=out=counter=0;共享数据while(true){while(counter==BUFFER_SIZE) ;buffer[in]=item;in=(in+1)%BUFFERSIZE;counter++;}生产者进程while(true){while(counter==0) ;item=buffer[out];out=(out+1)%BUFFERSIZE;counter--;}消费者进程生产者-消费者引出的问题共享变量counter会出现语义错误如生产者进程和消费者进程各执行一次register=counter;register=register+1;counter=register;生产者P消费者Cregister=counter;register=register-1;counter=register;P.register=counter;P.register=P.register+1;C.register=counter;C.register=C.register-1;counter=P.register;counter=C.register;一个可能的执行序列初始情况counter=5;解决该问题的一个尝试写counter时阻断其他进程访问counterP.register=counter;P.register=P.register+1;C.register=counter;C.register=C.register-1;counter=P.register;counter=C.register;一个可能的执行序列生产者PP.register=counter;P.register=P.register+1;给counter上锁消费者Ccounter=P.register;检查counter锁生产者P给counter开锁消费者CC.register=counter;C.register=C.register-1;counter=C.register;给counter上锁给counter开锁进程同步是操作系统一项重要内容用户怎么操纵进程?Windows进程创建:CreateProcessBOOLCreateProcess(LPCTSTRlpApplicationName,..){pNew=getNewPCB();

PCB[pNew].addrMap=newAddressMap;

Load(PCB[pNew].addrMap,lpApplicationName);

PCB[pNew].regs.r7=0; ...PCB[pNew].regs.r0=0;PCB[pNew].regs.retpc=

getStartAddress(lpApplicationName);EnQueue(ReadyQueue,pNew);}UNIX进程创建:forkintfork(){SaveSatate();//保存调用fork的进程的现场

pNew=getNewPCB();

copy(PCB[pNew],PCB[pCur]);

EnQueue(ReadyQueue,pNew);}if((pid=fork())==0){printf(“ChildProcess\n”);}else{printf(“ParentProcess\n”);}阻塞进程:WaitForSingleObject(…)intwait()//UNIX等待子进程结束{EnQueue(ChildExitQueue,pCur);Dispatch();}intWaitForSingleObject(ObjectO)//Windows等待{EnQueue(O.Queue,pCur);Dispatch();}大家可以考虑fprintf是怎么处理的?进程总结计算机解决问题执行程序

执行中的程序和静止程序存在很大区别

引出进程CPU太快引出并发进一步深化了进程进程走走停停状态转化现场切换进程调度进程相互干扰进程保护地址空间线程进程相互协作进程同步锁进程通信消息用户希望操纵进程进程创建等一点题外话进程是操作系统的核心

操作系统的根本目的是?进程的设计和实现需要考虑?进程转态进程调度进程其他操作接口操作系统OperatingSystem第5章线程Chapter5:Threads进程回顾进程进行中的程序需要准备程序执行所需的资源mov[100],ax100:1StackHeapDataCode0000ffff映射表需要记录进程如何向前推进进程1ax11bxPC寄存器映像...进程回顾进程=资源+指令执行将资源和指令执行分开一个资源+多个指令执行序列mov[100],ax进程映射表mov[100],ax

寄存器映像

寄存器映像进程代码、进程数据、进程资源线程线程:保留了并发的优点,避免了进程的高代价线程是否简单、实用?

一个真正好的想法一定是简单而实用的!多个执行序列+一个地址空间是否实用?这些线程共用一个地址空间吗?一个网页浏览器一个线程用来从服务器接收数据一个线程用来处理图片(如解压缩)一个线程用来显示文本一个线程用来显示图片同一个服务器建立连接并接收数据所有的文本、图片都显示在一个屏幕上线程是否简单好用?voidWebExplorer(char*URL){pthread_ttid1,tid2,tid3,tid4;pthread_attr_tattr1,attr2,attr3,attr4;pthread_attr_init(&attr1);...

pthread_create(&tid1,&attr1,GetData,URL);...}voidGetData(char*URL){...};voidShowText(){...};voidProcessImage(){...};voidShowImage(){...};线程怎么实现?WebExplorer怎么能好使?在函数库中实现和线程有关的函数两个问题:在哪里实现?怎么实现?#include<pthread.h>voidWebExplorer(char*URL){...pthread_create(&tid1,&attr1,GetData,URL);

...}线程库在哪里实现–这是一个问题吗?不是显然应该放在系统核心吗?–

和进程一样进程:不同的地址空间vs.线程:同一地址空间mov[100],ax进程1100:1StackHeapDataCode0000ffffmov[100],ax进程2100:0StackHeapDataCode0000ffff映射表映射表一个进程不应该访问其他进程的映射表进程在用户级实现没法完成这一目的实现方案1:用户级线程需要好好想一想!操作系统全然不知道有用户级线程库这回事需要做的事和通常写的程序(如图搜索)区别并不大(1)问题定义:要做什么(2)设计:要做成什么样(3)程序实现:具体怎么做要做什么?在一个地址空间中产生多个执行序列

A(){B();}100:1StackHeapDataCode0000ffff一个执行序列100:1Stack1Stack2HeapDataCode0000ffff多个执行序列

A(){B();}

C(){D();}要做成什么样?–如何产生执行序列在一个地址空间增加一个执行序列需增加什么?(1)PC指针(2)实现函数调用的栈(3)寄存器映像程序执行的其他信息在哪里?在该线程所属的PCB里具体怎么做?–产生执行序列执行序列所需的信息放在哪里?TCB!typedefstruct__pthread_attr_s{...void*__stackaddr;size_t__stacksize;...}pthread_attr_t;有点奇怪!PC指针和ax等的内容放在哪里了?具体怎么做?–用栈来保存现场首先回顾一下栈!A(inttmp){if(tmp<2)B();}B(){C();}C(){A(2);}A(1);A:tmp=2ret=C+1A:tmp=1ret=exitB:ret=A+2C:ret=B+1栈的增长方向栈顶指针从函数A(一段代码)到函数B(另一段代码)具体怎么做?–用栈来保存现场和函数调用有什么不同?两个栈线程SS.funcS.func

当前PC寄存器映像保存栈指针switch开始切换线程T栈的增长方向T.funcT.func

要到的PC寄存器映像载入栈指针保存在哪里?具体怎么做?–完成切换ThreadSwitch(Cur,Next)pushax;pushbx;...pushsi;pushdi;

movax,TCB[Cur].__stackaddr;mov[ax],sp;

movcx,TCB[Next].__stackaddr;movsp,[cx];popdi;popsi;...;popbx;popax

ret这是什么意思?具体怎么做?–关于NextThread如何选择NextThread?也是调度问题,将在下一章阐述有趣的是:用户级线程

用户可以自己定调度策略何时选择NextThread?和进程类似,等待某事件也可以定义优先级用户级线程

用户可以自己定调度策略具体怎么做?–pthread_create现在可以创建线程了!pthread_create(&tid,&attr,GetData,URL){get_TCB(&tid);copy(TCB[tid],attr);void*ssp=get_STACK();

TCB[Cur].__stackaddr=ssp;copy(ssp,URL);copy(ssp+1,Ge

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论