使用开源软件-自己动手写操作系统WriteOS_图文(精)
写一个简易嵌入式操作系统
写一个简易嵌入式操作系统在了解了操作系统的原理和工作后,我们可以自己写一个简易的嵌入式操作系统,下面由店铺为大家整理了写一个简易嵌入式操作系统的相关知识,希望对大家有帮助!写一个简易嵌入式操作系统概述1.首先确定CPU,在这里为了简单,就选用嵌入式的CPU,比如arm系列,之所以用RISC(简单指令集)类型的CPU,其方便之处是没有实模式与保护模式之分,采用线性的统一寻址,也就是不需要进行段页式内存管理,还有就是芯片内部集成了一些常用外设控制器,比如以太网卡,串口等等,不需要像在PC机的主板上那么多外设芯片2.确定要实现的模块和功能,为了简单,只实现多任务调度(但有限制,比如最多不超过10),实现中断处理(不支持中断优先级),不进行动态SHELL交互,不实现动态模块加载,不实现fork之类的动态进程派生和加载(也就是说要想在你的操作系统上加入用户程序,只能静态编译进内核中;不支持文件系统,不支持网络,不支持PCI,磁盘等外设(除了支持串口,呵呵,串口最简单嘛),不支持虚拟内存管理(也就是说多任务中的每个进程都可以访问到任何地址,这样做的话,一个程序死了,那么这个操作系统也就玩完了)3.确定要使用的编译器,这里采用GCC,文件采用ELF格式,当然,最终的文件就是BIN格式,GCC和LINUX有着紧密的联系,自己的操作系统,需要C库支持和系统调用支持,所以需要自己去裁剪库,自己去实现系统调用4.实现步骤:首先是CPU选型,交叉编译环境的建立,然后就是写BOOTLOADER,写操作系统通过以上4点的学习一个简单的嵌入式操作系统准备工作就差不多做好了。
写一个简易嵌入式操作系统详解程序本质的剖析写操作系统这个高端大气上档次的工作肯定要有一些铺垫了,最必须的就是对你写的程序的了解,也许你会说,我写的程序,我还能不理解吗,但是这次咱么要从寄存器角度分析。
咱们首先从类比学习开始,咱们先来理解中断,对于中断,学习单片机的小朋友们肯定很理解,咱么来一起回顾下,单片机是怎么用硬件实现中断的(更为具体的说明在Cortex-M3权威指南-carpter9中断的具体行为)其实中断就是多任务的环境了,只不过这个多任务环境只能有两个任务(在只有一个中断的前提下),那么只要咱么能模拟出来中断,那实现自己的操作系统也是很简单的呢。
os操作系统
1.2 操作系统的发展过程
1.2.1 无操作系统时的计算机系统 1.2.2 单道批处理系统(simple batch processing) 1.2.3 多道批处理系统(multiprogramming system) 1.2.4 分时系统(time-sharing system) 1.2.5 实时系统(real-time system)
– 通常按时间片(time slice)分配:各个程序在CPU上执行的 轮换时间。
20
分时的定义
把计算机的系统资源(尤其是CPU时间)进行时 间上的分割,每个时间段称为一个时间片(time slice),每个用户依次轮流使用时间片。
• 抢先式和非抢先式(preemptive & nonpreemptive):出让CPU是OS强迫或程序 主动
– CPU等待用户:计算前,手工装入纸带或卡片;计 算完成后,手工卸取纸带或卡片;CPU利用率低;
9
• 主要矛盾
– 计算机处理能力的提高,手工操作的低效率 (造成浪费);
– 用户独占全机的所有资源;
• 提高效率的途径
– 专门的操作员,批处理
10
➢ 联机输入输出方式 (On-Line I/O)
➢ 脱机输入输出方式 (Off-Line I/O) 外围机控制I/O, 减少CPU空闲时间 高速磁带、磁盘
• 缺点:
– 用户交互性差:整个作业完成后或中间出错时, 才与用户交互,不利于调试和修改;
– 作业平均周转时间长:短作业的周转时间显著增 长;
18
多道批处理系统的问题
• 处理机 • 内存 • I/O设备 • 文件 • 作业 各种类型
19
1.2.4 分时系统
70年代中期至今,用户的需求
自己动手写CPUOpenMIPS教学版讲解主要内容
指令wishbone接口 OpenMIPS 数据wishbone接口
iwishbone
dwishbone
m0
WB_CONMAX
s0
s1
s2
s3
SDRAM Controller
UART Controller
GPIO Controller
FLASH Controller
•《自己动手写CPU》OpenMIPS教 学版讲解主要内容
四 OpenMIPS教学版的文件组织
asm_test
包括所有的测试例程,其组织方式是参照《10天实现 处理器——OpenMIPS成长记》一文,按照“天”来组织, 比如Day2文件夹中存放的是《10天实现处理器—— OpenMIPS成长记》一文中第二天对应的测试例程,当 然所有的测试例程都可以在最终的OpenMIPS中进行测 试
•《自己动手写CPU》OpenMIPS教 学版讲解主要内容
四 OpenMIPS教学版的文件组织
rtl
所有OpenMIPS的源代码文件在该文件夹下,包括
流水线文件iu.vhd 除法模块div.vhd 寄存器文件Reg 顶层文件OpenMIPS.vhd 宏定义文件stdlib.vhd
•《自己动手写CPU》OpenMIPS教 学版讲解主要内容
一 OpenMIPS项目简介
OpenMIPS是采用具有哈佛结构的32位标量处理器,兼容 MIPS32体系结构,这样可以使用现有的MIPS编译环境。
具有以下特点:
五级整数流水线,分别是:取指、译码、执行、访存、 回写
哈佛结构,分开的指令、数据接口
32个32位整数寄存器
大端模式
向量化异常处理,支持精确异常处理
•《自己动手写CPU》OpenMIPS教 学版讲解主要内容
OS操作系统课程实验指导书附运行截图
OS操作系统课程实验指导书附运行截图实验1使用动态优先权的进程调度算法的模拟1、实验目的(1)加深对进程概念的理解(2)深入了解系统如何组织进程,创建进程(3)进一步认识如何实现处理机调度2、实验内容(1)实现对N个进程采用动态优先权优先算法的进程调度。
(2)每个用来标识进程的进程控制块PCB用结构来描述,包括以下字段:进程标识数ID。
进程优先数PRIORITY,并规定优先数越大的进程,其优先权越高。
进程已占用的CPU时间CPUTIME。
进程还需占用的CPU时间ALLTIME。
当进程运行完毕时,ALLTIME变为0。
进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK 个时间片后,将进入阻塞状态。
进程被阻塞的时间BLOCKTIME,表示已阻塞的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。
进程状态STATE。
队列指针NEXT,用来将PCB排成队列。
(3)优先数改变的原则:进程在就绪队列中停留一个时间片,优先数加1。
进程每运行一个时间片,优先数减3。
(4)假设在调度前,系统中有5个进程,它们的初始状态如下:ID 0 1 2 3 4PRIORITY 9 38 30 29 0CPUTIME 0 0 0 0 0ALLTIME 3 3 6 3 4STARTBLOCK 2 -1 -1 -1 -1BLOCKTIME 3 0 0 0 0STATE ready ready ready ready ready(5)为了清楚的观察各进程的调度过程,程序应将每个时间片内的情况显示出来,参照的具体格式如下:RUNNING PROG:i READY-QUEUE:->id1->id2BLOCK-QUEUE:->id3->id4= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = == = =ID 0 1 2 3 4PRIORITY P0 P1 P2 P3 P4CUPTIME C0 C1 C2 C3 C4ALLTIME A0 A1 A2 A3 A4STARTBLOCK T0 T1 T2 T3 T4BLOCKTIME B0 B1 B2 B3 B4STATE S0 S1 S2 S3 S43、实验结果(给出编写的程序源代码和运行结果的截图)【程序代码】#include#include#define N 5// 进程状态enum STATE { Ready, Run, Block, Finish };// PCB数据结构struct PCB {int id; // 标志数int priority; // 优先数int cpuTime; // 已占CPU时间int allTime; // 还需占CPU时间int blockTime; // 已被阻塞的时间int startBlock; // 开始阻塞时间STATE state; // 进程状态PCB *pre; // PCB的前指针PCB *nxt; // PCB的后指针};int id[N] = {0, 1, 2, 3, 4};int priority[N] = {9, 38, 30, 29, 0};int cpuTime[N] = {0, 0, 0, 0, 0};int allTime[N] = {3, 3, 6, 3, 4};int startBlock[N] = {2, -1, -1, -1, -1};int blockTime[N] = {3, 0, 0, 0, 0};void QuePush(PCB *process, PCB *queHead){process->pre = NULL;process->nxt = queHead->nxt;if (queHead->nxt != NULL) {queHead->nxt->pre = process;}queHead->nxt = process;}void quePop(PCB *process, PCB *queHead){if (process->pre != NULL) {process->pre->nxt = process->nxt;} else {queHead->nxt = process->nxt;}if (process->nxt != NULL) {process->nxt->pre = process->pre;}process->pre = process->nxt = NULL;}void queWalk(PCB *queHead){PCB *pro = queHead->nxt;if (pro == NULL) {printf("(没有进程啦)\");return;}while (pro != NULL){printf("id: %d, priority: %d, cpuTime: %d, alltime: %d,blockTime: %d,state:%d,startblock: %d\", pro->id, pro->priority, pro->cpuTime, pro->allTime, pro->blockTime, pro->state, pro->startBlock);pro = pro->nxt;}}int readyQueNum; // 就绪队列的进程数量PCB readyQueHead; // 就绪队列的头部PCB *readyMaxProcess; // 就绪队列中优先级最高的进程void readyQuePush(PCB *process){readyQueNum ++;process->state = Ready;QuePush(process, &readyQueHead);}PCB* readyQuePop(){readyQueNum --;quePop(readyMaxProcess, &readyQueHead);return readyMaxProcess;}// 每个时间片,更新就绪队列里进程的信息void readyQueUpdate(){int maxPriority = -1;PCB *pro = readyQueHead.nxt;if (pro == NULL) {// 就绪队列没有进程readyMaxProcess = NULL;return;}while (pro != NULL){pro->priority ++;if (pro->priority > maxPriority) {maxPriority = pro->priority;readyMaxProcess = pro;}pro = pro->nxt;}}// 返回就绪队列最高优先级的值int readyMaxPriority(){return readyMaxProcess->priority;}// 查看就绪队列里进程的信息void readyQueWalk(){printf("就绪队列里的进程信息为:\");queWalk(&readyQueHead);}#define EndBlockTime 3 // 进程最长被阻塞时间int blockQueNum; // 阻塞队列的进程数量PCB blockQueHead; // 阻塞队列的头部PCB *blockMaxProcess; // 阻塞队列中优先级最高的进程// 进程插入到阻塞队列void blockQuePush(PCB *process){blockQueNum ++;process->blockTime = 0;process->state = Block;if (process->blockTime != -1) {QuePush(process, &blockQueHead);}}// 优先级最高的进程出列PCB* blockQuePop(){blockQueNum --;quePop(blockMaxProcess, &blockQueHead);return blockMaxProcess;}// 每个时间片,更新阻塞队列里进程的信息void blockQueUpdate(){int maxPriority = -1;PCB *pro = blockQueHead.nxt;while (pro != NULL){pro->blockTime ++;if (pro->blockTime >= EndBlockTime) {PCB *process = pro;pro = pro->nxt;// 阻塞时间到,调入就绪队列blockQueNum --;quePop(process, &blockQueHead); readyQuePush(process);} else if (pro->priority > maxPriority) {// 更新阻塞队列里优先级最高的进程指针maxPriority = pro->priority; blockMaxProcess = pro;pro = pro->nxt;}}}// 查看阻塞队列里进程的信息void blockQueWalk(){printf("阻塞队列里的进程信息为:\"); queWalk(&blockQueHead);}// 初始化数据void initData(){// 初始化就绪队列和阻塞队列readyQueNum = blockQueNum = 0; readyMaxProcess = blockMaxProcess = NULL;readyQueHead.pre = readyQueHead.nxt = NULL; blockQueHead.pre = blockQueHead.nxt = NULL; // 初始化进程进入就绪队列int i, maxPriority = -1;for (i = 0; i < N; i ++){// 分配一个PCB的内存空间PCB *pro = (PCB *)malloc(sizeof(PCB));// 给当前的PCB赋值pro->id = id[i];pro->priority = priority[i];pro->cpuTime = cpuTime[i];pro->allTime = allTime[i];pro->blockTime = blockTime[i];pro->startBlock = startBlock[i];if (pro->allTime > 0) {// 插入到就绪队列中readyQuePush(pro);// 更新就绪队列优先级最高的进程指针if (pro->priority > maxPriority) {maxPriority = pro->priority; readyMaxProcess = pro;}}}}// 模拟cpu执行1个时间片的操作void cpuWord(PCB *cpuProcess){cpuProcess->priority -= 3;if (cpuProcess->priority < 0) {cpuProcess->priority = 0;}cpuProcess->cpuTime ++;cpuProcess->allTime --;// 显示正执行进程的信息:printf("CPU正执行的进程信息为:\");printf("id: %d, pri: %d, alltime: %d\", cpuProcess->id,cpuProcess->priority, cpuProcess->allTime);}int main(){int timeSlice = 0; // 模拟时间片int cpuBusy = 0; // 模拟cpu状态PCB *cpuProcess = NULL; // 当前在cpu执行的进程initData(); // 初始化// 模拟进程调度while (1){if (readyQueNum == 0 && blockQueNum == 0 && cpuBusy == 0) { // 就绪队列、阻塞队列和cpu无进程,退出break;}if (cpuBusy == 0) {// cpu空闲,选择一个进程进入cpuif (readyQueNum > 0) {// 选择绪队列优先级最高的进程cpuProcess = readyQuePop();} else {// 就绪队列没有进程,改为选择阻塞队列优先级最高的进程cpuProcess = blockQuePop();}cpuProcess->cpuTime = 0;cpuProcess->state = Run;cpuBusy = 1;cpuProcess->startBlock --;}timeSlice ++;printf("\第%d个时间片后:\", timeSlice);// 模拟cpu执行1个时间片的操作cpuWord(cpuProcess);if (cpuProcess->allTime == 0) {cpuProcess->state = Finish;// 释放已完成进程的PCBfree(cpuProcess);cpuBusy = 0;}// 更新就绪队列和阻塞队列里的进程信息blockQueUpdate();readyQueUpdate();// 查看就绪队列和阻塞队列的进程信息readyQueWalk();blockQueWalk();if ((cpuProcess -> startBlock) > 0) {blockQuePush(cpuProcess);cpuProcess = readyQuePop();}else {if (cpuBusy == 1 && readyQueNum > 0 && cpuProcess->priority < readyMaxPriority()){readyQuePush(cpuProcess);cpuProcess = readyQuePop();}}}printf("\模拟进程调度算法结束2145115 刘成路\");return 0;}【运行截图】实验2使用动态分区分配方式的模拟1、实验目的(1)了解动态分区分配方式中使用的数据结构和分配算法(2)加深对动态分区存储管理方式及其实现过程的理解。
自己动手制作操作系统
自己动手写操作系统(从引导到启动保护模式)自由软件社区是一个充满自由和梦想的地方,在10余年的时间里它创造了一个又一个奇迹。
然而,这些奇迹的创造者不只是Stallman,也不只是Linus Torvalds,而是活跃在世界各地的不计其数的开发人员。
在使用各种功能强大的自由软件时,我总会对其开发者充满崇敬之情,期盼有朝一日自己也能成为他们中的一员。
很多对自由社区充满向往之情的人,虽然也想努力融身于其中,但又不知该怎么做。
那么,就请与我们一起从编写一个简单的操作系统开始吧!我们要做的事情有人可能担心自己既没有学过计算机原理,也没有学过操作系统原理,更不懂汇编语言,对C语言也一知半解,能写操作系统吗?答案是没问题。
我将带大家一步一步完成自己的操作系统。
当然如果学一学上述内容再好不过。
首先要明确处理器(也就是CPU)控制着计算机。
对PC而言,启动的时候,CPU都处在实模式状态,相当于只是一个Intel 8086处理器。
也就是说,即使你现在拥有一个奔腾处理器,它的功能也只能是8086级别。
从这一点上来讲,可以使用一些软件把处理器转换到著名的保护模式。
只有这样,我们才可以充分利用处理器的强大功能。
编写操作系统开始是对BIOS控制,取出存储在ROM里的程序。
BIOS是用来执行POST(Power On Self Test,自检)的。
自检是检查计算机的完整性(比如外设是否工作正常、键盘是否连接等)。
这一切完成以后,你就会听到PC喇叭发出一声清脆的响声。
如果一切正常,BIOS就会选择一个启动设备,并且读取该设备的第一扇区(即启动扇区),然后控制过程就会转移到指定位置。
启动设备可能是一个软盘、光盘、硬盘,或者其它所选择的设备。
在此我们把软盘作为启动设备。
如果我们已经在软盘的启动扇区里写了一些代码,这时它就被执行。
因此,我们的目的很明确,就是往软盘的启动扇区写一些程序。
首先使用8086汇编来写一个小程序,然后将其拷贝至软盘的启动扇区。
DIY-给单片机写个实时操作系统内核!
DIY:给单片机写个实时操作系统内核!为了进一步把单片机的潜能发挥到极限,我一直想写个程序把单片机的所有资源都用光,但是如果依照单道程序顺序执行的方式,很难把MCU 的CPU 时间都充分利用,比如使用软件延时函数实际上就是在无谓地消耗着CPU 的时间什么事情都不做,因为CPU 一直在循环等待着条件结束,这相当于函数被阻塞了。
为了更明显地验证这一点,你可以在WINDOWS 下打开VC6.0或其他的C 语言编译器,写段代码如下:#include void main(void){while(1) ;}意思是让CPU 不做事情在等待,你猜,这句代码会消耗掉多少CPU 时间?答案会根据不同机型而不同,如果是单核CPU 的话,这句话会消耗掉CPU 接近100%的时间!如果是双核CPU,则只消耗掉50%左右,因为这段代码只运行在其中一个核,另外一个核还可以做别的事情,截图如下:然后你可以测试下面这几句代码:#include#includevoid main(void){while(1)Sleep(100);}这段代码实际上也是什么都不做,它不断地调用Sleep()函数,让它延时100 毫秒再醒来,然后继续睡觉。
现在你可以再打开任务管理器看一下CPU 时间用了多少,答案是基本不用CPU 时间!!为什么同样地什么事情都不做,差别咋就这么大呢?这是因为使用了Sleep()这个函数是WINDOWS 操作系统为你提供的,调用Sleep()之后WINDOWS 操作系统自动把你这个程序挂起了(就是暂时扔到一边不管),然后让CPU 去执行其他程序,等到时间到了,操作系统再把这段程序恢复继续执行,这样的话CPU 就可以得到充分地利用了,也就是说你可以在一块CPU 里面同时执行多个任务而互不影响!(这里所说的同时并不是同时执行,CPU。
跟大神一起15分钟制作一个属于自己的Linux操作系统
跟大神一起15分钟制作一个属于自己的Linux操作系统!计算机已成为现代人日常工作、学习和生活中必不可少的工具。
操作系统是计算机之魂,作为用户使用计算机的接口,它负责调度执行各个用户程序,使计算机完成特定的任务;作为计算机硬件资源的管理者,它负责协调计算机中各类设备高效地工作。
操作系统的重要性不言而喻,市面上主流的操作系统有Windows、Unix、Linux、Mac OS X。
Linux于1991年由芬兰大学生Linus开发,是一个类Unix的开源版操作系统,主要有以下几个特点:开放式操作系统Linux是一个免费软件,开发者可以自由安装并任意修改软件的源代码,相比Unix的命令行操作,Linux提供了窗口管理系统,相对容易操作,企业可以免费使用Linux,大大降低了成本预算。
强大的硬件支持Linux系统非常容易维护,用户可以集中更新操作系统和所有安装的软件,即安全又高效。
Linux能有效利用系统资源,允许用户针对特定的硬件要求进行安装,允许在旧计算机上安装Linux,从而有助于最佳地利用计算机硬件资源。
安全性高、稳定性强Linux系统下除非用户以root身份登录,否则程序无法更改系统设置和配置,很少出现因为用户误操作导致计算机无法启动的情形。
Linux下载的文件、恶意软件的权限将受到限制,能有效避免病毒的侵入,Windows系统中常见的勒索病毒、蠕虫病毒均无法在Linux下运行。
Linux非常稳定,不易崩溃,Linux能在几年后保持和第一次安装时一样的运行速度。
而Windows的话可能在运行半年后,速度就跟不上了。
Linux系统的成功归功于每个Linux爱好者的贡献,不管是在Linux内核还是开源软件等方面,都为我们后来人提供了一个良好的学习和研究环境。
下面我们就一起来做个小实验:通过裁剪现有Linux系统,根据自己的需要,打造一个属于自己的Linux小系统,让其能够具备Linux的一些常用小功能。
开源onlyofficewindows编译-概述说明以及解释
开源onlyofficewindows编译-概述说明以及解释1.引言1.1 概述本文将介绍如何在Windows系统下编译开源onlyofficewindows。
开源onlyofficewindows是一个功能强大的办公套件,它提供了文档处理、电子表格编辑、演示文稿制作等多种办公功能。
只需按照本文所述步骤进行编译,即可在Windows系统下获得自己定制的onlyofficewindows版本。
在正式介绍编译步骤之前,我们将先了解一下onlyofficewindows的基本概念和功能。
onlyofficewindows是一个开放源代码软件,它允许用户自由地使用、复制、编辑和分发。
它与微软Office套件相似,但更加灵活和易于定制。
通过编译onlyofficewindows,用户可以根据自己的需求添加或修改功能,使其更好地适应工作场景。
本文的结构如下:引言部分介绍了本文的目的和结构;正文部分将详细介绍编译onlyofficewindows的步骤,包括环境准备、代码获取、依赖库安装等;结论部分对本文进行总结,并探讨了开源onlyofficewindows 编译的意义和影响,最后展望了它在未来的发展。
通过阅读本文,读者将了解到如何在Windows系统上编译onlyofficewindows,并能够根据自己的需求进行定制。
在本文的指导下,读者可以轻松地获取并使用onlyofficewindows,享受到强大的办公功能。
同时,通过参与onlyofficewindows的开源社区,读者还能为软件的改进和完善贡献自己的力量。
只要按照本文所述步骤,相信读者可以成功地编译onlyofficewindows,并将其应用于自己的工作和学习中。
1.2 文章结构在文章结构部分,我们将介绍本文的组织结构以及各个章节的内容概要。
通过明确的文章结构,读者可以更好地理解文章的主要内容和阐述思路。
本文的结构分为以下几个部分:1. 引言:在这一部分中,我们将对文章所要讨论的主题进行概述和介绍。
一个操作系统的实现
Verum ipsum factum.──Giambattista Vico1马上动手写一个最小的“操作系统”虽说万事开头难,但有时也未必。
比如说,写一个有实用价值的操作系统是一项艰巨的工作,但一个最小的操作系统或许很容易就实现了。
现在我们就来实现一个小得无法再小的“操作系统”,建议你跟随书中的介绍一起动手来做,你会发现不但很容易,而且很有趣。
1.1准备工作对于写程序,准备工作无非就是硬件和软件两方面,我们来看一下:1.硬件•一台计算机(Linux操作系统1或Windows操作系统均可)•一张空白软盘2.软件•汇编编译器NASMNASM最新版本可以从其官方网站获得2。
此刻你可能会有疑问:这么多汇编编译器中,为什么选择NASM?对于这一点本书后面会有解释。
•软盘绝对扇区读写工具在Linux下可使用dd命令,在Windows下则需要额外下载一个工具比如rawrite3或者图形界面的rawwritewin4。
当然如果你愿意,也可以自己动手写一个“能用就好”的工具,并不是很复杂5。
1实际上Linux并非一种操作系统,而仅仅是操作系统的内核。
在这里比较准确的说法是GNU/ Linux,本书提到的Linux泛指所有以Linux为内核的GNU/Linux操作系统。
GNU经常被人们遗忘,但它的贡献无论怎样夸大都不过分,这不仅仅是因为在你所使用的GNU/Linux中,GNU软件的代码量是Linux内核的十倍,更加因为,如果没有以Richard Stallman为首的GNU项目倡导自由软件文化并为之付出艰辛努力,如今你我可能根本没有自由软件可用。
本书将GNU/Linux简化为Linux,仅仅是为表达方便,绝不是因为GNU这一字眼可有可无。
2NASM的官方网站位于/projects/nasm。
3rawrite可以在许多地方找到,比如/debian/tools/。
4下载地址为/rawwrite。
5我们不需要太强大的软盘读写工具,只要能将512字节的数据写入软盘的第一个扇区就足够了。
开源操作系统
内核
内核
很多操作系统是基于Linux内核来开发的。Linux基金会(Linux社区)负责“Linux内核”官方(Official) 或主干的各款通用版本的开发、发行和维护工作。对基于Linux内核的操作系统的开发者来说,可选择某款Linux 内核版本作为自己操作系统的内核,如果要对主干版本进行修改以形成自己的分支内核版本时,必须将其修改部 分及时反馈给主干版本的维护管理者,取得他们对修改的认可,并在主干Linux内核中登记注册,最终使这个分 支内核版本成为Linux内核大家庭中一员。
XFree86
XFree86是X窗口系统的其中一个实现,自1992年,它一直循着自由发放的开放源代码模式被发展。它主要 的运作平台是Unix类操作系统,包括各版本的UNIX、Linux、BSD、Solaris、Mac OS X、IRIX、OpenVMS及 Cygwin/X等。
由2004年开始,它再不是以GPL软件许可证的形式出现,而是使用XFree86®Project公司所拥有的XFree86 Licenseversion 1.1软件许可证模式发放。现时XFree86仍由XFree86®Project公司负责开发,该公司的主要负 责人是David Dawes。
谢谢观看
简介
简介
开源操作系统(open source operating system),就是公开源代码的操作系统软件,可以遵循开源协议 (GNU)进行使用、编译和再发布。在遵守GNU协议的前提下,任何人都可以免费使用,随意控制软享模式的开发系统
在国际开源操作系统中最著名的一种为“Linux操作系统”,它是一种计算机操作系统的泛称,中文读法大 致为“里纳克斯”。Linux操作系统的内核的名字也是“Linux”。Linux操作系统也是自由软件和开放源代码发 展中最著名的例子。
自己实现一个RTOS《实时操作系统揭秘》(附源码)
⾃⼰实现⼀个RTOS《实时操作系统揭秘》(附源码)新年伊始,将⾃⼰独⽴实现的⼀个⽐较⼩的RTOS源码贴上来,顺便把原理都讲⼀讲,希望对在这块⼯作的朋友有些帮助或者启发⼤家也给点改进的意见和建议。
本系列⽂章的标题叫做《实时操作系统揭秘》第⼀篇前⾔很多⼈对⽼美发明的操作系统顶礼膜拜,捧到了神的地步,市⾯上也充斥着很多有关操作系统的劣质的译作对其关键部分,⼤部都语焉不详,隔靴搔痒让更多的⼈越看越糊涂于是操作系统在⼈们⼼中更加⾼深了其实,操作系统远没有这些⼈想象的那么神秘任务切换,内存管理,⽂件系统,任务间通讯功能,引导程序等模块,就形成了⼀个完整的操作系统内核我们在这⾥就逐⼀剥⼀下操作系统的⽪,把各个模块的原理,以结合代码的形式,抖给⼤家看看让⼤家看清操作系统的⼀些秘密对某些模块,系统功能有兴趣的同学,也可以发邮件给我,我们⼀起研究,共同学习...(注:1,这系列⽂章,都是按照⽬前⼯作中,⼿头项⽬的进度以及涉及到的知识点所写出来的,是个类笔记的东西,是业余时间的⼀个作品2,附注的源码,是个⼈的⼀个⼩作品,⾃⼰给他取了个不响亮的名字:BenOS并且该系统在⾃⼰的Cortex-M3平台测试通过并且运⾏⾃⼰的应⽤没有问题3,BenOS是完全个⼈独⽴实现的没有抄袭任何其他OS的源码)⽂档与源码:第⼆篇任务切换,如何才能得到MM的青睐操作系统最核⼼的功能就是任务切换何为任务切换,为啥要任务切换这个就简单说:引⼊操作系统,就是为了让单个CPU可以运⾏多个任务但是这些任务是并发运⾏的,每个⼩猪吃⼀⼝奶,就让给另⼀个⼩猪吃⼀⼝⼤家轮流来,宏观看起来就像所有的⼩猪都在同时吃奶⼀样任务A正在运⾏,时间该任务B运⾏了,这个时候,操作系统就需要做任务切换于是,操作系统就保存任务A⽬前跑到了哪⼀步,运⾏时候,所有的参数是啥⼦然后在任务B恢复上次运⾏到的位置,并且恢复上次停⽌运⾏时间点的所有参数再打任务B⼀鞭⼦,任务B就像没停⽌过⼀样,开始欢快的跑了。
自己动手写操作系统(一)
软 盘 中。
一
个 I e 8 8 nt l 0 6处 理 器 。也 就 是 说 , 即
使 你 现 在 拥 有 一 个 奔 腾 处 理 器 , 它 的
莓 功 能 也 只 能 是 8 8 级 别 。从 这 一 点 上 06
张 空 软 盘 :它 用 于 存 储 编 写 的 操
式 。
Io 【】 o j n v l。 x f #
l p1 m p o oo :i l opl I
。
j
过 。
这 是 as 86可 以 读 懂 的 一 段 汇 编 程 序 。第 一 个 句 子 指 明 了 程 序 的入 口点 , 声 明 整 个 过 程 从 s a t处 开 始 。 第 二 行 tr 指 明 了 s a t的 位 置 , 说 明 整 个 程 序 要 tr 从 s a t 开 始 执 行 。0 tr 处 xb8 00是 显 存 的 开 始 地 址 。# 表 明 其 后 是 一 个 立 即 数 。 执 行语 句 :
e n虹 磷 矗
s art t :
们 的 目 的 很 明 确 , 就 是 往 软 盘 的 启 动
扇 区写 一些程 序 。 首 先 使 用 808 6汇 编 来 写 一 个 小 程
| l
l
序,然后将 其拷 贝至 软盘 的启动 扇 区。
我 们 要 做 的 事 情
有 人 可 能 担 心 自己 既 没 有 学 过 计 算
II V a # o IO x, xbS 0 0
耋
首 先 要 明 确 处 理 器 ( 就 是 CPU ) 也 控
j 制 着 计 算 机 。 Pc而 言 ,启 动 的 时 候 , 对
编写操作系统之
编写操作系统之键盘交互的实现Version 0.01谢煜波xieyubo@总述一个操作系统必需要具有交互性。
所谓交互性就是指人与计算机之间的一种交流,有两种最基本的交互设备,一是显示器,一是键盘。
显示器是计算机用来与人进行交流的,计算机通过显示器来告诉人一些信息,而键盘是人用来与计算机进行交流的,人通过键盘将命令发送给计算机,计算机接受人通过键盘发来的命令,然后进行处理,最后将处理的结果通过显示器告诉人,这样就完成了一次最简单最基本的交互。
在本篇中,笔才将从一个编写操作系统的角度去描述操作系统应当怎样处理键盘,让人可以通过键盘与计算机进行交互。
在本篇中,我们同样将以pyos做为我们的实验平台,在pyos上实验操作系统对键盘的控制,为了进行本次实验,笔者专门编写了一人非常简单的“推箱子”游戏,当pyos启动后,你可以输入“game(回车)”命令,然后系统就会调入这个游戏,这时,你可以通过上下左右四个方向键进行游戏,游戏结束后,按“ESC”键,可以返回系统内核。
所有的这一切你都会从本篇中了解到去怎样实现它。
在本篇中,pyos实现了类似windows的一个消息系统,换句话说,此处的pyos是由消息驱动的,如果你能windows的消息驱动很好奇,但又不知它是怎样实现的,那么,本篇中所介绍的pyos的消息驱动或许能对你理解windows的消息戏动有些许帮助:)本篇与前几篇实验报告是一脉相承的,特别是同《保护模式下中断编程》一篇有较为紧密的相关性,你可以在我的主页上()找到它们,上面的内容对理解本篇会具有较大帮助。
在pyos的编写过程中,得到了许多朋友的大力支持与帮助,中国安天实验室的张栗炜老师指出了pyos中存在的一些问题,并给出了怎样完全在windows环境下进行pyos开发的方法,哈尔滨工业大学的kylix,sun为本实现中曾经出现的奇怪现象提出了非常好的意见,极大的扩展了笔者的思路及眼界,pineapple,lizhenguo为本实验的调试花费了许多精力……还有许多朋友给我发来电子邮件及在QQ上留言,帮助并支持笔者进行实验,无法一一列举,仅在此对上述关心pyos的朋友致以最真诚的谢意与问候!Ok,言归正传,下面就让我们开始我们的实验,Let’s Go!~~键盘驱动简介CPU对外部设备的管理是通过中断程序进行的,键盘也是一种外部设备,因此,CPU 对键盘的管理也是通过中断进行的。
linux write流程
在Linux系统中,write()函数是用于向文件中写入数据的系统调用函数。
其工作流程如下:
1. 打开文件:使用open()函数打开要写入数据的文件,并获取文件描述符。
2. 定位文件指针:使用lseek()函数将文件指针定位到要写入数据的位置。
3. 写入数据:使用write()函数将要写入的数据写入文件。
write()函数的第一个参数是文件描述符,第二个参数是要写入的数据缓冲区,第三个参数是要写入的数据大小,第四个参数是要写入的数据数量。
4. 返回值:write()函数返回实际写入的数据数量。
如果发生错误,则返回-1。
5. 关闭文件:使用close()函数关闭文件,释放资源。
需要注意的是,write()函数是一个阻塞函数,即当数据没有写入完成时,该函数会一直等待,直到数据写入完成。
此外,write()函数可能会出现数据写不完整的情况,需要谨慎处理。
【IT专家】自己动手写shell命令之write
自己动手写shell 命令之write2014/10/17 0 Linux 下write 命令允许用户跟其他终端上的用户对话。
用c 语言实现shell 命令write,代码如下:#include stdio.h #include fcntl.h #include unistd.h #include utmp.h #include pwd.h #include sys/types.h #include stdlib.h #include sys/stat.h #include time.h char * get_terminal_name(char *);char * get_terminal_name_by_user_name(char *);void hello();int main(int argc, char * argv[]) {int fd;char buffer[1024];char * terminal_name;if (argc != 2) {printf( write usage: write [ttyname|username] return 1;}terminal_name = get_terminal_name(argv[1]);if(terminal_name == NULL){printf( get terminal name error\n return 1;}//printf( terminate_name:%s , terminal_name);fd = open(terminal_name,O_WRONLY);hello(fd);while(fgets(buffer,1024,stdin) != EOF){write(fd,buffer,strlen(buffer));}close(fd);return 0;}void hello(int fd) {char greeting[1024];struct passwd * passwd_pointer;time_t now;char host[255];gethostname(host, 255);time( now);passwd_pointer = getpwuid(getuid());sprintf(greeting, Message from %s@%s on %s at %5.5s ...\n ,passwd_pointer- pw_name, host, ttyname(0), ctime( now) + 11);write(fd,greeting,strlen(greeting));}char * get_terminal_name(char * user_input) {char terminal_name[255];struct stat stat_buffer;if (lstat(user_input, stat_buffer) != -1) {if (S_ISCHR(stat_buffer.st_mode)) {return user_input;}}return get_terminal_name_by_user_name(user_input);}char * get_terminal_name_by_user_name(char * user_name) {struct utmp * utmp_pointer;setutent();int number = 0;char * result = (char *) malloc(sizeof(char) * 255);char *mytty = ttyname(0); /* begins /dev/ */char *ttydev = mytty + strlen( /dev/ printf( %s\n , mytty);while ((utmp_pointer = getutent()) != NULL) {if (strcmp(user_name, utmp_pointer- ut_user) == 0 utmp_pointer- ut_type == USER_PROCESS strcmp(utmp_pointer- ut_line, ttydev) != 0 utmp_pointer- ut_line[0] != : )。