开发一个最简单的"操作系统"全过程

开发一个最简单的“操作系统”全过程

“FC简单”引导扇区初探 v0.1

===========================

作者:Weichao Liu

[写在前面gaga]

写一个PC 机的引导程序比我们想象的容易很多,事实上所需要了解的只是知道PC 机是怎样启动的。在网上看到不少类似的文章,说的很多,有的很麻烦,笔者觉得仅仅是写一个引导程序完全没有必要牵涉太多东西,知道足够的知识用于去实际地写一个出来看看是很多人最初的目的,那这篇文章就刚好适合你了。这篇文章的立足点就是短、简单、一看就懂,而又不会看完了什么都不知道就写出一个连自己都看不懂的代码。

另外,机器人天空重新改版,笔者兴奋的看到了一个真正的机器人网站,囊括了机器人科学与技术这样庞大的系统工程的各个方面,在此献上这篇文章给机器人天空的操作系统专栏,祝愿机器人天空越办越好,并能够为中国的机器人爱好者们带来更多更丰富的信息与资源,做更多的实事!同时,也希望广大的机器人爱好者和有识之士都能出一份力,为祖国更美好的明天共同努力!笔者与您共勉。

现在,让我们开始引导程序初探!

[什么?]

很多文章中把写一个引导程序称作是开发一个最简单的操作系统,其实这是非常片面的,引导程序算不上操作系统,虽然此程序可以运行在裸机上。所谓引导程序,直观的说就是在系统加电启动时BIOS 第一个执行的程序。

引导程序要想发挥作用,让机器识别,就必须安置在一个特别的位置,这个位置就是磁盘的第一个扇区(0面0磁道1扇区,备注:没有0扇区),而一个包含引导程序的扇区叫作引导扇区。

一个合法的引导扇区(1)通常包含512个字节(当然喽,一个扇区通常本来就是512个字节),(2)并且以0xAA55这样一个占用两个字节的数据结尾作为标志符。(备注:0x 前缀说明这是一个十六进制数)。

也就是如果把引导扇区看成一个字符数组的BootSector[]话(因为一个字符,即char ,刚好为一个字节),那么这个数组就拥有512个元素,如果用C 语言申明的话即为 char BootSector[512];

接着,一个合法的引导扇区必须以0xAA55结束,即

BootSector[510] = 0x55;

BootSector[511] = 0xAA;

除了结束标志必须符合上面的要求之外,中间虽然还有510字节的空间,但执行代码可以少于510字节,用无意义字符(通常用0x0)填充剩余空间即可。

[过程!]

PC 是通过BIOS 来启动机器的,当PC 机加电之后BIOS 启动相应的程序完成机器的自检,然后就寻找可以引导的驱动器,即大家通常所说的启动盘。在BIOS 中可以设置从哪个盘启动,但通常总要检查硬盘,所以当BIOS 检查完前面的启动设备之后,如果没有发现任何引导程序,那么就会开始检查主硬盘,即C 盘。如果此时在C 盘上找到了合法的引导扇区,那么就会将引导扇区的内容(共512字节)装载到内存0x0000:07C00处。此时BIOS 把控制权限交给这段引导程序。

那么,接下来,引导程序通常会简单的执行一些指令,比如输出一段文字,显示一个启动界面等等,但最重要的,引导程序将会启动一个更大的程序,然后把权限交给他,这通常就是我们所说的操作系统内核。额外补充一句,目前对操作系统的定义有不少,但笔者比较赞成的观点如下:

从形式上看,操作系统是:从计算机启动到结束的过程中始终在运行的程序。而这通常就是我们所说的操作系统内核。从功能上看,操作系统:管理和维护所有的硬件、软件、数据资源,并为上层应用或服务提供一个抽象的接口。从某种层面上看,第二中定义更接近于虚拟机。(闲话一段^_^)

[如何?]

现在,已经了解了这些基本的概念,那么,如何动手制作这样的引导扇区呢?这个过程十分简单,

(1)首先按照要求写一个合法的引导程序(通常用汇编,机器码也可以,呵呵);

(2)然后将其通过汇编程序,如NASM 汇编成二进制文件;

(3)最后,将这个二进制文件写入到目标盘的第一个扇区。

[跟我做:-P]

上面说的很简单吧?那好,现在我们来写一个吧!

第一步:写代码

; 文件名:boot.asm

; 代码如下,注意,汇编中通常用“;”来表示注释内容

; 此段代码参考《自己动手写操作系统》(于渊)

;

; 初始化函数

org 07c00h ; 告诉编译器将此段程序加载

; 到内存0x0000:07C00处

mov ax, cs

mov ds, ax

mov es, ax

call PrintStr ; 调用屏幕打印函数

jmp $ ; 无限循环

PrintStr: ; 屏幕打印函数

mov ax, HelloWorld ; 将字符串拷贝到ax

mov bp, ax ; es:bp = 串地址

mov cx, 24 ; cx = 串长度

mov ax, 01301h ; ah = 13, al = 01h

mov bx, 000ch ; 页号为0(bh = 0) 黑底红字(bl = 0ch,高亮) mov dl, 0

int 10h ; 10h号中断

ret

HelloWorld: db "Welcome to Lee's OS *_*" ; 字符串负值

times 510-($-$$) db 0 ; 用0x0填充剩余的空间使生成

; 的二进制代码刚好为512字节

dw 0xaa55 ; 结束标志

; 整个程序结束!很短吧

第二步:汇编

假设你已经安装了NASM 程序,那么进入命令行模式,然后输入以下命令:

C:[PATH]\ nasm boot.asm -o boot.bin

其中“C:[PATH]\”为boot.asm 代码文件所在位置。

现在如果不出意外的话,你已经拥有了boot.bin 二进制文件,这个就是引导程序!

第三步:制作引导盘

由于不能随便更改硬盘,否则系统无法进入原来的操作系统,所以我们用软盘来试验。 那么,我们准备一张软盘。

现在,我们要自己写一个程序将我们汇编得到的二进制文件写到软盘的第一个扇区。 C 语言程序代码如下:

/***************START***************/

#include

#include

int main(void)

{

FILE *in;

unsigned char buffer[520];

if((in = fopen("boot.bin", "rb"))==NULL)

{

printf("Error loading file\n");

exit(0);

}

fread(&buffer, 512, 1, in);

while(biosdisk(3, 0, 0, 0, 1, 1, buffer));

fclose(in);

return 0;

}

/****************END****************/

注意,这个程序必须同boot.bin 文件在同一目录下,然后将软盘放进软驱,运行此程序。 第四步:GOGOGO

好了,现在你拥有了一张从头到尾完全自制的引导盘,由于有了她,你想运行你的电脑再也不需要微软插手了,而且这很可能是你第一次能在裸机上运行一个自己的程序哦,哈哈! 重新启动你的机器,记得把软盘放进去,现在你看见什么了?

一行醒目的红字:

Welcome to Lee's OS *_*

打印在屏幕上!

[写在后面]

本文完整的讲述了编写引导程序的过程,其中肯定会有一些不足,欢迎指正。另外,对于有各种其他想法,如希望在虚拟PC 上尝试的人,那么只需要查找相应方法就可以。这是本文的第一个版本,如果有必要,后面还可能继续更新:-)

开发一个最简单的“操作系统”全过程

“FC简单”引导扇区初探 v0.1

===========================

作者:Weichao Liu

[写在前面gaga]

写一个PC 机的引导程序比我们想象的容易很多,事实上所需要了解的只是知道PC 机是怎样启动的。在网上看到不少类似的文章,说的很多,有的很麻烦,笔者觉得仅仅是写一个引导程序完全没有必要牵涉太多东西,知道足够的知识用于去实际地写一个出来看看是很多人最初的目的,那这篇文章就刚好适合你了。这篇文章的立足点就是短、简单、一看就懂,而又不会看完了什么都不知道就写出一个连自己都看不懂的代码。

另外,机器人天空重新改版,笔者兴奋的看到了一个真正的机器人网站,囊括了机器人科学与技术这样庞大的系统工程的各个方面,在此献上这篇文章给机器人天空的操作系统专栏,祝愿机器人天空越办越好,并能够为中国的机器人爱好者们带来更多更丰富的信息与资源,做更多的实事!同时,也希望广大的机器人爱好者和有识之士都能出一份力,为祖国更美好的明天共同努力!笔者与您共勉。

现在,让我们开始引导程序初探!

[什么?]

很多文章中把写一个引导程序称作是开发一个最简单的操作系统,其实这是非常片面的,引导程序算不上操作系统,虽然此程序可以运行在裸机上。所谓引导程序,直观的说就是在系统加电启动时BIOS 第一个执行的程序。

引导程序要想发挥作用,让机器识别,就必须安置在一个特别的位置,这个位置就是磁盘的第一个扇区(0面0磁道1扇区,备注:没有0扇区),而一个包含引导程序的扇区叫作引导扇区。

一个合法的引导扇区(1)通常包含512个字节(当然喽,一个扇区通常本来就是512个字节),(2)并且以0xAA55这样一个占用两个字节的数据结尾作为标志符。(备注:0x 前缀说明这是一个十六进制数)。

也就是如果把引导扇区看成一个字符数组的BootSector[]话(因为一个字符,即char ,刚好为一个字节),那么这个数组就拥有512个元素,如果用C 语言申明的话即为 char BootSector[512];

接着,一个合法的引导扇区必须以0xAA55结束,即

BootSector[510] = 0x55;

BootSector[511] = 0xAA;

除了结束标志必须符合上面的要求之外,中间虽然还有510字节的空间,但执行代码可以少于510字节,用无意义字符(通常用0x0)填充剩余空间即可。

[过程!]

PC 是通过BIOS 来启动机器的,当PC 机加电之后BIOS 启动相应的程序完成机器的自检,然后就寻找可以引导的驱动器,即大家通常所说的启动盘。在BIOS 中可以设置从哪个盘启动,但通常总要检查硬盘,所以当BIOS 检查完前面的启动设备之后,如果没有发现任何引导程序,那么就会开始检查主硬盘,即C 盘。如果此时在C 盘上找到了合法的引导扇区,那么就会将引导扇区的内容(共512字节)装载到内存0x0000:07C00处。此时BIOS 把控制权限交给这段引导程序。

那么,接下来,引导程序通常会简单的执行一些指令,比如输出一段文字,显示一个启动界面等等,但最重要的,引导程序将会启动一个更大的程序,然后把权限交给他,这通常就是我们所说的操作系统内核。额外补充一句,目前对操作系统的定义有不少,但笔者比较赞成的观点如下:

从形式上看,操作系统是:从计算机启动到结束的过程中始终在运行的程序。而这通常就是我们所说的操作系统内核。从功能上看,操作系统:管理和维护所有的硬件、软件、数据资源,并为上层应用或服务提供一个抽象的接口。从某种层面上看,第二中定义更接近于虚拟机。(闲话一段^_^)

[如何?]

现在,已经了解了这些基本的概念,那么,如何动手制作这样的引导扇区呢?这个过程十分简单,

(1)首先按照要求写一个合法的引导程序(通常用汇编,机器码也可以,呵呵);

(2)然后将其通过汇编程序,如NASM 汇编成二进制文件;

(3)最后,将这个二进制文件写入到目标盘的第一个扇区。

[跟我做:-P]

上面说的很简单吧?那好,现在我们来写一个吧!

第一步:写代码

; 文件名:boot.asm

; 代码如下,注意,汇编中通常用“;”来表示注释内容

; 此段代码参考《自己动手写操作系统》(于渊)

;

; 初始化函数

org 07c00h ; 告诉编译器将此段程序加载

; 到内存0x0000:07C00处

mov ax, cs

mov ds, ax

mov es, ax

call PrintStr ; 调用屏幕打印函数

jmp $ ; 无限循环

PrintStr: ; 屏幕打印函数

mov ax, HelloWorld ; 将字符串拷贝到ax

mov bp, ax ; es:bp = 串地址

mov cx, 24 ; cx = 串长度

mov ax, 01301h ; ah = 13, al = 01h

mov bx, 000ch ; 页号为0(bh = 0) 黑底红字(bl = 0ch,高亮) mov dl, 0

int 10h ; 10h号中断

ret

HelloWorld: db "Welcome to Lee's OS *_*" ; 字符串负值

times 510-($-$$) db 0 ; 用0x0填充剩余的空间使生成

; 的二进制代码刚好为512字节

dw 0xaa55 ; 结束标志

; 整个程序结束!很短吧

第二步:汇编

假设你已经安装了NASM 程序,那么进入命令行模式,然后输入以下命令:

C:[PATH]\ nasm boot.asm -o boot.bin

其中“C:[PATH]\”为boot.asm 代码文件所在位置。

现在如果不出意外的话,你已经拥有了boot.bin 二进制文件,这个就是引导程序!

第三步:制作引导盘

由于不能随便更改硬盘,否则系统无法进入原来的操作系统,所以我们用软盘来试验。 那么,我们准备一张软盘。

现在,我们要自己写一个程序将我们汇编得到的二进制文件写到软盘的第一个扇区。 C 语言程序代码如下:

/***************START***************/

#include

#include

int main(void)

{

FILE *in;

unsigned char buffer[520];

if((in = fopen("boot.bin", "rb"))==NULL)

{

printf("Error loading file\n");

exit(0);

}

fread(&buffer, 512, 1, in);

while(biosdisk(3, 0, 0, 0, 1, 1, buffer));

fclose(in);

return 0;

}

/****************END****************/

注意,这个程序必须同boot.bin 文件在同一目录下,然后将软盘放进软驱,运行此程序。 第四步:GOGOGO

好了,现在你拥有了一张从头到尾完全自制的引导盘,由于有了她,你想运行你的电脑再也不需要微软插手了,而且这很可能是你第一次能在裸机上运行一个自己的程序哦,哈哈! 重新启动你的机器,记得把软盘放进去,现在你看见什么了?

一行醒目的红字:

Welcome to Lee's OS *_*

打印在屏幕上!

[写在后面]

本文完整的讲述了编写引导程序的过程,其中肯定会有一些不足,欢迎指正。另外,对于有各种其他想法,如希望在虚拟PC 上尝试的人,那么只需要查找相应方法就可以。这是本文的第一个版本,如果有必要,后面还可能继续更新:-)


相关内容

  • 软件开发的流程
  • 软件开发流程 迭代化软件开发技术 1. 传统开发流程的问题 传统的软件开发流程是一个文档驱动的流程,它将整个软件开发过程划分为顺序相接的几个阶段,每个阶段都必需完成全部规定的任务(文档)后才能够进入下一个阶段.如必须完成全部的系统需求规格说明书之后才能够进入概要设计阶段,编码必需在系统设计完成之后才 ...

  • 如何选择配置管理工具--一丝布挂的敌人
  • 每一个软件项目,无论是工程类项目,还是产品类项目,都必须经历需求分析.系统设计.编码实现.集成测试.部署.交付.维护和支持的过程.在这个过程中,将生成各种各样不同的工件,包括文档.源程序.可执行代码.支持库.更可怕的是,频繁出现的变更是不可避免的,因此面向如此庞大且不断变动的信息集,如何使其有序.高 ...

  • 软件开发方法与过程
  • (1)软件开发过程是什么?  软件开发过程是按照软件工业化的标准定义的 在软件开发中必须具有的一系列过程规范:  软件开发过程是定义在软件中的软件需求.软件 设计.软件编码.软件测试.软件部署的实现目标和规范化的管理方法论:  软件开发过程是保证软件工业化生产的法典:  软件开发过程做的是: ...

  • 网页游戏开发入门教程
  • 网页游戏开发入门教程 网页, 入门, 教程, 游戏, 开发网页, 入门, 教程, 游戏, 开发 一.简单的程序框架. webgame程序构成: 三大部分. 第一是数据流程.第二是程序.第三是美术. 其中,数据流程包括了功能.也只有在功能中才能体现数据流程. 数据流程相当的麻烦,后面再讨论. 比如最简 ...

  • 学习NIOS-II的经验分享
  • 学习 NIOS-II 的流程-1--资料的准备--艾米电子工作室声明:本文系站长的个人经验分享,不是专业人士的评论,如有瑕疵,还望见谅! NIOS 即为 NIOS II 的缩写!本人学习 NIOS 的时间不算很长,也就 2 年多,开始接触 NIOS 就是从我们的一个实际项目出发的,以前一直学 习逻辑 ...

  • 干洗店管理系统
  • 目录 摘要 . ............................................................................................................ 1 序言 . .......................... ...

  • 学生选课系统可行性分析报告
  • 文档编号:RS-4 版本号:1.0.0 学生选课系统 可行性分析报告 项目名称:学生选课系统 项目负责人:路景 项目开发小组:软三四组 修改记录: 学生选课系统可行性分析报告 1. 引言 当今社会是一个讲求效率的社会,时间就是金钱.开发简单,易于操作的 管理软件不仅可以节省时间,还可以避免浪费人力, ...

  • 软件工程概念.原理
  • 第一部分 <传统软件开发方法>重点内容 1.软件危机是指在计算机软件的开发和维护过程中所遇到的一系列严重问题. 2.软件危机包含下述两方面的问题:①如何开发软件,以满足对软件日益增长的需求:②如何维护数量不 断膨胀的已有软件. 3.软件危机产生的原因 一方面与软件本身的特点有关,另一方面 ...

  • [人机交互与界面设计]实践项目
  • 课程设计项目 项目1 Windows软件界面设计(12学时) ⒈ 目的与要求 在熟练掌握人机界面相关原则和开发方法的基础上,考察对人机界面的设计理念和原则的掌握程度,使学生能够将相关理论和知识应用于实际系统的开发中.通过设计一个简单的Windows软件界面,进一步理解人机界面设计方法及其在实际软件开 ...