基于i386的简单OS的设计与实现_第1页
基于i386的简单OS的设计与实现_第2页
基于i386的简单OS的设计与实现_第3页
基于i386的简单OS的设计与实现_第4页
基于i386的简单OS的设计与实现_第5页
已阅读5页,还剩67页未读 继续免费阅读

下载本文档

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

文档简介

目录PAGE摘要基于i386的简单OS的设计与实现,是针对于操作系统的一个熟悉和深入理解熟悉的过程。初步实现了操作系统的加载启动,使进程在操作系统中运转,对文件磁盘内存进行了管理。本系统的设计完全在Linux系统上进行,调试运行使用了Bochs虚拟机,编译环境使用nasm、gcc、make等。大部分功能性实现参考借鉴于Linux内核。系统执行过程是虚拟设备上电启动,BIOS自检在7C00处找到引导扇区程序,系统进入到实模式,实模式加载完成后执行加载Loader的程序并跳转到保护模式,将Loader作为中转加载内核,并实现到内核的跳转,从此正式进入操作系统的核心部分,创建进程,将信息输出到终端中,输出进程的通信内容,对文件进行操作。引导扇区模块不依赖于其他软件实现在裸机上运行,负责引导存放在磁盘的其他部分的程序,用于加载Loader。Loader模块由于引导扇区空间有限,将不必要的工作交给Loader,负责用于过渡将内核加载入内存。内核模块从实模式进入保护模式,当计算机向扇区交出控制权后,所有的后续功能部分都在内核中实现。除部分中断由汇编实现外,其余部分都由C语言实现。进程创建模块负责在系统中创建进程。键盘模块中设置键盘中断处理程序,实现键盘输入缓冲区,设计键盘扫描表,根据检测到的输入并显示在终端,实现多终端的切换,实现特殊功能按键的处理。分区模块对磁盘进行分区。在中断模块中大体分为硬中断和软中断。根据程序结构编写Makefile,编译模块实现对代码的编译和链接等操作。实现了本系统。关键词:Linux内核,gcc,操作系统AbstractThedesignandimplementationofsimpleOSbasedoni386isafamiliaranddeepunderstandingprocessforoperatingsystem.Theinitialimplementationoftheoperatingsystemloadstart,sothattheprocessrunsintheoperatingsystem,thefilediskmemorymanagement.ThedesignprocessofthissystemisentirelyontheLinuxsystem,usingBochsvirtualmachine,GCC,NASM,makeandothercompilingenvironments.ReferencetotheLinuxkernel.Thesystemprocessisthatthevirtualdeviceispoweredonandstarted.TheBIOSselfcheckfindsthebootsectorprogramat7c00,andthesystementerstherealmode.Aftertherealmodeisloaded,executetheprogramtoloadtheloaderandjumptotheprotectionmode.Taketheloaderasthetransitloadingkernelandrealizethejumptothekernel.Thenformallyenterthecorepartoftheoperatingsystem,createtheprocess,andoutputtheinformationtotheterminalOutputthecommunicationcontentoftheprocessandoperatethefile.Thebootsectormoduledoesnotrelyonothersoftwareimplementationtorunonbaremetalmachine,andisresponsibleforbootingprogramsstoredinotherpartsofthediskforloadingloader.Duetothelimitedspaceofthebootsector,theloadermodulegivestheunnecessaryworktotheloader,whichisresponsiblefortheTransitionalLoadingofthekernelintomemory.Thekernelmoduleenterstheprotectionmodefromtherealmode.Whenthecomputerhandsoverthecontrolrighttothesector,allsubsequentfunctionsareimplementedinthekernel.Exceptthatsomeinterruptsareimplementedbyassembly,therestareimplementedbyClanguage.Theprocesscreationmoduleisresponsibleforcreatingprocessesinthesystem.Inthekeyboardmodule,thekeyboardinterruptprocessingprogramisset,thekeyboardinputbufferisrealized,thekeyboardscantableisdesigned,andaccordingtothedetectedinputanddisplayedintheterminal,themultiterminalswitchisrealized,andtheprocessingofspecialfunctionkeysisrealized.Thepartitionmodulepartitionsthedisks.Intheinterruptmodule,itcanbedividedintohardinterruptandsoftinterrupt.Themakefileiswrittenaccordingtotheprogramstructure,andthecompilingmodulecancompileandlinkthecode.Thesystemisrealized.Keywords:Linuxkernel,GCC,operatingsystem目录PAGEPAGE47目录第1章概述 41.1设计背景 41.2国内外研究现状 41.3设计内容及目标 5第2章需求分析 62.1操作系统概况 62.2系统需求 7第3章概要设计 93.1功能模块设计 93.2功能设计 102.3.1加载模块需求分析 102.3.2进程模块需求分析 112.3.3I/O模块需求分析 112.3.4磁盘管理模块需求分析 112.3.5文件模块需求分析 12第4章详细设计 134.1系统描述 134.2系统结构 134.3加载模块 154.3.1引导扇区模块 154.3.2Loader模块 174.3.3内核模块 184.4进程模块 184.4.1进程创建模块 184.4.2进程调度模块 204.4.3进程通信模块 214.4I/O模块 214.4.1键盘模块 214.6.2终端模块 234.5磁盘管理模块 264.5.1磁盘驱动模块 264.5.2磁盘分区模块 274.6文件模块 284.6.1文件系统 284.6.1文件创建 294.6.2文件读写 314.6.4文件删除 32第5章测试 335.1单元测试 335.2集成测试 34结论 46致谢 47参考文献 48附录设计系统部分源代码 50附录PAGE16ContentsChapter1Overview 41.1Designbackground 41.2Researchstatusathomeandabroad 41.3Designcontentsandobjectives 5Chapter2Requirementanalysis 62.1Operatingsystemoverview 62.2systemrequirements 7Chapter3Outlinedesign 93.1Functionmoduledesign 93.2Functionaldesign 102.3.1Demandanalysisofloadingmodule 102.3.2Processmodulerequirementsanalysis 112.3.3I/Omodulerequirementsanalysis 112.3.4Requirementanalysisofdiskmanagementmodule 112.3.5Requirementanalysisofdocumentmodule 12Chapter4Detaileddesign 134.1Systemdescription 134.2Systemstructure 134.3Loadmodule 154.3.1Bootsectormodule 154.3.2Loadermodular 174.3.3Kernelmodule 184.4Processmodule 184.4.1Processcreationmodule 184.4.2Processschedulingmodule 204.4.3Processcommunicationmodule 214.4I/Omodule 214.4.1Keyboardmodule 214.6.2Terminalmodule 234.5Diskmanagementmodule 264.5.1Diskdrivermodule 264.5.2Partitionmodule 274.6Filemodule 284.6.1Filesystem 284.6.1Filecreation 294.6.2Filereadingandwriting 314.6.4Filedeletion 32Chapter5Test 335.1Unittesting 335.2Integrationtesting 34Conclusion 46Thanks 47References 48Appendixdesignsystempartsourcecode 50第1章概述1.1设计背景操作系统是承载各种信息设备和软件应用运行的基础平台,是配置在计算机硬件上的第一层软件。它是一组控制和管理计算机硬件和软件资源,合理地对各类作业进行调度以及方便用户的程序集合。操作系统是用来对整个计算机系统的硬件和软件资源进行配置和管理,控制所有应用程序运行,提供人机交互的平台,是计算机工作的灵魂,CPU、数据库、办公软件、中间件、应用软件等需要与操作系统深度适配。现如今,操作系统发展迅速,逐步进入了社会生活的各个方面,涉及大型计算机、个人计算机、移动便携设备、其他自动化设备等各个层次的应用领域。操作系统产业生态非常复杂,需要以操作系统为核心,支撑软件(数据库、中间件)、硬件(芯片、其他硬件厂商)、终端(基于嵌入式系统)、应用支持、教育和培训体系等各个方面的相互配合和支撑,形成可持续发展的产业生态。1.2国内外研究现状从产业规模上看,全球OS市场规模保持稳定,但其产业生态带动作用持续增强。自2010年起,全球OS市场规模增速持续放缓,基本保持在320亿美元左右。全球操作系统领军企业微软在操作系统领域的营收自2010年起呈现出逐步下滑态势(2010年微软操作系统全球市场份额为78.6%)。尽管市场规模增长乏力,但OS在信息技术创新和产业发展的地位仍然较大。微软持续加大在OS领域的研发,并积极布局发展移动终端、平板、虚拟现实设备等新计算平台上的操作系统。谷歌一方面不断夯实其在智能手机OS领域的领先地位,另一方面积极拓展桌面、物联网等操作系统市场。苹果则一如既往加大对自身品牌操作系统的优化,利用已经建立的产业生态扩大操作系统的市场地位。由此可见,操作系统在产业生态带动中的价值依然突出,依旧保持着在产业竞争中的核心地位。从产业格局上看,通用型OS已被国际巨头占据先发优势,加快构建壁垒。在桌面OS领域,微软依旧占据着全球领先地位。截至2017年12月,全球桌面OS市场的绝大多数份额都被微软Windows所占据,非Windows产品市场份额总和仅为11.12%。在移动终端OS领域,截至2017年第一季度,谷歌主导的安卓的全球市场份额已经达到了85%,谷歌和苹果两家总市场份额达到99.79%,移动OS市场已经呈现出“一大一小”的基本格局,相较于2010年,市场的集中度大幅提升。此外,微软、谷歌等国际巨头在OS领域的研发投入力度持续加大,通过不断的推进新产品的研发来确保自身在市场竞争中的优势地位,旧产品市场份额下降的同时新产品的市场份额会快速上升,从而使企业系列产品的市场份额总和保持稳定,持续的技术研发和产品更新构建了较为厚实的市场竞争壁垒,市场新进者基本无法撼动原有的市场格局。1.3设计内容及目标本设计的功能包括:1、引导扇区和用于加载内核的Loader。2、实现进程和系统调用。3、检测键盘的输入并将内容显示在显示器上,并实现多终端切换,实现输入输出调用。4、实现进程间的通信。5、实现文件管理。第2章需求分析本系统大部分将通过借鉴于Linux内核成熟的设计经验,Linux是自由免费开源的Linux是以Unix为原型改造的,一个多用户多任务的操作系统,任何人都可以修改其代码和页面,其中主要的目的就是为了不受商业化的限制,而我们将服务器部署在Linux系统上会更加高效稳定、安全(注:UNIX操作系统(尤尼斯),是一个强大的多用户、多任务操作系统,支持多种处理器架构).Linux最初是由芬兰赫尔辛基大学学生LinusTorvalds在1991年处于个人爱好设计了Linux系统的内核,在1994年正式采用GPL协议。在前辈大神们的基础上,开发这款基于i386的简单OS的设计与实现为题目的简单操作系统雏形。2.1操作系统概况操作系统是为高等院校开发的,用于管理电脑硬件及软件的资源,操作系统提供环境以便执行程序。它为程序及程序用户提供服务,使编程变得更加容易。操作系统(OperatingSystem,简称Os)是承载各种信息设备和软件应用运行的基础平台,是配置在计算机硬件上的第一层软件。它是一组控制和管理计算机硬件和软件资源,合理地对各类作业进行调度以及方便用户的程序集合。操作系统是用来对整个计算机系统的硬件和软件资源进行配置和管理,控制所有应用程序运行,提供人机交互的平台,是计算机工作的灵魂,CPU、数据库、办公软件、中间件、应用软件等需要与操作系统深度适配。现如今,操作系统发展迅速,逐步进入了社会生活的各个方面,涉及大型计算机、个人计算机、移动便携设备、其他自动化设备等各个层次的应用领域。2.2系统需求本系统设计,设计的是一个简单的操作系统,要在一个裸机的状态下让计算机从开启电源,从BIOS模式下识别进入引导扇区,在通过Loader进入系统内核部分同时在显示器上显示系统运行的状态。在内核中实现系统对进程的管理,实现进程调度,进程通信等基础功能。管理系统的输入部分,将用户的按键输入等解析成正确的内容并显示在屏幕上。让系统对磁盘进行操作,并进行合理分区化管理。最后为系统设计文件系统,对文件进行基础的增删改查操作。2.2.1加载模块需求分析与Linux等操作系统相似,本系统使用三步来引导系统内核,引导扇区、loader和引导内核。这过程中存在双模式:实模式和保护模式。2.2.2进程模块需求分析在操作系统的进程管理上,应实现通过创建进程结构体与进程结构表的方式来创建进程,通过时钟中断等方式来实现进程的调度,使用进程通信模块来实现进程之间的异步通信。2.2.3I/O模块需求分析作为一个相对完备的操作系统,拥有良好的人机交互是必不可少的,在操作系统的人机交互上,应实现通过键盘模块实现键盘的输入,(包括一些特殊键的处理),并能够将内容实时显示到终端上。2.2.4磁盘管理模块需求分析本操作系统对于磁盘的管理,主要分成两个部分,一是磁盘驱动,它用来隐藏硬件细节,向上层进程提供统一接口。二是磁盘分区,实现合理使用资源和对磁盘空间的良好管理,避免磁盘浪费。2.2.5文件模块需求分析操作系统应有一个,用于存储和组织计算机文件数据的文件系统。在文件模块中,设计对文件的添加、删除、修改等。第3章概要设计基于i386的简单OS的设计与实现,设计了操作系统的从上电启动开始启动的过程。对进程的运行状态进行控制。设计系统的输入输出部分,检测用户输入和显示的功能。让系统识别磁盘,并对磁盘进行分区。设计文件系统对文件进行合理有效的管理。3.1功能模块设计功能模块图如图3-1所示。本系统可分为五个部分1、加载模块:加载模块是在计算机在电源启动后,逐渐加载各个状态的一个功能模块。分为引导扇区模块、Loader模块、内核模块。2、进程模块:进程模块负责在系统中创建进程,并处理进程的运行状态,实现多进程。分为进程创建模块、进程调度模块、进程通信模块。3、I/O模块:I/O模块实现系统的输入输出功能,分为键盘模块、终端模块。4、磁盘管理模块:磁盘管理模块是系统对磁盘的管理,可分为磁盘驱动模块、磁盘分区模块。5、文件模块:设计实现一个文件系统,并对文件实现增删改查的功能,分为文件系统、文件创建、文件读写、文件删除。图3-1功能模块图3.2功能设计2.3.1加载模块概要设计加载模块部分可大体上分为三部分,引导扇区模块、Loader模块、内核模块。引导扇区模块负责引导存放在磁盘的其他部分的程序,用于加载Loader。装入内存后,即开始执行该引导程序段,其主要功能是完成操作系统的自检并将控制权交给操作系统。由于引导扇区空间有限,将不必要的工作交给Loader,负责用于过渡将内核加载入内存。跳入保护模式。内核模块从实模式进入保护模式,当计算机向扇区交出控制权后,所有的后续功能部分都在内核中实现。2.3.2进程模块概要设计进程模块中大体可包含三部分,进程创建模块、进程调度模块、进程通信模块。进程创建模块负责在系统中创建进程。进程调度模块实现系统调度,由时钟中断处理进程启动,为系统添加几个进程,实现优先级调度。通过不同的延时时间体现调度效果,并输出进程调度的情况。引入进程表。定义进程提。实现特权级的转换。进程通信模块为进程增加了消息机制,并输出消息内容。2.3.3I/O模块概要设计I/O模块中包含两部分,键盘模块、终端模块。键盘模块获取用户在按下按键时获得的扫描码,对获取的扫描码进行解析,并将结果输出到屏幕上。终端模块通过合理的分割显存,将不同的显示内容隔离存储,从而实现多终端相互切换等效果。2.3.4磁盘管理模块概要设计磁盘管理模块有两部分组成,分别是磁盘驱动模块和磁盘分区模块。通过磁盘驱动实现操作系统对磁盘的直接控制。磁盘分区模块对现有磁盘进行合理分区,实现磁盘空间有效合理化管理。2.3.5文件模块概要设计文件模块中包含了四部分,文件系统、文件创建、文件读写、文件删除。为操作系统设计一个文件系统,对计算机中的文件数据进行有规律的存储。合理利用有限的空间。并实现对文件最基础的添加、删除、修改等一系列的操作。第4章详细设计4.1系统描述在计算机中,操作系统是其最基本也是最为重要的基础性系统软件。从计算机用户的角度来说,计算机操作系统体现在其提供的各项服务;从程序员的角度来说,其主要是指用户登录的界面或者接口;如果从设计人员的角度来说,就是指各式各样模块和单元之间的联系。事实上,全新操作系统的设计和改良的关键工作就是对体系结构的设计,经过几十年以来的发展,计算机操作系统已经由一开始的简单控制循环体发展成为较为复杂的分布式操作系统,再加上计算机用户需求的愈发多样化,计算机操作系统已经成为既复杂而又庞大的计算机软件系统之一。本系统以i386为架构,在认真调研和分析了操作系统的应用现状之后,根据操作系统需要实现的基本功能需求,做出了积极的设计方案。在新的操作模式和资源调度上,力争能各个资源板块的使用效率和使用程度达到一个最优的调整。4.2系统结构系统结构图如图4-1所示。本系统的设计过程完全在Linux系统上进行,使用Bochs虚拟机,gcc、nasm、make等编译环境。参考借鉴于Linux内核。系统过程为虚拟设备上电启动,BIOS自检在7C00处找到引导扇区程序,系统进入到实模式,实模式加载完成后执行加载Loader的程序并跳转到保护模式,将Loader作为中转加载内核,并实现到内核的跳转,从此正式进入操作系统的核心部分,创建进程,将信息输出到终端中,输出进程的通信内容,对文件进行操作。图4-1总体结构图加载模块中包括引导扇区模块、Loader模块、内核模块。进程模块包括进程创建模块、进程调度模块、进程通信模块。I/O模块键盘模块、终端模块。磁盘管理模块磁盘驱动模块、磁盘分区模块。文件模块文件系统、文件创建、文件读写、文件删除。4.3加载模块本系统的加载模块部分可大体上分为三部分,引导扇区模块、Loader模块、内核模块。引导扇区模块不依赖于其他软件实现在裸机上运行,负责引导存放在磁盘的其他部分的程序,用于加载Loader。装入内存后,即开始执行该引导程序段,其主要功能是完成操作系统的自检并将控制权交给操作系统。Loader模块由于引导扇区空间有限,将不必要的工作交给Loader,负责用于过渡将内核加载入内存。跳入保护模式。正常情况下CPU是工作在实模式状态,经过某种机制之后,才进入保护模式。计算机在保护模式下有着强大的寻址能力。为32位操作系统提供了硬件保障。内核模块从实模式进入保护模式,当计算机向扇区交出控制权后,所有的后续功能部分都在内核中实现。除部分中断由汇编实现外,其余部分都由C语言实现。4.3.1引导扇区模块引导扇区就是,当计算机启动电源,会进行上电自检,寻找启动盘;计算机会检测磁盘的0面0磁道1扇区,如果发现是以0xAA55结束,同时还有一段少于512字节的执行码的,这段少于512字节的执行码就是引导扇区。当BIOS找到引导扇区后,会将这512字节装载到,内存地址0000:7c00处,跳转到0000:7c00处,清屏将控制权交给这段引导代码。设置背景及字符颜色,调整终端大小,在显示器显示字符串BootingReady表示已启动引导扇区,引导扇区实现了从BIOS固有程序的控制,转移到操作系统控制的一个过程。引导扇区模块流程图如图4-2所示。图4-2引导扇区模块流程图4.3.2Loader模块Loader模块作用是承接引导扇区,因为引导扇区有512字节的限制,所以无法完成全部功能,所以一部分的功能转移到了Loader当中,Loader用于过度将内核加载内存当中,并跳入保护模式。当内存加载到内核当中之后才相当于真正的进入了操作系统的核心部分。图4-3Loader模块流程图在屏幕上显示Loading字符串,在磁盘中寻找kernel.bin,每读取一个扇区就在屏幕上打印一个‘.’字符,如果找到将kernel.bin装载内存中,移交可控制权并在屏幕显示Ready。4.3.3内核模块内核是一个操作系统的核心部分所在,后续所有的程序部分都在内核中得到扩展,内核模块中只针对kernel.asm文件中实现的部分进行说明。把esp(栈指针寄存器)从Loader中挪到kernel,在cstart函数中改变gdt_ptr,指向新的GDT描述符。屏蔽当前中断,置EOI位,调用中断处理程序,并恢复当前中断。设置一些常见异常。让栈顶指向ELF,堆栈中从顶向下依次是:EIP(存储CPU要读取指令的地址)、CS(代码段寄存器)、EFLAGS(系统标志以及控制标志),添加系统调用。4.4进程模块进程创建模块负责在系统中创建进程。进程调度模块实现系统调度,由时钟中断处理进程启动,为系统添加几个进程,实现优先级调度。通过不同的延时时间体现调度效果,并输出进程调度的情况。引入进程表。定义进程提。实现特权级的转换。进程通信模块为进程增加了消息机制,并输出消息内容。实现IPC(进程间通信)需要实现intSYSVEC软中断和sys_call()函数,并通过实现msg_send()(消息发送)和msg_receive()(消息接收)函数进行信息的传递。4.4.1进程创建模块创建进程结构体s_proc,regs(保存在堆栈中的进程寄存器)、ldt_sel(gdt选择器的基准)、ldts[LDT_SIZE](代码和数据的局部描述符)、ticks(标记)、priority(优先级)、pid(进程id)、p_name[16](进程名)、nr_tty。在main.c(内核主函数入口文件)中初始化进程表,填充GDT中进程LDT的描述符,用init_prot()函数,填充TSS以及对应的描述符。在global.c中声明一个进程表。进程创建模块流程图如图4-4所示。图4-4进程创建模块流程图进程创建过程,先初始化进程体,再初始化GDT中的TSS和LDT两个描述符,准备进程表完成对进程的创建。4.4.2进程调度模块打开时钟中断,设置EOI让中断多次发生,编辑时钟中断处理程序,实现进程的现场保护和恢复。通过时间片来实现进程的切换和进程的调度。为系统添加多个进程,通过时钟中断处理程序,分片执行,实现系统的多进程。实现简单的系统调用。通过get_ticks()函数来实现延时函数的效果。通过在proc.c(进程管理)文件中的schedule()函数实现了对不同优先级进程的进程调度。进程调度模块流程图如图4-5所示。图4-5进程调度模块流程图4.4.3进程通信模块本系统中实现的通信是进程间的异步通信。分别通多sys_sendrec()函数,把SEND消息给msg_send()函数处理,把RECEIVE消息给msg_receive()函数处理。编写assert()函数,为用户提供相应的错误提示,assertion_failure()函数实现了,将错误发生的位置打印出来的功能。通过block()函数阻塞进程,通过unblock()函数解除进程阻塞,通过deadlock()函数判断消息发送可能出现的死锁。在schedule()函数中增加了消息机制的进程调度。4.4I/O模块I/O操作可以有多种方式,比如DIO(DirectI/O),AIO(AsynchronousI/O,异步I/O),Memory-MappedI/O(内存映射I/O)等,不同的I/O方式有不同的实现方式和性能,在不同的应用中可以按情况选择不同的I/O方式。4.4.1键盘模块本系统通过扫描码来处理键盘输入,扫描码的对应关系0x01是ESC按键,0x02-0x0B是数字1到9和0,即是主键盘部分从左到右,从上到下依次增加可得出主键盘部分按键相应的扫描码。从0x3B到0x44为F1到F10扫描码。从0x45开始小键盘和功能按键扫描码。在本系统中,键盘支持的是Scancodeset2,考虑到TX键盘的程序兼容性,将其转化为Scancodeset1。扫描码是一些数字,在知道按键对应的扫描码后,通过整合扫描码,以扫描码为下标,对应的元素是相应的字符,在keymap.h头文件中建立一个无符号整型数组keymap[NR_SCAN_CODES*MAP_COLS],NR_SCAN_CODES对应的就是当前键盘最先按下的按键的扫描码,如扫描码是0x10可判断按下按键为q,可知结果是小写字母q,如获得扫描码结果为0x20x12可判断,当前为在按下左shift的情况下按下e按键,可知结果是大写字母E。但同时有一个问题在用户按下多个按键的时候,会产生多个中断,这样就很难区分用户想要输入的到底是什么,这个时候在程序中是通过建立缓冲区,使keyboard_handler()函数将扫描码放入缓冲区,键盘缓冲区结构体s_kb在keyboard.h中实现,结构体有四个成员分别是,p_head(指向缓冲区中下一个空暇位置)、p_tail(指向键盘任务应处理的字节)、count(缓冲区中共有多少字节)、buf[KB_IN_BYTES](缓冲区),然后建立新的任务通过keyboard_read()解析获得的扫描码,在keyboard_read()中分别要分析不同字符按键的输入情况,和组合按键的输入解析情况,通过in_process()函数处理所有以解析码0xE0开头的特殊按键的解析。通过数组存储的扫描码识别当前键盘的输入实施将这些字符输出到当前终端。键盘缓冲区示意图如图4-6所示,键盘扫描流程图如图4-7所示:图4-7键盘扫描流程图键盘扫描过程,当用户按下按键的时候获取到一个对应的扫描码,通过keyboard_handler()函数将扫描码存入缓冲区,在使用keyboard_read()函数解析扫描码,将结果输出到终端上。4.6.2终端模块不同TTY对应的输入设备是同一个键盘,输出在不相同的显示器上,不同TTY对应画面不同,通过显示在显存的不同位置实现。通过简单的端口操作实现此功能。屏幕显示示意图如图4-8所示。本系统只使用最简单的80*25文本模式,在这种模式下,显存的大小为32KB,所使用的范围是0xB8000~0xBFFFF,一个屏幕可以显示25行,每行80个字符。每两个字节代表一个字符,低字节表示的是字符本身,高字节定义字符颜色。字符分为两部分:前背景和后背景。它们各占4位,低三位表示颜色,前景最高位为1,字符颜色会比0位深;后背景最高位为1,字符闪烁。本系统设计了disp_color_str()函数来改变字符的颜色。字符属性位颜色详解如表4-3所示。在终端中显示输入光标跟随键盘输入的每一个字符。通过使用disable_int()和enable_int()函数打开关闭中断中用out_byte()使用相应的几组数据达到光标输入跟随字符的效果。在tty.c中使用in_process()函数,通过设置StartAddressHighRegister和StartAddressLowRegister重新设置显示开始地址,实现了滚屏的功能,同时会检测当前按键是否是Shift+↑,如果是,则滚动屏幕至80*15处,就是向上滚动15行。设计了s_tty(终端)和s_console(控制台)的两个结构体。结构体s_tty,in_buf[TTY_IN_BYTES](TTY输入缓冲区)、p_inbuf_head(指向缓冲区中下一个空闲位置)、p_inbuf_tail(指向键盘任务应处理的键值)、inbuf_count(缓冲区中已经填充了多少)。结构体s_console,current_start_addr(当前显示到了什么位置 */)、original_addr(当前控制台对应显存位置)、v_mem_limit(当前控制台占的显存大小)、cursor(当前光标位置)。在TTY任务中执行一个循环,这个循环将轮询每一个TTY,处理它的亊件,包括从键盘缓冲区读取败据、显示字符等内容。有以下几点:并非每轮询到某个TTY时,全部亊件都会发生,只有当某个TTY对应的控制台是当前控制台时,它才可以读取键盘缓冲区。我们应该把键盘和显示器算做毎一个TTY的一部分,它们是公用的。终端通过调用init_tty()函数初始化多终端,通过in_process()函数设置开始地址,并开始检测屏幕滚动,通过disp_color_str()修改字符颜色。终端流程图如图4-9所示。图4-9终端流程图4.5磁盘管理模块实现了一个简单的文件系统,建立在一个真正意义上的磁盘上。通过磁盘驱动程序实现对磁盘的直接操作。对磁盘进行分区管理。4.5.1磁盘驱动模块磁盘驱动程序作用在于隐藏硬件细节,向上层进程提供统一接口。进程通信通过收发消息来实现相互通信,驱动程序的接口同样是消息。定义驱动程序接收什么消息,就是定义了驱动程序的接口。通过hd.c(磁盘管理程序)中的task_hd()是驱动程序的主体;init_hd()从物理地址0x475(BIOS指定)处获取系统磁盘数量,然后指定hd_handler()为磁盘的中断处理程序,打开主8259A,hd_identify()函数获取磁盘参数,并调用print_identify_info()函数打印部分磁盘参数。磁盘驱动模块流程图如图4-10所示。图4-10磁盘驱动模块流程图4.5.2磁盘分区模块让系统一下把一整块磁盘用完,又浪费,又不清晰。于是对系统进行了分区处理。设计了磁盘分区表,磁盘状态、起始磁头号、起始扇区号、起始柱面号的低8位、分区类型、结束磁头号、结束扇区号、结束柱面号低8位、起始扇区的LEA、扇区数目。把虚拟机系统下的磁盘分成一个主分区和一个扩展分区,扩展分区中又分成五个逻辑分区。将分区类型修改为99h,并设置可启动标志。这种分区形似,就像一个链表,链表的结点就是扩展分区的分区表,每个结点有两个表项,分别是前一个表项描述一个普通分区,下一个表项指向下一个结点。并对磁盘进行编号,主盘是hd0,它的主引导扇区对应四个分区分别是hd1,hd2,hd3,hd4。每个扩展分区最多又有16个逻辑分区,用字符a~p表示,所以逻辑分区的设备号即从hd1a开始增长。在磁盘驱动程序中遍历所有分区,并将分区打印出来。磁盘分区模块流程图如图4-11所示。图4-11磁盘分区模块流程图4.6文件模块在这一个模块中,要为系统编写了一个文件系统。文件系统所指的是,用于存储和组织计算机文件数据的一种方式。合理的利用磁盘有限的空间,设计对文件的添加、删除、修改等操作。4.6.1文件系统在磁盘驱动的基础上,为磁盘规划一定的格式,行成相应的数据结构,定义三个结构体,分别是。结构体super_block(超级块)、结构体inode和结构体dir_entry(目录项)。超级块中记录了,文件系统的标识,文件系统最多允许有多少个i-node,inode_array占用多少扇区,文件系统总共有多少扇区,inode-map占用多少扇区,sector-map占用多少扇区,第一个数据扇区的扇区编号是多少,根目录的i-node号是多少。Inode中成员表示了,文件的起始位置,总扇区数,文件大小等。结构体dir_entry用于索引目录。在main.c中添加task_fs()函数,调用init_fs()函数来初始化文件系统,再调用mkfs()函数来创建文件系统。mkfs()函数中实现如下功能,向磁盘驱动索取ROOT_DEV的起始扇区和大小,建立超级块,建立inode-map,建立sector-map,写入inode_array,建立根目录文件。文件系统流程图如图4-12所示。图4-12文件系统流程图4.6.1文件创建想要对文件进行修改删除等操作,就需要有一个文件才能进行相应的操作,这就需要在文件系统的基础上进行文件的创建。文件的创建就需要实现几个系统调用分别为open(),write(),read(),close()等。同时文件从文件系统上获取到相应的接口,我们需要创建文件描述的格式来存储这些信息,定义了结构体file_desc。open()函数其实实现的就是向文件系统发送一个OPEN的消息,同时还设计了do_opne()函数来专门处理OPEN消息,并返回进程表中的一个索引。接着调用create_file()函数来真正意义上的创建一个文件,在这之中还是用了,alloc_imap_bit()函数在i-node中进行分配即确定了文件的索引位置,alloc_smap_bit()函数在sector-map中分配多位即对文件分配了扇区空间,new_inode()函数在inode_array中分配了一个i-node,new_dir_entry()函数在相应的目录中写入目录项。文件创建流程图如图4-13所示。图4-13文件创建流程图4.6.2文件读写同样的文件读写也是需要向文件系统发送,READ和WRITE的消息来实现文件的读写操作。这两个信息的处理由do_rdwt()函数来实现。实现了read()和write()系统调用。文件读写流程图如图4-14所示。图4-14文件读写流程图4.6.4文件删除文件删除就是创建文件的逆过程,就需要删除inode-map中相应的位,释放sector-map中相应的位,删除根目录中的目录项。inode_array中相应的i-node是不需要释放的,因为在释放inode-map的时候inode_array的对应位已经被标记为未使用。用户可以通过unlink()函数来实现对文件的删除工作。文件删除流程图如图4-15所示。图4-15文件删除流程图第5章测试让系统稳定的运行也离不开有效的测试阶段,全面的测试可以检测出系统存在的隐患问题,防止在之后的使用中出现问题。本章即针对系统的测试进行相应的描述。5.1单元测试1.扇区引导模块测试扇区引导模块测试用例及结果如图5-1所示。图5-1扇区引导模块测试结果2.引导模块测试引导模块测试用例及结果如图5-2所示。图5-2引导模块测试结果3、内核加载模块测试内核加载模块测试用例及结果如图5-3所示。图5-3内核加载模块测试结果5.2集成测试1.进程状态测试测试A,B,C三个进程的状态。进程状态测试如图5-4,5-5,5-6所示:图5-4进程状态图图5-5进程状态图图5-6进程状态图偏差:无测试结果:进程状态测试结果正确。2.键盘扫描测试字母按键扫描测试输出结果如图5-7所示:图5-7字母按键扫描测试结果图功能按键扫描测试输出结果如图5-8,5-9,5-10所示:图5-8SHIFT功能按键效果图图5-9CAPSLOCK功能按键效果图图5-10NUMLOCK功能按键效果图3.终端切换测试终端切换测试结果如图5-11,5-12所示:图5-11终端切换效果图图5-12终端切换效果图4、屏幕滚动对比测试通过shift+↑/↓实现屏幕滚动,效果对比如图5-13,5-14所示:图5-13屏幕滚动对比效果图图5-14屏幕滚动对比效果图结论本系统,基于i386的简单OS的设计与实现,通过使用汇编语言和C语言实现绝大部分的代码。初步实现了操作系统的加载启动,使进程在操作系统中运转,对文件磁盘内存进行了管理。本系统的设计完全在Linux系统上进行,调试运行使用了Bochs虚拟机,编译环境使用nasm、gcc、make等。大部分功能性实现参考借鉴于Linux内核。设计了引导扇区和用于加载内核的Loader。实现了进程和系统调用。检测键盘的输入并将内容显示在显示器上,并实现多终端切换,实现了输入输出调用。实现了进程间的通信。实现了文件管理。引导扇区模块不依赖于其他软件实现在裸机上运行,负责引导存放在磁盘的其他部分的程序,用于加载Loader。Loader模块由于引导扇区空间有限,将不必要的工作交给Loader,负责用于过渡将内核加载入内存。内核模块从实模式进入保护模式,当计算机向扇区交出控制权后,所有的后续功能部分都在内核中实现。除部分中断由汇编实现外,其余部分都由C语言实现。进程创建模块负责在系统中创建进程。键盘模块中设置键盘中断处理程序,实现键盘输入缓冲区,设计键盘扫描表,根据检测到的输入并显示在终端,实现多终端的切换,实现特殊功能按键的处理。分区模块对磁盘进行分区。在中断模块中大体分为硬中断和软中断。根据程序结构编写Makefile,编译模块实现对代码的编译和链接等操作。实现了预期设计的大部分功能,较完整的实现了本系统。本系统仍然存在部分缺陷,部分功能实现的并不完善,并且没有图形展示的部分,全部由终端代替,没有好的视觉体验,同时缺少了和用户的更多的互动性,和可拓展行。希望在之后的继续设计中可以进行完善。致谢光阴似箭,日月如棱。在这短暂的四年时间里,在我漫长的人生旅途当中是如此的短暂。但是,这短短的四年是最真诚的青春,是最纯真的岁月,是最美丽的大学生活。我的自学能力在这里得长足的提升。这本次的毕业论文中,我发挥出了在学校学习了解到的知识和技能的实际应用,也是我最后一次能够做学校的作业了,我要感谢我的指导老师牛老师,还有我的班主任老师高老师,以及各位任课老师,感谢他们的尊尊教诲,让我知道在社会上懂得怎样去做好自己,端正自己的位置,为社会贡献出我自己的力量。参考文献赛迪智库.我国操作系统产业生态报告[N].中国计算机报,2018-06-18.008.刘鲁昊.Linux操作系统探讨[J].计算机产品与流通,2019(12):114.博韦,西斯特等.深入理解Linux内核[M].中国电力出版社,2007.30-230CalumTMcHale,JoanneECecil,AnitaHLaidlaw.Ananalysisofdirectlyobservedweightcommunicationprocessesbetweenprimarycarepractitionersandoverweightpatients[J].PatientEducationandCounseling,2019,102(12).ZaheerKhan,VivekSoundararajan,AmirShoham.Globalpost-mergeragility,transactivememorysystemsandhumanresourcemanagementpractices[J].HumanResourceManagementReview,2020,30(1).McHaleCalumT,CecilJoanneE,LaidlawAnitaH.Ananalysisofdirectlyobservedweightcommunicationprocessesbetweenprimarycarepractitionersandoverweightpatients.[J].Patienteducationandcounseling,2019,102(12).邱瑞阳.基于NiosⅡ的变压器声音采集系统设计及实现[D].成都理工大学,2013.顾舒欣.嵌入式票据影像处理仪软件设计[D].浙江大学,2006.张东,卫一芃.嵌入式实时操作系统中虚中断的设计与实现[J].信息通信,2018(04):134-135.吴强.操作系统实验课程建构主义教学方法研究[J].绍兴文理学院学报(自然科学),2010,30(01):77-80.张桐.嵌入式实时数据库关键技术研究[J].通讯世界,2015(14):201-202.刘峥嵘.Linux嵌入式化技术研究[D].电子科技大学,2005.包瑞琳.FishOs文件系统的设计与实现[D].中国石油大学(华东),2016.王娟.新型电子文件保险箱的设计与实现[D].电子科技大学,2012.陈云龙,曲波.小型微内核操作系统内核模型设计与实现[J].赤峰学院学报(自然科学版),2011,27(08):58-59.谢宇枫.硬盘主引导扇区数据保护研究[D].东华大学,2006.成国永.可信加密磁盘的设计与应用[D].北京工业大学,2013.蔡林锋.基于消息队列的分布式SP端短信网关[D].暨南大学,2006.米热古丽·克比尔.计算机操作系统体系结构分析[J].电脑知识与技术,2018,14(33):238-240.附录设计系统部分源代码//终端控制PRIVATEvoidinit_tty(TTY*p_tty);PRIVATEvoidtty_do_read(TTY*p_tty);PRIVATEvoidtty_do_write(TTY*p_tty);PRIVATEvoidput_key(TTY*p_tty,u32key);PUBLICvoidtask_tty(){ TTY* p_tty; init_keyboard(); for(p_tty=TTY_FIRST;p_tty<TTY_END;p_tty++){ init_tty(p_tty); } select_console(0); while(1){ for(p_tty=TTY_FIRST;p_tty<TTY_END;p_tty++){ tty_do_read(p_tty); tty_do_write(p_tty); } }}PRIVATEvoidinit_tty(TTY*p_tty){ p_tty->inbuf_count=0; p_tty->p_inbuf_head=p_tty->p_inbuf_tail=p_tty->in_buf; init_screen(p_tty);}PUBLICvoidin_process(TTY*p_tty,u32key){charoutput[2]={'\0','\0'};if(!(key&FLAG_EXT)){ put_key(p_tty,key);}else{intraw_code=key&MASK_RAW;switch(raw_code){caseENTER: put_key(p_tty,'\n'); break;caseBACKSPACE: put_key(p_tty,'\b'); break;caseUP:if((key&FLAG_SHIFT_L)||(key&FLAG_SHIFT_R)){ scroll_screen(p_tty->p_console,SCR_DN);} break; caseDOWN: if((key&FLAG_SHIFT_L)||(key&FLAG_SHIFT_R)){ scroll_screen(p_tty->p_console,SCR_UP); } break; caseF1: caseF2: caseF3: caseF4: caseF5: caseF6: caseF7: caseF8: caseF9: caseF10: caseF11: caseF12: /*Alt+F1~F12*/ if((key&FLAG_ALT_L)||(key&FLAG_ALT_R)){ select_console(raw_code-F1); } break;default:break;}}}PRIVATEvoidput_key(TTY*p_tty,u32key){ if(p_tty->inbuf_count<TTY_IN_BYTES){ *(p_tty->p_inbuf_head)=key; p_tty->p_inbuf_head++; if(p_tty->p_inbuf_head==p_tty->in_buf+TTY_IN_BYTES){ p_tty->p_inbuf_head=p_tty->in_buf; } p_tty->inbuf_count++; }}PRIVATEvoidtty_do_read(TTY*p_tty){ if(is_current_console(p_tty->p_console)){ keyboard_read(p_tty); }}PRIVATEvoidtty_do_write(TTY*p_tty){ if(p_tty->inbuf_count){ charch=*(p_tty->p_inbuf_tail); p_tty->p_inbuf_tail++; if(p_tty->p_inbuf_tail==p_tty->in_buf+TTY_IN_BYTES){ p_tty->p_inbuf_tail=p_tty->in_buf; } p_tty->inbuf_count--; out_char(p_tty->p_console,ch); }}PUBLICvoidtty_write(TTY*p_tty,char*buf,intlen){char*p=buf;inti=len;while(i){out_char(p_tty->p_console,*p++);i--;}}PUBLICintsys_write(char*buf,intlen,PROCESS*p_proc){tty_write(&tty_table[p_proc->nr_tty],buf,len);return0;}//键盘特殊按键检测效果PRIVATEKB_INPUT kb_in;PRIVATE int code_with_E0;PRIVATE int shift_l; /*lshiftstate*/PRIVATE int shift_r; /*rshiftstate*/PRIVATE int alt_l; /*laltstate */PRIVATE int alt_r; /*rleftstate */PRIVATE int ctrl_l; /*lctrlstate */PRIVATE int ctrl_r; /*lctrlstate */PRIVATE int caps_lock; /*CapsLock */PRIVATE int num_lock; /*NumLock */PRIVATE int scroll_lock; /*ScrollLock */PRIVATE int column;PRIVATEint caps_lock; /*CapsLock */PRIVATEint num_lock; /*NumLock */PRIVATEint scroll_lock; /*ScrollLock */PRIVATEu8 get_byte_from_kbuf();PRIVATEvoidset_leds();PRIVATEvoidkb_wait();PRIVATEvoidkb_ack();PUBLICvoidkeyboard_handler(intirq){ u8scan_code=in_byte(KB_DATA); if(kb_in.count<KB_IN_BYTES){ *(kb_in.p_head)=scan_code; kb_in.p_head++; if(kb_in.p_head==kb_in.buf+KB_IN_BYTES){ kb_in.p_head=kb_in.buf; } kb_in.count++; }}PUBLICvoidinit_keyboard(){ kb_in.count=0; kb_in.p_head=kb_in.p_tail=kb_in.buf; shift_l =shift_r=0; alt_l =alt_r=0; ctrl_l =ctrl_r=0; caps_lock=0; num_lock=1; scroll_lock=0; set_leds();put_irq_handler(KEYBOARD_IRQ,keyboard_handler);/*设定键盘中断处理程序*/enable_irq(KEYBOARD_IRQ);/*开键盘中断*/}PUBLICvoidkeyboard_read(TTY*p_tty){ u8 scan_code; char output[2]; int make; /*1:make;0:break.*/ u32 key=0;/*用一个整型来表示一个键。比如,如果Home被按下, *则key值将为定义在keyboard.h中的'HOME'。 */ u32* keyrow; /*指向keymap[]的某一行*/ if(kb_in.count>0){ code_with_E0=0; scan_code=get_byte_from_kbuf(); /*下面开始解析扫描码*/ if(scan_code==0xE1){ inti; u8pausebrk_scode[]={0xE1,0x1D,0x45, 0xE1,0x9D,0xC5}; intis_pausebreak=1; for(i=1;i<6;i++){ if(get_byte_from_kbuf()!=pausebrk_scode[i]){ is_pausebreak=0; break; } } if(is_pausebreak){ key=PAUSEBREAK; } } elseif(scan_code==0xE0){ scan_code=get_byte_from_kbuf(); /*PrintScreen被按下*/ if(scan_code==0x2A){ if(get_byte_from_kbuf()==0xE0){ if(get_byte_from_kbuf()==0x37){ key=PRINTSCREEN; make=1; } } } /*PrintScreen被释放*/ if(scan_code==0xB7){ if(get_byte_from_kbuf()==0xE0){ if(get_byte_from_kbuf()==0xAA){ key=PRINTSCREEN; make=0; } } } /*不是PrintScreen,此时scan_code为0xE0紧跟的那个值.*/ if(key==0){ code_with_E0=1; } } if((key!=PAUSEBREAK)&&(key!=PRINTSCREEN)){ /*首先判断MakeCode还是BreakCode*/ make=(scan_code&FLAG_BREAK?0:1); /*先定位到keymap中的行*/ keyrow=&keymap[(scan_code&0x7F)*MAP_COLS]; column=0; intcaps=shift_l||shift_r; if(caps_lock){ if((keyrow[0]>='a')&&(keyrow[0]<='z')){ caps=!caps; } } if(caps){ column=1; } if(code_with_E0){ column=2; } key=keyrow[column]; switch(key){ caseSHIFT_L: shift_l=make; break; caseSHIFT_R: shift_r=make; break; caseCTRL_L: ctrl_l=make; break; caseCTRL_R: ctrl_r

温馨提示

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

评论

0/150

提交评论