30天自制操作系统(附光盘1张)

30天自制操作系统(附光盘1张) pdf epub mobi txt 电子书 下载 2025

[日] 川合秀实 著,周自恒,李黎明,曾详江,张文旭 译
图书标签:
  • 操作系统
  • 自制操作系统
  • DIY
  • 编程
  • 计算机科学
  • 技术
  • 入门
  • 实践
  • 30天
  • 光盘教材
想要找书就要到 静思书屋
立刻按 ctrl+D收藏本页
你会得到大惊喜!!
出版社: 人民邮电出版社
ISBN:9787115287960
版次:1
商品编码:11055051
包装:平装
丛书名: 图灵程序设计丛书
开本:16开
出版时间:2012-08-01
用纸:胶版纸
页数:710
字数:1063000
正文语种:中文
附件:光盘
附件数量:1

具体描述

编辑推荐

  

  只需30天
  从零开始编写一个五脏俱全的图形操作系统
  39.1KB迷你系统
  实现多任务、汉字显示、文件压缩,还能听歌看图玩游戏
  日本编程天才
  揭开CPU、内存、磁盘以及操作系统底层工作模式的神秘面纱

内容简介

  《30天自制操作系统》是一本兼具趣味性、实用性与学习性的操作系统图书。作者从计算机的构造、汇编语言、C语言开始解说,让读者在实践中掌握算法。在这本书的指导下,从零编写所有代码,30天后就可以制作出一个具有窗口系统的32位多任务操作系。
  《30天自制操作系统》适合操作系统爱好者和程序设计人员阅读。

作者简介

  川合秀实(Hidemi Kawai),生于1975年,是一位以“轻量化”编程思想见长的“非主流”开发者。2000年因自行开发的OSASK项目而名声大噪。OSASK是一个开源的32位微型操作系统,它并非以Linux等内核为基础,而是完全从零开始开发,在一张软盘的容量下实现了GUI、多任务、多语言等高级特性,启动时间只需1秒。本书的内容可以看成是作者以OSASK为蓝本,教会读者从零开始开发一个操作系统,同时可以让初学者在编写操作系统的过程中,了解操作系统背后更多的知识。

目录

第0天 着手开发之前
1 前言
2 何谓操作系统
3 开发操作系统的各种方法
4 无知则无畏
5 如何开发操作系统
6 操作系统开发中的困难
7 学习本书时的注意事项(重要!)
8 各章内容摘要

第1天 从计算机结构到汇编程序入门
1 先动手操作
2 究竟做了些什么
3 初次体验汇编程序
4 加工润色

第2天 汇编语言学习与Makefile入门
1 介绍文本编辑器
2 继续开发
3 先制作启动区
4 Makefile入门

第3天 进入32位模式并导入C语言
1 制作真正的IPL
2 试错
3 读到18扇区
4 读入10个柱面
5 着手开发操作系统
6 从启动区执行操作系统
7 确认操作系统的执行情况
8 32位模式前期准备
9 开始导入C语言
10 实现HLT(harib00j)

第4天 C语言与画面显示的练习
1 用C语言实现内存写入(harib01a)
2 条纹图案(harib01b)
3 挑战指针(harib01c)
4 指针的应用(1)(harib01d)
5 指针的应用(2)(harib01e)
6 色号设定(harib01f)
7 绘制矩形(harib01g)
8 今天的成果(harib01h)

第5天 结构体、文字显示与GDT/IDT初始化
1 接收启动信息(harib02a)
2 试用结构体(harib02b)
3 试用箭头记号(harib02c)
4 显示字符(harib02d)
5 增加字体(harib02e)
6 显示字符串(harib02f)
7 显示变量值(harib02g)
8 显示鼠标指针(harib02h)
9 GDT与IDT的初始化(harib02i)

第6天 分割编译与中断处理
1 分割源文件(harib03a)
2 整理Makefile(harib03b)
3 整理头文件(harib03c)
4 意犹未尽
5 初始化PIC(harib03d)
6 中断处理程序的制作(harib03e)

第7天 FIFO与鼠标控制
1 获取按键编码(hiarib04a)
2 加快中断处理(hiarib04b)
3 制作FIFO缓冲区(hiarib04c)
4 改善FIFO缓冲区(hiarib04d)
5 整理FIFO缓冲区(hiarib04e)
6 总算讲到鼠标了(harib04f)
7 从鼠标接受数据(harib04g)

第8天 鼠标控制与32位模式切换
1 鼠标解读(1)(harib05a)
2 稍事整理(harib05b)
3 鼠标解读(2)(harib05c)
4 移动鼠标指针(harib05d)
5 通往32位模式之路

第9天 内存管理
1 整理源文件(harib06a)
2 内存容量检查(1)(harib06b)
3 内存容量检查(2)(harib06c)
4 挑战内存管理(harib06d)

第10天 叠加处理
1 内存管理(续)(harib07a)
2 叠加处理(harib07b)
3 提高叠加处理速度(1)(harib07c)
4 提高叠加处理速度(2)(harib07d)

第11天 制作窗口
1 鼠标显示问题(harib08a)
2 实现画面外的支持(harib08b)
3 shtctl的指定省略(harib08c)
4 显示窗口(harib08d)
5 小实验(harib08e)
6 高速计数器(harib08f)
7 消除闪烁(1)(harib08g)
8 消除闪烁(2)(harib08h)

第12天 定时器(1)
1 使用定时器(harib09a)
2 计量时间(harib09b)
3 超时功能(harib09c)
4 设定多个定时器(harib09d)
5 加快中断处理(1)(harib09e)
6 加快中断处理(2)(harib09f)
7 加快中断处理(3)(harib09g)

第13天 定时器(2)
1 简化字符串显示(harib10a)
2 重新调整FIFO缓冲区(1)(harib10b)
3 测试性能(harib10c~harib10f)
4 重新调整FIFO缓冲区(2)(harib10g)
5 加快中断处理(4)(harib10h)
6 使用“哨兵”简化程序(harib10i)

第14天 高分辨率及键盘输入
1 继续测试性能(harib11a~harib11c)
2 提高分辨率(1)(harib11d)
3 提高分辨率(2)(harib11e)
4 键盘输入(1)(harib11f)
5 键盘输入(2)(harib11g)
6 追记内容(1)(harib11h)
7 追记内容(2)(harib11i)

第15天 多任务(1)
1 挑战任务切换(harib12a)
2 任务切换进阶(harib12b)
3 做个简单的多任务(1)(harib12c)
4 做个简单的多任务(2)(harib12d)
5 提高运行速度(harib12e)
6 测试运行速度(harib12f)
7 多任务进阶(harib12g)

第16天 多任务(2)
1 任务管理自动化(harib13a)
2 让任务休眠(harib13b)
3 增加窗口数量(harib13c)
4 设定任务优先级(1)(harib13d)
5 设定任务优先级(2)(harib13e)

第17天 命令行窗口
1 闲置任务(harib14a)
2 创建命令行窗口(harib14b)
3 切换输入窗口(harib14c)
4 实现字符输入(harib14d)
5 符号的输入(harib14e)
6 大写字母与小写字母(harib14f)
7 对各种锁定键的支持(harib14g)

第18天 dir命令
1 控制光标闪烁(1)(harib15a)
2 控制光标闪烁(2)(harib15b)
3 对回车键的支持(harib15c)
4 对窗口滚动的支持(harib15d)
5 mem命令(harib15e)
6 cls命令(harib15f)
7 dir命令(harib15g)

第19天 应用程序
1 type命令(harib16a)
2 type命令改良(harib16b)
3 对FAT的支持(harib16c)
4 代码整理(harib16d)
5 第一个应用程序(harib16e)

第20天 API
1 程序整理(harib17a)
2 显示单个字符的API(1)(harib17b)
3 显示单个字符的API(2)(harib17c)
4 结束应用程序(harib17d)
5 不随操作系统版本而改变的API(harib17e)
6 为应用程序自由命名(harib17f)
7 当心寄存器(harib17g)
8 用API显示字符串(harib17h)

第21天 保护操作系统
1 攻克难题——字符串显示API(harib18a)
2 用C语言编写应用程序(harib18b)
3 保护操作系统(1)(harib18c)
4 保护操作系统(2)(harib18d)
5 对异常的支持(harib18e)
6 保护操作系统(3)(harib18f)
7 保护操作系统(4)(harib18g)

第22天 用C语言编写应用程序
1 保护操作系统(5)(harib19a)
2 帮助发现bug(harib19b)
3 强制结束应用程序(harib19c)
4 用C语言显示字符串(1)(harib19d)
5 用C语言显示字符串(2)(harib19e)
6 显示窗口(harib19f)
7 在窗口中描绘字符和方块(harib19g)

第23天 图形处理相关
1 编写malloc(harib20a)
2 画点(harib20b)
3 刷新窗口(harib20c)
4 画直线(harib20d)
5 关闭窗口(harib20e)
6 键盘输入API(harib20f)
7 用键盘输入来消遣一下(harib20g)
8 强制结束并关闭窗口(harib20h)

第24天 窗口操作
1 窗口切换(1)(harib21a)
2 窗口切换(2)(harib21b)
3 移动窗口(harib21c)
4 用鼠标关闭窗口(harib21d)
5 将输入切换到应用程序窗口(harib21e)
6 用鼠标切换输入窗口(harib21f)
7 定时器API(harib21g)
8 取消定时器(harib21h)

第25天 增加命令行窗口
1 蜂鸣器发声(harib22a)
2 增加更多的颜色(1)(harib22b)
3 增加更多的颜色(2)(harib22c)
4 窗口初始位置(harib22d)
5 增加命令行窗口(1)(harib22e)
6 增加命令行窗口(2)(harib22f)
7 增加命令行窗口(3)(harib22g)
8 增加命令行窗口(4)(harib22h)
9 变得更像真正的操作系统(1)(harib22i)
10 变得更像真正的操作系统(2)(harib22j)

第26天 为窗口移动提速
1 提高窗口移动速度(1)(harib23a)
2 提高窗口移动速度(2)(harib23b)
3 提高窗口移动速度(3)(harib23c)
4 提高窗口移动速度(4)(harib23d)
5 启动时只打开一个命令行窗口(harib23e)
6 增加更多的命令行窗口(harib23f)
7 关闭命令行窗口(1)(harib23g)
8 关闭命令行窗口(2)(harib23h)
9 start命令(harib23i)
10 ncst命令(harib23j)

第27天 LDT与库
1 先来修复bug(harib24a)
2 应用程序运行时关闭命令行窗口(harib24b)
3 保护应用程序(1)(harib24c)
4 保护应用程序(2)(harib24d)
5 优化应用程序的大小(harib24e)
6 库(harib24f)
7 整理make环境(harib24g)

第28天 文件操作与文字显示
1 alloca(1)(harib25a)
2 alloca(2)(harib25b)
3 文件操作API(harib25c)
4 命令行API(harib25d)
5 日文文字显示(1)(harib25e)
6 日文文字显示(2)(harib25f)
7 日文文字显示(3)(harib25g)

第29天 压缩与简单的应用程序
1 修复bug(harib26a)
2 文件压缩(harib26b)
3 标准函数
4 非矩形窗口(harib26c)
5 bball(harib26d)
6 外星人游戏(harib26e)

第30天 高级的应用程序
1 命令行计算器(harib27a)
2 文本阅览器(harib27b)
3 MML播放器(harib27c)
4 图片阅览器(harib27d)
5 IPL的改良(harib27e)
6 光盘启动(harib27f)

第31天 写在开发完成之后
1 继续开发要靠大家的努力
2 关于操作系统的大小
3 操作系统开发的诀窍
4 分享给他人使用
5 关于光盘中的软件
6 关于开源的建议
7 后记
8 毕业典礼
9 附录






精彩书摘

  第15天
  多任务(1)
  挑战任务切换(harib12a)
  任务切换进阶(harib12b)
  做个简单的多任务(1)(harib12c)
  做个简单的多任务(2)(harib12d)
  提高运行速度(harib12e)
  测试运行速度(harib12f)
  多任务进阶(harib12g)
  1 挑战任务切换(harib12a)
  “话说,多任务到底是啥呢?”我们今天的内容,就从这个问题开始吧。
  多任务,在英语中叫做“multitask”,顾名思义就是“多个任务”的意思。简单地说,在Windows等操作系统中,多个应用程序同时运行的状态(也就是同时打开好几个窗口的状态)就叫做多任务。
  对于生活在现代社会的各位来说,这种多任务简直是理所当然的事情。比如你会一边用音乐播放软件听音乐一边写邮件,邮件写到一半忽然有点东西要查,便打开Web浏览器上网搜索。这对于大家来说这些都是家常便饭了吧。可如果没有多任务的话会怎么样呢?想写邮件的时候就必须关掉正在播放的音乐,要查东西的时候就必须先保存写到一半的邮件,然后才能打开Web浏览器……光想象一下就会觉得太不方便了。
  然而在从前,没有多任务反倒是普遍的情形(那个时候大家不用电脑听音乐,也没有互联网)。在那个年代,电脑一次只能运行一个程序,如果要同时运行多个程序的话,就得买好几台电脑才行。
  就在那个时候,诞生了最初的多任务操作系统,大家都觉得太了不起了。从现在开始,我们也要准备给“纸娃娃系统”添加执行多任务的能力了。连这样一个小不点儿操作系统都能够实现多任务,真是让人不由地感叹它生逢其时呀。
  稍稍思考一下我们就会发现,多任务这个东西还真是奇妙,它究竟是怎样做到让多个程序同时运行的呢?如果我们的电脑里面装了好多个CPU的话,同时运行多个程序倒也顺理成章,但实际上就算我们只有一个CPU,照样可以实现多任务。
  其实说穿了,这些程序根本没有在同时运行,只不过看上去好像是在同时运行一样:程序A运行一会儿,接下来程序B运行一会儿,再接下来轮到程序C,然后再回到程序A……如此反复,有点像日本忍者的“分身术”呢(笑)。
  为了让这种分身术看上去更完美,需要让操作系统尽可能快地切换任务。如果10秒才切换一次,那就连人眼都能察觉出来了,同时运行多个程序的戏码也就穿帮了。再有,如果我们给程序C发出一个按键指令,正巧这个瞬间系统切换到了程序A的话,我们就不得不等上20秒,才能重新轮到程序C对按键指令作出反应。这实在是让人抓狂啊(哭)。
  在一般的操作系统中,这个切换的动作每0.01~0.03秒就会进行一次。当然,切换的速度越快,让人觉得程序是在同时运行的效果也就越好。不过,CPU进行程序切换(我们称为“任务切换”)这个动作本身就需要消耗一定的时间,这个时间大约为0.0001秒左右,不同的CPU及操作系统所需的时间也有所不同。如果CPU每0.0002秒切换一次任务的话,该CPU处理能力的50%都要被任务切换本身所消耗掉。这意味着,如果同时运行2个程序,每个程序的速度就只有单独运行时的1/4,这样你会觉得开心吗?如果变成这种结果,那还不如干脆别搞多任务呢。
  相比之下,即便是每0.001秒切换一次任务,单单在任务切换上面也要消耗CPU处理能力的10%。大概有人会想,10%也没什么大不了的吧?可如果你看看速度快10%的CPU卖多少钱,说不定就会恍然大悟,“对啊,只要优化一下任务切换间隔,就相当于一分钱也不花,便换上了比现在更快的CPU嘛……”(笑),你也就明白了浪费10%也是很不值得的。正是因为这个原因,任务切换的间隔最短也得0.01秒左右,这样一来只有1%的处理能力消耗在任务切换上,基本上就可以忽略不计了。
  关于多任务是什么的问题,已经大致讲得差不多了,接下来我们来看看如何让CPU来处理多任务。
  当你向CPU发出任务切换的指令时,CPU会先把寄存器中的值全部写入内存中,这样做是为了当以后切换回这个程序的时候,可以从中断的地方继续运行。接下来,为了运行下一个程序,CPU会把所有寄存器中的值从内存中读取出来(当然,这个读取的地址和刚刚写入的地址一定是不同的,不然就相当于什么都没变嘛),这样就完成了一次切换。我们前面所说的任务切换所需要的时间,正是对内存进行写入和读取操作所消耗的时间。
  接下来我们来看看寄存器中的内容是怎样写入内存里去的。下面这个结构叫做“任务状态段”(task status segment),简称TSS。TSS有16位和32位两个版本,这里我们使用32位版。顾名思义,TSS也是内存段的一种,需要在GDT中进行定义后使用。
  参考上面的结构定义,TSS共包含26个int成员,总计104字节(摘自CPU的技术资料),我特意把它们分成4行来写。从开头的backlink起,到cr3为止的几个成员,保存的不是寄存器的数据,而是与任务设置相关的信息,在执行任务切换的时候这些成员不会被写入(backlink除外,某些情况下是会被写入的)。后面的部分中我们会用到这里的设定,不过现在你完全可以先忽略它。
  第2行的成员是32位寄存器,第3行是16位寄存器,应该没必要解释了吧……不对,eip好像到现在还没讲过呢。EIP的全称是"extended instruction pointer",也就是"扩展指令指针寄存器"的意思。这里的"扩展"代表它是一个32位寄存器,也就是说其对应的16位版本叫做IP,类比一下的话,跟EAX与AX之间的关系是一样的。
  EIP是CPU用来记录下一条需要执行的指令位于内存中哪个地址的寄存器,因此它才被称为"指令指针"。如果没有这个寄存器,记性不好的CPU就会忘记自己正在运行哪里的程序,于是程序就没办法正常运行了。每执行一条指令,EIP寄存器中的值就会自动累加,从而保证一直指向下一条指令所在的内存地址。
  说点题外话,JMP指令实际上是一个向EIP寄存器赋值的指令。JMP 0x1234这种写法,CPU会解释为MOV EIP,0x1234,并向EIP赋值。也就是说,这条指令其实是篡改了CPU记忆中下一条该执行的指令的地址,蒙了CPU一把。这样一来,CPU在读取下一条指令时,就会去读取0x1234这个地址中的指令。你看,这不就相当于是做了一个跳转吗?
  对了,如果你在汇编语言里用MOV EIP,0x1234这种写法是会出错的,还是不要尝试的好。在汇编语言中,应该使用JMP 0x1234来代替MOV EIP,0x1234。
  如果在TSS中将EIP寄存器的值记录下来,那么当下次再返回这个任务的时候,CPU就可以明白应该从哪里读取程序来运行了。
  按照常识,段寄存器应该是16位的才对,可是在TSS数据结构中却定义成了int(也就是DWORD)类型。我们可以大胆想象一下,说不定英特尔公司的人将来会把段寄存器变成32位的,这样想想也挺有意思的呢(笑)。
  第4行的ldtr和iomap也和第1行的成员一样,是有关任务设置的部分,因此在任务切换时不会被CPU写入。也许你会想,那就和第1行一样,暂时先忽略好了--但那可是绝对不行的!如果胡乱赋值的话,任务就无法正常切换了,在这里我们先将ldtr置为0,将iomap置为0x40000000就好了。
  关于TSS的话题暂且先告一段落,我们回来继续讲任务切换的方法。要进行任务切换,其实还得用JMP指令。JMP指令分为两种,只改写EIP的称为near模式,同时改写EIP和CS的称为far模式,在此之前我们使用的JMP指令基本上都是near模式的。不记得CS是什么了?CS就是代码段(code segment)寄存器啦。
  说起来我们其实用过一次far模式的JMP指令,就在asmhead.nas的"bootpack启动"的最后一句(见8.5节)。
  JMP DWORD 2*8:0x0000001b
  这条指令在向EIP存入0x1b的同时,将CS置为2*8(=16)。像这样在JMP目标地址中带冒号(:)的,就是far模式的JMP指令。
  如果一条JMP指令所指定的目标地址段不是可执行的代码,而是TSS的话,CPU就不会执行通常的改写EIP和CS的操作,而是将这条指令理解为任务切换。也就是说,CPU会切换到目标TSS所指定的任务,说白了,就是JMP到一个任务那里去了。
  CPU每次执行带有段地址的指令时,都会去确认一下GDT中的设置,以便判断接下来要执行的JMP指令到底是普通的far-JMP,还是任务切换。也就是说,从汇编程序翻译出来的机器语言来看,普通的far-JMP和任务切换的far-JMP,指令本身是没有任何区别的。
  好了,枯燥的讲解就到这里,让我们实际做一次任务切换吧。我们准备两个任务:任务A和任务B,尝试从A切换到B。
  首先,我们需要创建两个TSS:任务A的TSS和任务B的TSS。
  本次的HariMain节选
  struct TSS32 tss_a, tss_b;
  向它们的ldtr和iomap分别存入合适的值。
  本次的HariMain节选
  tss_a.ldtr = 0;
  tss_a.iomap = 0x40000000;
  tss_b.ldtr = 0;
  tss_b.iomap = 0x40000000;
  接着将它们两个在GDT中进行定义。
  本次的HariMain节选
  struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT;
  set_segmdesc(gdt + 3, 103, (int) &tss;_a, AR_TSS32);
  set_segmdesc(gdt + 4, 103, (int) &tss;_b, AR_TSS32);
  将tss_a定义在gdt的3号,段长限制为103字节,tss_b也采用类似的定义。
  现在两个TSS都创建好了,该进行实际的切换了。
  我们向TR寄存器存入3 * 8这个值,这是因为我们刚才把当前运行的任务定义为GDT的3号。TR寄存器以前没有提到过,它的作用是让CPU记住当前正在运行哪一个任务。当进行任务切换的时候,TR寄存器的值也会自动变化,它的名字也就是"task register"(任务寄存器)的缩写。我们每次给TR寄存器赋值的时候,必须把GDT的编号乘以8,因为英特尔公司就是这样规定的。如果你有意见的话,可以打电话找英特尔的大叔投诉哦(笑)。
  给TR寄存器赋值需要使用LTR指令,不过用C语言做不到。唉,各位是不是都已经见怪不怪了啊?啥?你早就料到了?(笑)所以说,正如你所料,我们只能把它写进naskfunc.nas里面。
  本次的HariMain节选
  load_tr(3 * 8);
  本次的naskfunc.nas节选
  _load_tr: ; void load_tr(int tr);
  LTR [ESP+4] ; tr
  RET
  对了,LTR指令的作用只是改变TR寄存器的值,因此执行了LTR指令并不会发生任务切换。
  要进行任务切换,我们必须执行far模式的跳转指令,可惜far跳转这事C语言还是无能为力,这种语言还真是不方便啊。没办法,这个函数我们也得在naskfunc.nas里创建。
  本次的naskfunc.nas节选
  _taskswitch4: ; void taskswitch4(void);
  JMP 4*8:0
  RET
  也许有人会问,在JMP指令后面写个RET有意义吗?也对,通常情况下确实没意义,因为已经跳转到别的地方了嘛,后面再写什么指令也不会被执行了。不过,用作任务切换的JMP指令却不太一样,在切换任务之后,再返回这个任务的时候,程序会从这条JMP指令之后恢复运行,也就是执行JMP后面的RET,从汇编语言函数返回,继续运行C语言主程序。
  另外,如果far-JMP指令是用作任务切换的话,地址段(冒号前面的4*8的部分)要指向TSS这一点比较重要,而偏移量(冒号后面的0的部分)并没有什么实际作用,会被忽略掉,一般来说像这样写0就可以了。
  现在我们需要在HariMain的某个地方来调用taskswitch(),可到底该写在哪里呢?唔,有了,就放在显示"10[sec]"的语句后面好了。也就是说,程序启动10秒以后进行任务切换。
  本次的HariMain节选
  } else if (i == 10) { /* 10秒计时器*/
  putfonts8_asc_sht(sht_back, 0, 64, COL8_FFFFFF, COL8_008484, "10[sec]", 7);
  taskswitch4(); /*这里! */
  } else if (i == 3) { /* 3秒计时器 */
  大功告成了?不对,我们还没准备好tss_b呢。在任务切换的时候需要读取tss_b的内容,因此我们得在TSS中定义好寄存器的初始值才行。
  本次的HariMain节选
  tss_b.eip = (int) &task;_b_main;
  tss_b.eflags = 0x00000202; /* IF = 1; */
  tss_b.eax = 0;
  tss_b.ecx = 0;
  tss_b.edx = 0;
  tss_b.ebx = 0;
  tss_b.esp = task_b_esp;
  tss_b.ebp = 0;
  tss_b.esi = 0;
  tss_b.edi = 0;
  tss_b.es = 1 * 8;
  tss_b.cs = 2 * 8;
  tss_b.ss = 1 * 8;
  tss_b.ds = 1 * 8;
  tss_b.fs = 1 * 8;
  tss_b.gs = 1 * 8;
  乍看之下,貌似会有很多看不懂的地方吧,我们从后半段对寄存器赋值的地方开始看。这里我们给cs置为GDT的2号,其他寄存器都置为GDT的1号,asmhead.nas的时候也是一样的。也就是说,我们这次使用了和bootpack.c相同的地址段。当然,如果你用别的地址段也没问题,不过这次我们只是想随便做个任务切换的实验而已,这种麻烦的事情还是以后再说吧。
  继续看剩下的部分,关于eflags的赋值,如果把STI后的EFLAGS的值通过io_load_eflags赋给变量的话,该变量的值就显示为0x00000202,因此在这里就直接使用了这个值,仅此而已。如果还有看不懂的地方,大概就是eip和esp的部分了吧。
  在eip中,我们需要定义在切换到这个任务的时候,要从哪里开始运行。在这里我们先把task_b_main这个函数的内存地址赋值给它。
  本次的bootpack.c节选
  void task_b_main(void)
  {
  for (;;) { io_hlt(); }
  }
  这个函数只执行了一个HLT,没有任何实际作用,后面我们会对它进行各种改造,现在就先这样吧。
  task_b_esp是专门为任务B所定义的栈。有人可能会说,直接用任务A的栈不就好了吗?那可不行,如果真这么做的话,栈就会混成一团,程序也无法正常运行。
  本次的HariMain节选
  int task_b_esp;
  task_b_esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024;
  总之先写成这个样子了。我们为任务B的栈分配了64KB的内存,并计算出栈底的内存地址。请各位回忆一下向栈PUSH数据(入栈)的动作,ESP中存入的应该栈末尾的地址,而不是栈开头的地址。
  好了,我们已经讲解得够多了,现在总算是万事俱备啦,马上"make run"一下吧。这个程序如果运行正常的话应该是什么样子呢?嗯,启动之后的10秒内,还是跟以前一样的,10秒一到便执行任务切换,task_b_main开始运行。因为task_b_main只有一句HLT,所以接下来程序就全部停止了,鼠标和键盘也应该都没有反应了。
  唔……这样看起来好像很无聊啊,算了,总之我们先来"make run"吧。10秒钟的等待还真是漫长……哇!停了停了!
  看来我们的首次任务切换获得了圆满成功。
  ……

前言/序言

  “好想编写一个操作系统呀!”笔者的朋友曾说这是所有程序员都曾经怀揣的一个梦想。说“所有的程序员”可能有点夸张了,不过作为程序员的梦想,它至少也应该能排进前十名吧。
  也许很多人觉得编写操作系统是个天方夜谭,这一定是操作系统业界的一个阴谋(笑)。他们故意让大家相信编写操作系统是一件非常困难的事情,这样就可以高价兜售自己开发的操作系统,而且操作系统的作者还会被顶礼膜拜。那么实际情况又怎么样呢?和别的程序相比,其实编写操作系统并没有那么难,至少笔者的感觉是这样。
  在各位读者之中,也许有人曾经挑战过操作系统的编写,但因为太难而放弃了。拥有这样经历的人也许不会认同笔者的观点。其实你错了,你的失败并不是因为编写操作系统太难,而是因为没有人告诉你那其实是一件很简单的事而已。
  不仅是编写操作系统,任何事都是一样的。如果讲解的人认为它很难,那就不可能把它讲述得通俗易懂,即便是同样的内容,也会讲得无比复杂。这样的讲解,肯定是很难懂的。
  那么,你想不想和笔者一起再挑战一次呢?如果你曾经梦想过编写自己的操作系统,一定会觉得乐在其中的。
  可能有人会说,这本书足足有700多页,怎么会“有趣”和“简单”呢?唔,这么一说笔者也觉得挺心虚的,不过其实也只是长了那么一点点啦。平均下来的话,每天只有大约23页的内容,你看,也没有那么长吧?
  这本书的文风非常轻松,也许你不知不觉中就会读得很快。但是这样的话可能印象不会很深,最好还是能静下心来慢慢地读。书中所展示的程序代码和文字的说明同样重要,因此也希望大家仔细阅读。只要注意这些,理解本书的内容就应该没有问题了。
  在本书中,我们使用C语言和汇编语言来编写操作系统,不过不必担心,你可以在阅读本书的同时来逐步学习关于这些编程语言的知识。本书在这方面写得非常仔细,如果能有人通过本书终于把C语言中的指针给搞懂了,那笔者的目的也就达到了。即便是从这样的水平开始,30天后你也能够编写出一个很棒的操作系统,请大家拭目以待吧!

《30天自制操作系统》(附光盘1张):开启你的系统开发者之旅 这是一本旨在引领你踏入操作系统开发领域的实践指南。本书以一种循序渐进、深入浅出的方式,为你揭示操作系统的核心奥秘,并指导你亲手构建一个属于自己的操作系统。无论你是对计算机底层原理充满好奇的学生,还是渴望突破技术瓶颈的开发者,亦或是希望深入理解现代计算架构的爱好者,本书都将是你开启系统开发之旅的理想伴侣。 为什么选择自制操作系统? 在当今数字世界中,操作系统无处不在,支撑着我们日常使用的电脑、智能手机、服务器乃至嵌入式设备。然而,大多数人仅仅是操作系统的使用者,对其内部运作机制知之甚少。了解操作系统是如何工作的,不仅仅是满足好奇心,更是对计算机科学核心概念的深刻理解。 通过亲手构建一个操作系统,你将: 掌握底层原理: 深入理解 CPU 如何执行指令,内存如何管理,进程如何调度,以及设备如何与系统交互。这些知识是理解任何软件系统运行基础的关键。 提升编程技能: 你将大量接触 C 语言、汇编语言,学习如何进行低级别的内存操作、硬件访问和并发编程。这些技能将极大提升你的编程功力。 培养解决问题的能力: 操作系统开发是一个充满挑战的过程,需要细致的分析、严谨的逻辑和强大的调试能力。克服这些挑战将极大地锻炼你的技术解决问题的能力。 拓展技术视野: 了解操作系统的工作原理,能让你更好地理解各种应用软件、编程语言、数据库甚至网络协议的设计与实现。 激发创新灵感: 掌握了操作系统的基础,你将更有能力去设计和实现更高效、更安全的系统,甚至探索全新的计算范式。 本书内容概览 本书将引导你从零开始,逐步构建一个功能相对完整的操作系统。整个过程被精心设计为 30 个阶段(章节),确保学习的连贯性和可控性。以下是本书涵盖的主要内容模块,它们构成了你系统开发之旅的骨架: 第一部分:基础准备与入门 第一章:踏入系统之门: 介绍操作系统的概念、历史、分类以及其在现代计算中的重要性。我们将讨论为什么学习操作系统开发,以及本书的学习路径和目标。 第二章:开发环境搭建: 详细指导你配置必要的开发工具,包括交叉编译器、汇编器、链接器、模拟器/虚拟机(如 QEMU)以及调试器。确保你拥有一个稳定高效的开发环境是后续学习的基础。 第三章:汇编语言初步: 操作系统与硬件的交互离不开汇编语言。本章将介绍 x86 架构的汇编语言基础,包括寄存器、指令集、寻址模式等,为后续的引导程序开发打下基础。 第四章:实模式与保护模式: 了解 CPU 的工作模式至关重要。我们将深入讲解实模式和保护模式的区别与联系,以及如何从实模式切换到保护模式,这是进入更广阔的内存空间和启用高级特性的关键一步。 第二部分:引导与核心组件 第五章:编写你的第一个引导程序: 学习如何编写一个能够被 BIOS 加载并执行的简单引导程序。这个程序虽然简陋,却是操作系统的起点,它负责初始化硬件,加载后续的操作系统内核。 第六章:加载操作系统内核: 探讨引导程序如何将操作系统内核从磁盘加载到内存中,并将其控制权交给内核。我们将讲解文件系统的基本概念,以及如何设计简单的加载机制。 第七章:内存管理概览: 内存是操作系统最重要的资源之一。本章将介绍物理内存和虚拟内存的概念,以及初步的内存分配与回收策略。 第八章:保护模式下的内存管理: 在保护模式下,我们需要利用分页机制来管理内存。本章将详细讲解分页的工作原理,如何设置页目录和页表,以及实现基本的内存映射。 第三部分:进程与调度 第九章:中断与异常处理: 中断是操作系统响应外部事件和内部异常的关键机制。本章将讲解中断向量表(IVT)和中断描述符表(IDT),并实现基本的中断和异常处理程序。 第十章:键盘输入处理: 学习如何通过中断处理键盘输入,将用户的按键转换为可用的字符数据,这是实现人机交互的第一步。 第十一章:进程的概念: 引入进程的概念,理解进程的生命周期、状态转换以及进程控制块(PCB)的作用。 第十二章:简单的进程调度: 实现一个简单的进程调度算法(例如,先来先服务或循环轮转)。你将学习如何管理多个进程,并在它们之间切换执行。 第四部分:用户界面与设备驱动 第十三章:图形模式初探: 学习如何进入 VGA 图形模式,并在屏幕上绘制像素点、线条和简单的图形。这将为构建更友好的用户界面奠定基础。 第十四章:文本模式下的用户界面: 在图形模式尚未完善的情况下,我们将在文本模式下构建一个简单的命令行界面(CLI)。学习如何接收用户输入并显示输出。 第十五章:时钟中断与定时器: 利用可编程间隔定时器(PIT)产生时钟中断,为实现更精确的进程调度和定时任务提供基础。 第十六章:简单的设备驱动模型: 介绍设备驱动的基本概念,以及如何编写一个简单的设备驱动,例如与显示器或串行端口交互。 第五部分:文件系统与多任务 第十七章:文件系统基础: 探讨文件系统的作用,包括文件、目录、inode 等概念。我们将设计一个简单的文件系统结构。 第十八章:实现一个简单的文件系统: 动手实现一个基础的文件系统,支持文件的创建、读取、写入和删除操作。 第十九章:多任务与上下文切换: 深入理解多任务的原理,并学习如何实现进程的上下文切换,使多个进程能够并发执行。 第二十章:中断和异常的深入: 回顾中断和异常处理,学习如何处理更复杂的异常情况,并优化中断响应效率。 第六部分:系统调用与进阶 第二十一章:系统调用接口: 设计并实现一个系统调用接口,允许用户程序请求内核服务,例如文件操作、进程管理等。 第二十二章:用户模式与内核模式: 区分用户模式和内核模式,学习如何在两种模式之间安全地进行切换。 第二十三章:内存保护与隔离: 进一步强化内存保护机制,确保用户进程之间以及用户进程与内核之间内存的隔离,防止非法访问。 第二十四章:并发与同步: 学习并发编程中的挑战,例如竞态条件,并引入互斥锁(mutex)等同步机制来解决这些问题。 第七部分:高级特性与优化 第二十五章:驱动编写进阶: 学习编写更复杂的设备驱动,例如鼠标、硬盘等。 第二十六章:多处理器支持(可选): 如果时间允许,我们将简要介绍多处理器(SMP)系统的概念,以及如何为多核 CPU 进行基本适配。 第二十七章:简单的内存分配器: 设计并实现一个更高效的内存分配器,以满足不断增长的内存需求。 第二十八章:错误处理与调试技巧: 学习更高级的系统调试技巧,以及如何优雅地处理和报告系统错误。 第八部分:总结与展望 第二十九章:系统整合与测试: 将前面构建的各个模块整合起来,进行全面的测试,确保系统的稳定性和功能性。 第三十章:未来的方向与学习资源: 总结本次操作系统开发之旅,展望未来可以深入研究的方向,并推荐相关的学习资源和社区。 附带光盘内容 本书附带的光盘不仅仅是一张存储介质,更是你实践的强大助手。光盘中包含: 完整的源代码: 光盘中提供了本书所有章节代码的完整实现,你可以直接下载、编译和运行,作为学习和参考的宝贵资源。 开发工具链: 包含常用的交叉编译工具链(如 GCC for i386-elf)等,方便你快速搭建开发环境,避免因工具安装和配置带来的困扰。 模拟器镜像: 预先配置好的 QEMU 虚拟机镜像,你无需花费大量时间配置模拟器,即可快速启动你构建的操作系统进行测试。 参考文档与资料: 收集了与操作系统开发相关的技术文档、规范和推荐阅读列表,帮助你进一步深入学习。 常见问题解答(FAQ): 整理了在操作系统开发过程中可能遇到的常见问题及其解决方案,为你排忧解难。 本书的特色 理论与实践紧密结合: 本书不仅讲解操作系统的核心理论,更强调动手实践。每一章都伴随着具体的代码实现,让你在理论学习的同时,能够立即看到成果。 循序渐进的学习路径: 学习过程被分解为 30 个逻辑清晰的阶段,从最基础的汇编指令到复杂的进程调度和文件系统,层层递进,确保学习的连贯性和可理解性。 贴近实际的开发环境: 使用当下流行的开源工具链和模拟器,让你接触到的开发环境与真实世界的嵌入式系统或小型机开发环境相似。 注重细节和易懂性: 作者在讲解过程中,力求用最清晰的语言解释复杂的概念,并辅以大量的图示和代码注释,帮助读者快速掌握。 为读者赋能: 本书的目标是让你真正理解操作系统的运作机制,掌握系统级开发的必备技能,并有能力根据自己的需求进行扩展和创新。 适合读者 计算机科学与技术专业的学生: 深入理解操作系统课程的理论知识,并通过实践巩固。 有 C 语言基础的程序员: 渴望突破应用层开发,进入更底层的系统编程领域。 对计算机底层原理感兴趣的爱好者: 想要揭开计算机神秘面纱,了解“一切的根源”。 希望提升编程技能的开发者: 学习低级编程技巧,锻炼严谨的逻辑思维和强大的问题解决能力。 嵌入式系统开发者: 了解操作系统如何与硬件交互,为开发嵌入式系统打下坚实基础。 立即开始你的系统构建之旅! 《30天自制操作系统》将为你打开一扇通往计算机核心世界的大门。你将不再仅仅是用户,而是可以亲手塑造和控制这个数字世界的创造者。拿起这本书,插上光盘,让你的操作系统开发之旅,从今天开始!

用户评价

评分

我是一个对技术有着狂热追求的业余爱好者,一直梦想着能够亲手构建一个属于自己的操作系统。然而,这条路充满了挑战,各种知识点像迷雾一样笼罩着我。《30天自制操作系统》这本书,就像一束光,照亮了我前行的道路。它的语言风格非常接地气,没有过多的学术术语堆砌,而是用一种能够被普通读者理解的方式来解释复杂的概念。书中的每一个步骤都经过精心设计,能够引导读者逐步攻克难关。我最喜欢的部分是关于如何设计和实现内核的章节,作者用非常巧妙的比喻和图示,将原本抽象的内核工作原理变得生动形象。光盘里附带的源代码,更是让我爱不释手,我可以直接在虚拟机上运行,观察它的行为,并尝试进行修改,看看不同的参数设置会带来什么结果。通过这本书,我不仅学习到了操作系统的基本原理,还培养了解决实际问题的能力,更重要的是,我感受到了创造的乐趣。这本书绝对是每个有志于自制操作系统的人必不可少的伙伴。

评分

我是一名已经工作多年的软件工程师,虽然日常工作接触的是应用层开发,但一直对操作系统的底层细节感到好奇,总觉得不把这一块弄明白,对整个计算机体系的理解就不够透彻。市面上有些关于操作系统的书,动辄几百页,内容又晦涩难懂,看了几页就容易打退堂鼓。这本《30天自制操作系统》的出现,恰好满足了我这种“碎片化”学习的需求。它的篇幅不算特别厚重,而且“30天”这个概念也给了一个明确的学习目标。更重要的是,书中以非常务实的态度,从最基础的环节开始,一步步构建。我喜欢它那种“从小处着手,逐步完善”的思路,比如先实现一个简单的屏幕输出,再引入键盘输入,然后是中断处理等等。光盘提供的资源更是锦上添花,可以直接拿来运行和调试,这对于理解抽象的概念非常有帮助。虽然30天要“完全”掌握所有细节可能有些难度,但这本书绝对是一个非常好的入门和实践平台,让我能够快速对操作系统的核心有了一个清晰的认识。

评分

说实话,当我拿到这本《30天自制操作系统》的时候,心里是抱着一丝怀疑的。毕竟“30天”这个时限听起来就很有挑战性,我担心它会为了赶进度而牺牲内容的深度。但事实证明,我的担忧是多余的。这本书的作者显然对如何引导读者学习有着深刻的理解。它并没有试图在一开始就构建一个功能齐全的复杂系统,而是从最核心、最关键的部分入手,逐步增加功能。这种“由简入繁”的教学方法,让我能够专注于理解每个阶段的核心概念。书中的案例设计也非常贴切,比如,在讲解中断处理时,作者会引导读者实现一个简单的键盘输入响应,这比单纯的理论讲解要生动有趣得多。我特别喜欢书中对一些常见误区的提醒和解释,这大大节省了我自己摸索的时间。光盘里的资源也非常丰富,包含了不同阶段的操作系统代码,方便我对比和学习。虽然30天完成一个完整的操作系统可能需要付出大量的努力和时间,但这本书提供了一个非常坚实的基础和清晰的路径,让我看到了实现这个目标的可能性。

评分

这本书简直是为我量身定做的!我是一名在校的计算机专业学生,一直在寻找能够真正将理论知识付诸实践的项目。传统的操作系统课程虽然有讲解,但总感觉缺少了那种“亲手打造”的感觉。《30天自制操作系统》正是弥补了这一遗憾。它不仅仅是一本书,更像是一位经验丰富的导师,耐心地引导我一步步探索操作系统的世界。我尤其欣赏书中对每一项技术的讲解,比如如何编写汇编语言的引导程序,如何理解CPU的执行流程,以及如何实现简单的内存管理。这些内容虽然在其他教材中可能有所提及,但这本书将它们串联起来,形成了一个完整的学习链条。光盘中的源代码更是宝藏,我不仅可以运行它,还可以尝试修改和扩展,看看不同的设计会带来什么样的效果。通过这本书,我不仅巩固了课堂上学到的知识,还学到了很多书本上没有的实践技巧。我甚至开始思考,如何将书中的一些模块应用到我自己的课程设计项目中。

评分

这本书绝对是技术学习者的一场及时雨!我一直对操作系统底层运作原理充满好奇,但市面上很多书籍要么过于理论化,要么需要扎实的计算机体系结构基础。这本《30天自制操作系统》的出现,恰恰填补了这个空白。它以一种非常直观、循序渐进的方式,带领读者一步步构建自己的操作系统。从最基础的 bootloader 到内核的初始化,再到简单的内存管理和任务调度,每一个章节都设计得恰到好处,不会让人望而却步。最让我惊喜的是,它提供了配套的光盘,里面包含了大量的源代码和调试工具,这对于动手实践来说至关重要。我花了整整一个周末,跟着书里的代码一点点调试,看着自己的代码在虚拟机里运行起来,那种成就感是难以言喻的。书中的讲解清晰易懂,即使是初学者也能理解其中的逻辑。而且,它并不是简单地复制代码,而是深入浅出地解释了每一行代码的意义和作用,这对于建立深层次的理解非常有帮助。总的来说,这本书是一次非常棒的学习体验,我强烈推荐给所有对操作系统感兴趣的朋友。

评分

???????

评分

不错,看着不错先买了,闲暇之时值得一读。

评分

不错,有必要了解一下编程语言的执行过程

评分

国内很少有日本人写的计算机书籍。买来看一下。

评分

京东购物方便快捷 发货快

评分

这书很好,能帮助你理解操作系统细节,我很满意,尤其京东送货速度就是飞快啊!!!!

评分

。。。。。。。。

评分

书质量不错,,,

评分

看不懂,不过还是要认真看。

相关图书

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 book.idnshop.cc All Rights Reserved. 静思书屋 版权所有