![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
从0实现操作系统
文章平均质量分 76
武子康
永远清澈,永远热情,永远好奇,无限进步!请记住,计算机所有内容都是人研究创造的,所以不存在任何的"黑魔法",别人会的只是你暂时不会,总有一天,你会都研究明白的。我知道这个过程会很难很难,可是只要你想做一些事情,又有哪一件不难呢?所以请你不要放弃!!!
展开
-
MacOS环境-手写操作系统-48-让内核从错误中恢复
微软早期的DOS系统 存在一个严重的问题是如果应用程序运行出现问题 它会导致整个系统完全奔溃掉我们当前的系统内核也存在这一的问题例如打开api_call.asm,其内容如下call main 时CPU控制权会提交给应用程序执行应用程序的代码 应用程序执行完毕后返回到call main语句的下一条指令继续执行call main 的下一条语句是retf它的作用是从堆栈上得到内核代码的全局描述符把该描述符在描述符表中的下标赋值给寄存器cs。原创 2023-01-16 09:34:01 · 129 阅读 · 0 评论 -
MacOS环境-手写操作系统-46,47-C语言开发应用程序
内核为了避免恶意程序通过污染其内存而入侵自己在启动应用程序前 会专门给应用程序分配一块与内核完全隔离的内存 作为应用程序运行时的专属内存这样内核就拥有了比应用程序更高的等级 也就是内核可以访问应用程序的内存 反之则不行内核启动应用程序 -[DS,ES,SS寄存器指向应用程序专有的内存段描述符]-> 应用程序运行自身代码-[DS,ES,SS寄存器切换到内核对应的内存段描述符]->应用程序调用内核API CPU指向内核代码-[DS,ES,SS寄存器切换到应用程序专有的内存段描述符]原创 2023-01-13 17:07:31 · 129 阅读 · 0 评论 -
MacOS环境-手写操作系统-45-C语言开发应用程序
前边跳了几节 一个是内容比较细碎 另一个是原老师的文章链接挂掉了我也不太好做笔记 所以就跳过去啦 中间修复了一些bug和加了一些功能也不是那么重要 所以就忽略啦我们的操作系统通过增添内核接口导出机制后已经可以作为平台 运行应用程序了但目前应用程序的开发有一个不足就是我们只能使用汇编语言开发应用程序 用汇编语言开发程序实在太累了如果能使用C语言就好了例如当我们想要开发一个在控制台上输出一个字符的应用程序如果上面的代码能编译成二进制文件 并能通过系统加载执行。原创 2023-01-13 17:05:32 · 210 阅读 · 0 评论 -
MacOS环境-手写操作系统-44-运行简单的程序
我们写的操作系统 通过控制台命令 将其从软盘中载入到内存中运行 运行后 控制台卡住。用汇编写了一个小程序 只有几行(这个小程序启动之后 hlt卡住)在Makefile文件目录下 执行 make。即可实现对指令的执行 从而实现项目编译打包。(本节原来老师给的链接挂掉了)所以这里直接编译运行了。原创 2023-01-12 16:42:27 · 106 阅读 · 0 评论 -
MacOS环境-手写操作系统-43-dir命令的实现 和 文件写入
本节要实现的控制台命令是dir它的作用是列举出当前目录下的文件信息我们当前的操作系统根本没有硬盘 更没有文件系统那么这个命令列举的文件从哪里来呢?由于我们的系统内核是存储在软盘上的 因此 我们直接把软盘当做系统硬盘该命令列举的是存储在虚拟软盘上的文件假设我们在虚拟软盘上存储了两个文件分别为abc.exe, efg.sys,文件的大小分别为256字节和128字节。原创 2023-01-12 16:38:06 · 407 阅读 · 0 评论 -
MacOS环境-手写操作系统-42-Cls清屏
上节 我们实现了控制台命令mem它能显示当前可用内存本节我们实现另一常用命令叫cls该命令的作用是把控制台所以字符全部清空。原创 2023-01-12 16:34:45 · 292 阅读 · 0 评论 -
MacOS环境-手写操作系统-41-mem 第一个控制台程序
操作系统的一个重要功能是平台功能 也就是它能提供基础设施让其他程序运行在其自身之上甚至不少应用程序发展到后期 它自身的代码量和复杂度比运行它的操作系统还要复杂例如现在的chrome有一类程序叫命令行程序 此类程序没有花哨的窗口特效他们的运行方法是 用户在黑色的命令行窗口中 输入程序的名字后面跟着提交给程序的参数 点击回车 然后程序开始运行 然后把计算后的结果展示在命令行窗口里早期的DOS 以及现在Linux系统的Shell 都可以通过命令行来运行一系列程序。原创 2023-01-12 16:31:40 · 757 阅读 · 0 评论 -
MacOS环境-手写操作系统-40-进程消息通讯 和 回车键处理
我们顺利的完成了进程间的相互切换 但当前存有的一个问题是如果我们把输入焦点转移到命令行控制台 然后在通过Tab键 把输入焦点切换回文本框此时存在一个问题是 命令行控制台的输入指针居然还存在这就涉及到了进程间的通讯 一个进程将信号发送给另一个进程让对方及时采取某些动作由于我们在设计时 为每个进程准备了一个接收信息的队列 因此进程间相互发送消息是可以把消息放入到接收方的队列中 当接收方从队列中获取数据时 就能收到其他进程发送过来的信息进而及时处理。原创 2023-01-12 15:38:32 · 152 阅读 · 0 评论 -
MacOS环境-手写操作系统-39-Caps键响应
上一节 我们成功实现了对shift按键的处理这一节 我们看看如何处理caps 按键当该键按下时 输入系统的字符在大小写间切换由于我们系统启动后 默认输入是大写字符完成本节后 我们把系统的默认字符改成小写按下caps键 系统字符自动切换成大写当caps键按下时 键盘给系统发过来的扫描码是0x3a当该键弹起后 键盘发送过来的断码为0xba因此 相应caps按键事件只要针对这键盘中断发送过来的这两个数值进行对应处理就可。原创 2023-01-12 15:35:38 · 169 阅读 · 0 评论 -
MacOS环境-手写操作系统-38-Shift键响应
前几节 我们花费不少精力在键盘响应的处理之上到目前为止 我们的内核能够准确的将按键字符合理的显示在指定窗口上但目前还有一些遗憾 就是当前内核对shift 键的按下不做反应按理 当shift键按下后 再按数字键1那么显示的字符应该是”!”而不是“1”本节我们要处理的就是响应shift键的点击处理。原创 2023-01-12 15:33:44 · 140 阅读 · 0 评论 -
MacOS环境-手写操作系统-37-切换窗口 键盘输入
我们实现了键盘的输入焦点切换 但尽管控制命令台激活后如果我们敲击键盘 会发现字符输入的还是前头的Message box这一节 我们要实现把键盘敲击的内容输入到被切换的窗口实现的思路是这样的 我们为每个任务配置一个输入队列当窗口被激活时 一旦有键盘输入 主进程首先会把键盘数据获取到然后判断当前被激活的是哪个窗口 然后找到运行窗口所对应的进程对象通过进程对象获得其对应的输入队列 于是把键盘传过来的信息放入到输入队列中 然后激活对应的进程对象。原创 2023-01-12 15:32:04 · 117 阅读 · 0 评论 -
MacOS环境-手写操作系统-36-Tab键切换窗口
我们使用操作系统的时候 一个必不可少的功能就是通过Tab间在不同的窗口中来回切换这种便捷方式使得你不必要挪动鼠标去点击某个窗口 只要不停的按Tab键直到你的目标窗口被激活为止 一旦窗口被Tab键激活后 对应的窗口会响应你在键盘的输入我们本节的目的是在系统中实现这个功能。原创 2023-01-12 15:28:21 · 250 阅读 · 0 评论 -
MacOS环境-手写操作系统-35-Shell控制台
操作系统有一个重要的应用 就是命令控制台像Linux系统 命令控制台集合是使用系统的主要工具本节 我们将为系统开发一个命令控制台今后我们会为系统开发应用程序 不少程序将会通过控制台来运行。原创 2023-01-11 15:53:33 · 1646 阅读 · 0 评论 -
MacOS环境-手写操作系统-34-进程优先级
我们有了进程调度 目前来看 所有进程一律平等我们的调度算法是遍历每一个进程 然后给每一个进程一定的运行时间然后再切换下一个进程但实际运用上 进程间不会是平等的 有些进程承担着比较重要的工作因此 它有理由获得更多的运行时间例如内核进程 一些进程不是很重要它就不应该占用过度的CPU资源本节 我们要引入进程优先级的功能 让优先级高的进程获得更多的运行机会。原创 2023-01-11 15:49:56 · 177 阅读 · 0 评论 -
MacOS环境-手写操作系统-33-多任务多窗口
为了让多任务的特性展示的更直观本节 我们基于多任务的基础上 为系统实现多个窗口特效 每个窗口都运行于一个任务或进程由于窗口基于各自不同的进程 因此窗口自身的变化更新不会影响到其他窗口。原创 2023-01-11 15:46:13 · 137 阅读 · 0 评论 -
MacOS环境-手写操作系统-32-进程挂起和恢复
有了进程的自动调度后 接下来的任务在于如何将空闲进程挂起 空闲进程往往是那些没有具体任务需要处理的进程因此 如果继续让其运行的话 那么必然会耗费宝贵的CPU资源如果能让它先挂起 等到它需要执行具体任务时 再把它调度到前台 那才是一种合理的进程管理机制我们实现的进程调度 是依赖于进程控制器也就是taskctl中的任务数组来实现的 当我们想要启动某个进程时在该数组中找到对应的任务对象 然后把它加载到CPU那就可以了。原创 2023-01-11 15:43:22 · 155 阅读 · 0 评论 -
MacOS环境-手写操作系统-31-进程自动切换
我们已经通过时钟中断完成了两个进程间的相互切换但当前实现有很大的缺陷 例如我们只能在两个指定的进程间切换如果要想增添新的进程 那么 没增加一个进程按照当前模式 我们只能再增加相应代码 这显然是不可接受的因此 这节 我们希望完成进程的切换机制 使得有新进程时 我们无需改动代码进程的管理机制会自动把新进场添加进切换机制。原创 2023-01-05 10:44:16 · 101 阅读 · 0 评论 -
MacOS环境-手写操作系统-30-进程之间互相切换
上一节 我们初步介绍了进程相关的具体概念特别是讲解了进程切换相关的数据结构 也就是TSS也实现了进程的自我切换本节 我们看看如何从当前的进程切换到新进程 然后再切换回来进程A -切换->进程B-切换->进程A.原创 2023-01-05 10:40:25 · 105 阅读 · 0 评论 -
MacOS环境-手写操作系统-29-进程切换
操作系统内核开发 一个及其重要的模块是进程以及进程调度在大学的操作系统课堂上 研究进程和相关调度算法 是一块耗时耗力的内容市面上 讲解操作系统进程概念以及调度算法的内容可谓是汗牛充栋 记得我以前读相关内容时 看到很多算法流程图 伪码说明等等但无论描述的如何详细 但只要我无法动手实践 那么也只能是隔靴搔痒 心中困顿 始终无法排解从本节开始 我们看看 如何通过代码实践的方式 把各种天花乱坠的进程算法落地实现。原创 2023-01-04 17:11:04 · 143 阅读 · 0 评论 -
MacOS环境-手写操作系统-28-输入文本框和鼠标移动窗体
上一节 我们实现了按键转换成字符的功能这一节 我们更近一步在message box中实现一个输入文本框按键时 字符显示在文本框内 并且输入光标在文本框中不断闪动。原创 2023-01-04 16:12:46 · 116 阅读 · 0 评论 -
MacOS环境-手写操作系统-27-修改分辨率
当前 我们系统的分辨率是320*480这种分辨率太小 绘制出来的系统界面看起来很大条 也很粗糙跟我们现实使用的操作系统比起来 差别太大因此 本节 我们就在分辨率上做一些改进。原创 2023-01-04 15:59:12 · 283 阅读 · 0 评论 -
MacOS环境-手写操作系统-26-利用时钟开发光标闪烁
上一节,我们已经实现了时钟超时功能 但一个操作系统 肯定是能支持多个时钟的本节 我们就看看如何从上一节的单时钟向多时钟转变 同时利用时钟超时机制实现光标的闪烁特效。原创 2023-01-04 15:37:26 · 88 阅读 · 0 评论 -
MacOS环境-手写操作系统-25-实现定时器
当指定的时间过去后 系统会触发你给定的回调函数Timer功能实在是太重要了 如果没有定时器 操作系统很多任务都做不了至少你编程画个时钟 搞个闹钟程序什么的 你就没法实现从这节开始 我们看看timer功能是怎么实现的。原创 2023-01-04 15:27:20 · 122 阅读 · 0 评论 -
MacOS环境-手写操作系统-24-消除鼠标闪烁
上一节 我们消除了因刷新而导致的严重闪烁 但问题并没有从根子上解决因为当我们把鼠标挪动不断刷新自己的Message Box上面时 发现鼠标居然变得闪动起来当窗体自身刷新时 它会把处于它上方的窗体也进行刷新 而这种操作其实是没有必要的我们看下面这种情况数字1代表的是标号为1的窗口所对应的像素点数字2所代表的是编号为2的窗口所对应的像素点窗口1的右下边部分被窗口2所覆盖窗口2比窗口1的高度还要高当窗口1的像素进行刷新时 如果窗口2的内容没有变化的话。原创 2023-01-04 15:20:11 · 159 阅读 · 0 评论 -
MacOS环境-手写操作系统-23-消除刷新的闪烁
就以前几节我们创造的Message box为例我们修改一下代码 不断的修改Box窗体内的字符 进而导致图层不断刷新(在上节我们已经出现了这样的问题 22-突破连续读取72个扇区)运行后 就疯狂的闪烁这个现象的产生 是因为我们在刷新Box窗体时 我们也同时在刷新底层桌面假设一个窗体 它的高度是10 那么它刷新时 高度为0到9的窗体根本不需要跟着刷新如果高度低的窗体跟着刷新 不但产生闪烁的效果而且是毫无必要的浪费CPU资源 接下来我们的改进就是 当窗体刷新时 只刷新同一层高度原创 2023-01-03 14:50:46 · 70 阅读 · 0 评论 -
MacOS环境-手写操作系统-22-突破扇区读取限制
因为一些特殊的原因 当我们读取超过72个扇区的时候 就会出现错误但是我们后边的开发 肯定是要超过72个扇区的。我们的操作系统加载器 秉承简单够用的原则只要能把编译好的二进制内核送进内存就可以了 所以加载器的算法是 连续读取软盘扇区 将扇区的内容写入到从0x8000 开始的内存中原创 2023-01-03 14:30:42 · 195 阅读 · 1 评论 -
MacOS环境-手写操作系统-21-实现MessageBox
早年学习win32 GUI编程 通过调用一个API 叫MessageBox使得程序能快速弹出一个小窗口 当看到这个小窗口出现在屏幕上时 开心得不得了 觉得非常不可思议它生动形象 跟原来在控制台上运行的 只能给出黑底白色结果的dos程序完全不同从此 我从黑色单调的世界进入了称之为“图形界面“的色彩斑斓的绝妙空间原创 2023-01-03 09:22:28 · 127 阅读 · 0 评论 -
MacOS环境-手写操作系统-20-图层叠加优化
在前几节 我们使用窗体图层叠加技术 解决了窗体鼠标移动时 破坏其他窗体界面的问题但同时 也引入了新的问题当鼠标移动时 内核会将所有窗口重新绘制如果当前系统打开的窗口很多 假设有几十上百个 那么鼠标动一下 就重新绘制上百个窗口这对cpu资源的消耗就会非常大 整个系统的性能就会被拖垮由此 我们需要优化内核对窗口更新重绘的设计 降低不必要的损耗原创 2023-01-03 09:15:20 · 81 阅读 · 0 评论 -
MacOS环境-手写操作系统-19-编译自动化
因为原文章的老师 编译环境是:mac + ubuntu而我的环境是: mac (当前是MacOS BigSur)在java中 会对 反汇编源码文件里带有global , extern, SECTION等关键字的语句进行自动删除同时对 跳转指令后面的目的地所在的距离跟当前指令的距离超过了127个字节 的问题也进行了修复(我本地是没有跳转的这个问题的 加上也无所谓)我当前环境运行java打包 出现nasm无法使用的问题这里给它nasm的绝对路径原创 2023-01-03 09:09:56 · 88 阅读 · 0 评论 -
MacOS环境-手写操作系统-18-图片分层技术
在前面的章节中 我们完成了鼠标的绘制 但存在一个严重的问题是当鼠标移动的时候 鼠标下方的窗口或图案会因为内核重绘鼠标而被擦除掉解决这个问题的办法是 每当鼠标移动时 我们先把底下的图案绘制一遍 然后把鼠标在移动后的新坐标处再绘制一遍由此 我们引出一个叫图层的概念 鼠标下面的背景是一个图层 鼠标自己处于一个图层 图层间有高度差别作为背景的图层 它的高度就要比鼠标所在的图层低 因此内核每次重绘时 先绘制高度低的图层 再绘制高度高的图层 我们使用的操作系统 用鼠标挪动窗口时 窗口底部的图案不原创 2023-01-03 09:07:25 · 211 阅读 · 0 评论 -
MacOS环境-手写操作系统-17-内存管理算法实现
在上一节,我们得知可用内存的大小后,我们就可以开发一个简单的管理算法去管理和分配可用用内存。原创 2023-01-02 11:14:47 · 206 阅读 · 0 评论 -
MacOS环境-手写操作系统-16-内存管理 解析内存状态
现在 我们可以显示和分析获得的相关信息 为下一步实现内存管理做准备MemChkBuf 是BIOS填充好的数据缓冲区地址 C语言模块通过调用接口get_adr_buffer 获得该地址以便对内存分布状况进行深入的解析。原创 2023-01-02 11:13:35 · 132 阅读 · 0 评论 -
MacOS环境-手写操作系统-15-内核管理 检测可用内存
操作系统的一大功能就是为运行程序分配资源在众多系统资源中 内存是系统内核必须小心处理的一块内存分配算法 也是操作系统内核理论和开发上的重点和难点从本节开始我们看看内核如何有效的管理和控制内存如何知道系统运行的硬件有多少可用内存呢,一种通用性比较好的办法是使用15h中断 具体步骤如下:(1)将寄存器ax 赋值为 0E820h(2)将寄存器ebx 初始化为0,该寄存器的内容会被BIOS修改,修改成什么数值,我们不用关心,但必须保证内存查询过程中,该寄存器不会被修改。原创 2023-01-02 11:10:35 · 127 阅读 · 0 评论 -
MacOS环境-手写操作系统-14-控制鼠标移动
鼠标发送的数据 必须三个字节连在一起解读 所以我们的内核要等待鼠标发送足够的数据后才可以采取行动前面我们看到 当鼠标被激活后 它会立马给内核发送一个字节数据 数值为0xfa当内核收到这个数据后 就可以开始积攒数据 每接收三个字节后 根据数据绘制鼠标这三个字节数据是有一定特点的 第一个字节0xaba的数值必须在0-3这个范围内 由于a对应的是八比特中的高四位 所以这意味着该字节的第7,8两个比特位必须为0。原创 2023-01-02 11:05:01 · 236 阅读 · 0 评论 -
MacOS环境-手写操作系统-13-鼠标中断
如果大家还记得描述8259A中断控制器那一小节的话鼠标发送中断信号的数据线在从8259A芯片的IRQ4信号线因此 为了接收鼠标中断信号 我们在初始化中断控制芯片时 必须启用该信号线同时 从8259A芯片是通过主8259A的IRQ2信号线连接在一起的所以也必须同时启动主8259A芯片的IRQ2信号线mov al, 11111001b 这一句指令 启用了主8259A芯片的IRQ1和IRQ2两根信号线。原创 2023-01-01 20:22:14 · 315 阅读 · 0 评论 -
MacOS环境-手写操作系统-12-键盘中断机制
我们实现了键盘中断的响应 但响应的处理比较简单 只是向界面打印一条字符串而已本节 当键盘上的一个按键按下时 键盘会发送一个中断信号给CPU与此同时 键盘会在指定端口(0x60) 输出一个数值这个数值对应按键的扫描码(make code) 当按键弹起时 键盘又给端口输出一个数值 这个数值叫断码(break code).我们以按键按键’A’为例 当按键’A’按下时 键盘给端口0x60发出的扫描码是0X1E 当按键’A’弹起时 键盘会给端口0x60发送断码0x9E。原创 2023-01-01 20:18:58 · 341 阅读 · 0 评论 -
MacOS环境-手写操作系统-11-建立中断机制
上一节,我们绘制了鼠标图案,遗憾的是,鼠标箭头是死的,动不了,要想让鼠标移动,我们需要为内核建立中断机制当我们移动鼠标时,鼠标会给CPU发送信号,CPU接收到信号后,终止当前的运算,执行内核给定的代码以处理鼠标发送的信号每一个8259A控制器有8根中断信号线 总共可以接入15个外设硬件一般情况下 鼠标接入的是从8259A所对应的IRQ4这根信号线鼠标发送信号时 先通过管线IRQ4将信号传递到从8259A然后通过管线IRQ2传递到主8259A。原创 2023-01-01 20:16:26 · 180 阅读 · 0 评论 -
MacOS环境-手写操作系统-10-绘制系统鼠标
有了桌面背景,能够显示字符串,现在在图形界面上还少了点东西,那就是鼠标指针,如果有个鼠标能在桌面里动来动去,那系统就有点意思了。原创 2023-01-01 20:14:11 · 104 阅读 · 0 评论 -
MacOS环境-手写操作系统-09-绘制系统字体
可以直接将项目下的font.txt文件中的字体转换为我们需要的字体文件 生成fontData.inc。接着 在write_vga_desktop.c的主函数中,在for(;如果我们把8*16区域当做一个二维数组,白色的像素我们用0表示,黑色像素我们用1表示,有了上面的字体二进制文件后,我们直接将它include到内核文件kernel.asm里。那么上图的字符A, 最顶层的一行全是白色,所以用8个0表示,修改boot(直接放大一点)直接读了20个扇区 肯定够用了。第二行,8个像素中,中间两个像素设置成黑色,原创 2023-01-01 20:10:41 · 189 阅读 · 0 评论 -
MacOS环境-手写操作系统-08-C语言调色板(绘制系统界面)
在上一节 已经完成了C语言图像的绘制 这节课 我们来写一个像模像样的系统界面把多种RGB颜色的24位数值放入到一个数组中 原来的八位数不再对应一个颜色值 而是变成这个数组的下标硬件在显示像素颜色时,从像素对应的显存读取这个八位数,然后把这个数当做下标,在RGB颜色素组中找到对应的RGB颜色值,再把这个颜色值显示到对应的像素上。原创 2022-12-24 10:14:10 · 551 阅读 · 0 评论