30天自制操作系统

《30天自制操作系统》Day01

穿精又带淫゛_ 提交于 2020-04-05 17:54:05
我宣布,从今天开始,本懒狗正式踏入自制操作系统的大坑之中,内容将使用较现代的新工具和新思路来编写,会不定期更新(谁让我懒呢...) 当然,这个系列不会涉及太多理论,主要以我自己的实践过程为主,看理论请看书。 可以在 GitHub 跟进我的学习实践进度... 1. 工具准备 作者使用的工具,并不是我熟悉的,也不一定是最好的解决方案。 对于 16进制编辑器 ,你可以选用 WinHex ,我将采用开源免费的 wxMEdit : 文本编辑器 我首选 Visual Studio Code ,你可以选择自己喜欢的文本编辑器。 虚拟机 的话,你可以使用 Virtual Box 或者 VMware 。我将使用VMware Workstation 14,因为它更加强大。 汇编 的话,还是老老实实采用作者的 nask.exe 吧,我们并不需要自己写一个汇编器。 我们还需要一个 Bash环境 ,你可以选择 Git 的Bash,我这里使用 Cmder 。 2. 以16进制方式编辑image映像文件 2.1. Bash环境,dd命令,生成全0的image文件 软盘规定大小必须为 1440 KB ,也就是 1474560 字节(1440 * 1024 Bytes , 1 KB = 1024 Bytes )。 我们要制作的img文件中,由于只显示 hello,world ,所以很多空间中的值都是 0 。

《30天自制操作系统》笔记(12)——多任务入门

送分小仙女□ 提交于 2020-01-10 06:56:22
《30天自制操作系统》笔记(12)——多任务入门 进度回顾 上一篇 介绍了设置显示器高分辨率的方法。本篇讲一下操作系统实现多任务的方法。 什么是多任务 对程序员来说,也许这是废话,不过还是说清楚比较好。 多任务就是让电脑 同时 运行多个程序(如一边写代码一边听音乐一边下载电影)。 电脑的CPU只有固定有限的那么一个或几个, 不可能 真的同时运行多个程序。所以就用近似的方式,让多个程序 轮换 着运行。当轮换速度够快(0.01秒),给人的 感觉 就是"同时"运行了。 多任务之不实用版 我们首先从最基本的想法开始,做一个不实用版的多任务作为例子。在学习这个例子的过程中引入真正的多任务必须的TSS、TR、far模式JMP的概念,为后续内容打基础。 当你向CPU发出任务切换的指令时,CPU会先把寄存器中的值全部 写入 内存某处;然后,从内存另一位置把所有寄存器的值 读取 出来。这就完成了一次任务切换。 任务切换消耗的时间就是读写内存消耗的时间,大概为 0.0001秒 。 任务状态段TSS 存取全部寄存器的值这件事,当然需要有一个数据结构,这就是 "任务状态段" (Task Status Segment)简称TSS。 1 struct TSS32 2 { 3 int backlink, esp0, ss0, esp1, ss1, esp2, ss2, cr3; 4 int eip,

《30天自制操作系统》笔记(10)——定时器

天大地大妈咪最大 提交于 2020-01-04 14:32:25
《30天自制操作系统》笔记(10)——定时器 进度回顾 上一篇 和 上上一篇 解决了绘制窗口和窗口刷新的问题。关于窗口的东西就此告一段落。本篇介绍一个相对独立且十分重要的操作系统部件—— 定时器 的使用方法。 定时器是一个硬件 可编程的间隔型定时器(Programmable Interval Timer)简称 定时器(PIT) ,是集成到电脑上的一个硬件部件。之前讲过的用于实现中断机制的 PIC 也是个硬件部件。有了PIT,我们才能在计算机中计时。 初始化定时器 前面,CPU、PIC都需要设置好才能用, PIT也需要设置 。PIT类似C#Winform里的Timer控件,能设置的只有激发Tick事件的 时间间隔(Interval) 这个属性。PIT里的Tick事件,对应的是PIC里的 0号中断 。也就是说,PIT会根据你设定的Interval,每隔Interval时间就发送一个0号中断。这里又印证了 "事件小名中断" 的说法。 1 #define PIT_CTRL 0x0043 2 #define PIT_CNT0 0x0040 3 void init_pit(void) 4 { 5 io_out8(PIT_CTRL, 0x34);/*中断周期(Interval)即将变更*/ 6 io_out8(PIT_CNT0, 0x9c);/*中断周期的低8位*/ 7 io_out8(PIT

《30天自制操作系统》15_day_学习笔记

给你一囗甜甜゛ 提交于 2020-01-04 14:31:59
harib12a:   这一部分我们来尝试两个任务的切换。下面我们一步一步的看:    1、定义TSS任务状态段(task statuc segment); 定义的一种段,需要在GDT中定义使用 //TSS任务状态段(task statuc segment) struct TSS32 {//26个int成员,104字节 //与任务设置相关的信息(任务切换时,除backlink,都不会被写入) int backlink, esp0, ss0, esp1, ss1, esp2, ss2, cr3; //32位寄存器;eip任务返回时,找到返回的地址 int eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi; //16位寄存器 int es, cs, ss, ds, fs, gs; //第一行一样,有关任务设置的信息。任务切换时CPU不写 //ldtr = 0; iomap = 0x4000_0000 int ldtr, iomap; };    2、尝试两个任务的切换。A和B //(1)、两个任务定义   struct TSS32 tss_a, tss_b; //(2)、任务初始化:ldtr和iomap赋初值 tss_a.ldtr = 0; tss_a.iomap = 0x40000000; tss_b.ldtr = 0; tss

《30天自制操作系统》笔记(07)——内存管理

我的梦境 提交于 2020-01-04 14:31:39
《30天自制操作系统》笔记(07)——内存管理 进度回顾 上一篇 中处理掉了绝大部分与CPU配置相关的东西。本篇介绍内存管理的 思路 和 算法 。 现在想想,从软件工程师的角度看,CPU也只是一个软件而已:它的功能就是加载指令、执行指令和响应中断,而响应中断也是在加载指令、执行指令。就像火车沿着一条环形铁轨前进;当中断发生时,就好像铁轨岔口处变轨了,火车就顺着另一条轨迹走了;走完之后又绕回来重新开始。决定CPU是否变轨的,就是CPU里的特定寄存器。 这是题外话,就此为止。 什么是内存管理 假设内存大小是128MB,应用程序A暂时需要100KB,画面控制需要1.2MB……。 像这样,操作系统有时要 分配 一定大小的内存,用完后又要 收回 。因此,必须管理好哪些内存空闲可用,哪些正在被占用。这就是内存管理。 内存管理的两个任务,一是内存分配,一是内存释放。 如何获取内存容量 检查内存容量的方法 要管理内存,首先得知道操作系统所在的这个计算机内存有多大。检查内存容量的方法很简单,就是从要检查的起始位置到最后位置依次写入一个数值(例如0xaa55aa55),然后按位反转,检查是否正确地完成了反转(变成0x55aa55aa);然后再次反转,检查是否正确地完成了反转。如果反转结果都是正确的,说明这个地址的内存是存在的;否则就说明内存的最大地址就到此为止了。其代码如下。 1 unsigned

《30天自制操作系统》笔记(13)——总结

一笑奈何 提交于 2020-01-04 14:31:19
《30天自制操作系统》笔记(13)——总结 进度回顾 上一篇 介绍了操作系统实现多任务的方法。操作系统利用CPU的far模式的JMP指令、寄存器TR、GDT、TSS和PIT中断这些功能实现了多任务,可见CPU在设计时就考虑到了计算机要具有多任务处理的能力。也就是说,CPU、PIC等硬件支持什么功能,操作系统才能实现什么功能。 至此全书已经读了一半。我发现后半部分读不下去,也没必要再读了。本篇就对所有的笔记做一总结,至此《30天自制操作系统》这本书就暂且不读了。 所学所感 我们可以把CLR虚拟机(或者JVM)看做计算机。当用户双击一个保存了MSIL的exe文件,这个计算机能够加载exe文件,并执行其中的代码。 类似的,当用户按下开机按钮,物理机能够加载BIOS指定的程序代码,并执行之。硬件电路就是这么设计好的。 计算机自动加载的程序只有512字节,不够用来放OS程序。所以这512字节的程序就用来装载真正的OS程序到内存某处,然后JMP到该处执行OS程序。 硬件电路提供了寄存器若干、加减乘除、中断机制、定时器、内存段属性、任务切换等功能。OS程序利用CALL、RET等实现了函数的概念;利用中断机制实现了基于事件的编程;利用定时器、内存段、任务切换实现了多任务OS;利用内存段属性实现了保护OS的功能;利用一般保护性异常中断实现了抛出异常的功能。 充分了解CPU,充分了解汇编语言

《30天自制操作系统》笔记(01)——hello bitzhuwei’s OS!

偶尔善良 提交于 2019-12-20 17:43:59
《30天自制操作系统》笔记(01)——hello bitzhuwei's OS! 最初的OS代码 1 ; hello-os 2 ; TAB=4 3 4 ORG 0x7c00 ; 指明程序的装载地址 5 6 ; 以下这段是标准FAT12格式软盘专用的代码 7 8 JMP entry 9 DB 0x90 10 DB "HELLOIPL" ; freeparam 启动区的名称可以是任意的字符串(8字节) 11 DW 512 ; 每个扇区(sector)的大小(必须为512字节) 12 DB 1 ; 簇(cluster)的大小(必须为1个扇区) 13 DW 1 ; FAT的起始位置(一般从第一个扇区开始) 14 DB 2 ; FAT的个数(必须为2) 15 DW 224 ; 根目录的大小(一般设成224项) 16 DW 2880 ; 该磁盘的大小(必须是2880扇区) 17 DB 0xf0 ; 磁盘的种类(必须是0xf0) 18 DW 9 ; FAT的长度(必须是9扇区) 19 DW 18 ; 1个磁道(track)有几个扇区(必须是18) 20 DW 2 ; 磁头数(必须是2) 21 DD 0 ; 不使用分区,必须是0 22 DD 2880 ; 重写一次磁盘大小 23 DB 0,0,0x29 ; 意义不明,固定 24 DD 0xffffffff ; (可能是)卷标号码 25 DB

《30天自制操作系统》笔记(12)——多任务入门

大兔子大兔子 提交于 2019-12-16 23:42:14
《30天自制操作系统》笔记(12)——多任务入门 进度回顾 上一篇 介绍了设置显示器高分辨率的方法。本篇讲一下操作系统实现多任务的方法。 什么是多任务 对程序员来说,也许这是废话,不过还是说清楚比较好。 多任务就是让电脑 同时 运行多个程序(如一边写代码一边听音乐一边下载电影)。 电脑的CPU只有固定有限的那么一个或几个, 不可能 真的同时运行多个程序。所以就用近似的方式,让多个程序 轮换 着运行。当轮换速度够快(0.01秒),给人的 感觉 就是"同时"运行了。 多任务之不实用版 我们首先从最基本的想法开始,做一个不实用版的多任务作为例子。在学习这个例子的过程中引入真正的多任务必须的TSS、TR、far模式JMP的概念,为后续内容打基础。 当你向CPU发出任务切换的指令时,CPU会先把寄存器中的值全部 写入 内存某处;然后,从内存另一位置把所有寄存器的值 读取 出来。这就完成了一次任务切换。 任务切换消耗的时间就是读写内存消耗的时间,大概为 0.0001秒 。 任务状态段TSS 存取全部寄存器的值这件事,当然需要有一个数据结构,这就是 "任务状态段" (Task Status Segment)简称TSS。 1 struct TSS32 2 { 3 int backlink, esp0, ss0, esp1, ss1, esp2, ss2, cr3; 4 int eip,