自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(30)
  • 资源 (2)
  • 收藏
  • 关注

原创 PE可选头

紧跟着PE文件头的,是一个叫做PE可选头(Optional Header)的数据结构。这个数据结构被叫做可选头是因为某些PE格式文件,比如目标文件(.OBJ)没有这个数据结构。但是对于一个可执行文件或动态链接库来说,这个数据结构是必须的。可选头由4部分组成,第一部分是一个PE可选头签名。通过检查这个签名,我们可以知道这是一个32位的可选头还是64位的可选头。我们现在只介绍32位的可选头。

2009-10-21 13:59:00 1514

原创 CSDN博客不支持FireFox?

刚才文章中使用了表格,居然只能用IE看了,难道是CSDN的Bug?

2009-10-20 15:17:00 720 1

原创 PE文件头

大体上,PE文件由下面几个部分组成,DOS头,PE头,可选头,节表,以及各节的数据。这些数据结构在文件中的位置如下图所示。 PE文件的第一部分是一个DOS头,一般我们称之为DOS STUB。 这个DOS头实际上就是一个完整的DOS应用程序。这样当你在DOS下试图运行这个程序的时候,DOS将会把它识别成一个DOS可执行程序。一般这个DOS STUB会在屏幕上打印一条信息“该程序需要W

2009-10-20 13:51:00 2319 2

原创 PE文件格式

到现在为止,我们已经完成的足够的代码来从硬盘上读出一个文件了。我们的操作系统内核将以一个DLL文件的形式放在硬盘上。而RMOSLDR会负责把这个内核文件读进来。但是现在还有一个问题。既然内核是一个DLL文件,那么,我们该如何加载一个DLL文件呢?这就牵涉到Windows上可执行文件的格式。Windows上的可执行文件格式被称为PE(Portable Executable)格式。PE格式可以

2009-10-13 11:32:00 748

原创 文件系统(六)

到现在为止,整个文件系统还有最后一个重要功能没有实现,那就是读文件。现在我们就来看看这个功能是怎么实现的。 首先自然是FAT16File对象的构造函数,很简单。FAT16File::FAT16File(System::Boot::FAT16 *fs, struct Entry *pEntry){ m_fs = fs; memcpy(&m_entry, pEntry, siz

2009-09-24 16:28:00 651

原创 文件系统(五)

FAT16文件系统的根目录处理方式和其他目录有点不同。区别在于根目录的空间不是由文件分配表管理的,而是格式化时预留的。我们可以从BPB数据中计算出根目录的各个扇区的位置。因此取GetSubDirectory方法的实现如下。/* * Get a list of all directories in root * We will get the boot sector of device

2009-09-21 20:25:00 604

原创 文件系统(四)

这一节中我们来看下FAT16目录的实现 首先自然是构造函数FAT16Directory::FAT16Directory(System::Boot::FAT16 *fs, struct Entry *pEntry){ m_fs = fs; memcpy(&m_entry, pEntry, sizeof(struct Entry));}  其中Struct En

2009-09-20 17:41:00 605

原创 文件系统(三)

现在我们来看一下上一节提到的几个类的各个主要方法的实现。 FAT16类的构造函数非常简单:FAT16::FAT16(System::Boot::IBlockDevice *pDevice){    m_pDevice = pDevice;}  其次是GetRootDirectory方法,实现这个方法只需生成一个根目录对象即可,后面我们会介绍这个FAT16Root

2009-09-20 10:55:00 542

原创 文件系统(二)

为了实现读取FAT16文件系统,我们需要为FAT16实现上节提到的那些接口,先看 IFileSystem接口 /** * This Class is a read-only FAT-16 file system. A file system can be created on a * block device */ class FAT16 : public IFil

2009-09-09 10:37:00 628

原创 文件系统(一)

又是文件系统。前面已经提到过一次文件系统的实现了,为什么这里还要再介绍一边文件系统呢?原因是前面介绍的文件系统访问比较简单,仅仅是读取固定的几个文件。而这里,为了保证装载器的灵活性,这里的文件系统设计复杂多了。而且由于是C++实现,代码可读性也提高了。以后在内核中,我们还需要处理一次文件系统,那是操作系统中正式使用的文件系统。这里我们先来看一个相对简单的实现。   上图中,

2009-08-24 21:34:00 944 1

原创 访问硬盘(四)

下面我们来实现IDEHardDrive这个类。IDEHardDrive将真正和硬盘硬件打上交道,假如你已经忘了该如何操作硬盘,请参考前面的介绍。 废话少说,我们先来看构造函数 #include using namespace System::Boot;IDEHardDrive::IDEHardDrive(unsigned int IOBase){ m_IO

2009-08-20 20:12:00 820

原创 访问硬盘(三)

现在我们来实现上一节提到的几个类。首先是主分区类。这个类的构造函数十分简单。using namespace System::Boot;MainPartition::MainPartition(IBlockDevice *pDevice, int start, int size, System::Boot::VGA * pVga){ m_pDevice = pDevice;

2009-08-18 20:56:00 881

原创 访问硬盘(二)

这一节我们来看下RMOSLDR中硬盘驱动的各个接口 首先我们需要一个C++块设备接口。这个接口将实现设备的分块读取。硬盘驱动器,光盘驱动器,USB驱动器都要实现这个接口。换句话说,只要某个设备实现了这个接口,就可以在其上建立文件系统。  class IBlockDevice { public: virtual void Open() = 0; virtual v

2009-08-17 20:41:00 1080 2

原创 访问硬盘(一)

在实现显卡驱动后,我们下一个必须要访问的硬件就轮到硬盘了。同样的,在保护模式下,所有的BIOS中断例程都无法使用,当然也包括硬盘服务INT 13H。所以我们必须通过直接读写端口来访问硬盘。 硬盘有一个接口标准,叫做ATA/ATAPI。这个标准现在已经发展到第8版,里面甚至包括了串行ATA的内容。但是由于我们的虚拟机不支持如此最新的ATA标准,因此我们只能按照旧标准来操作硬盘。 对于

2009-08-17 09:08:00 2857 1

原创 简单的VGA字符模式驱动(二)

上节介绍了访问VGA显卡显存的方法。现在我们要在屏幕上设置光标了。光标和显存不一样。它必须通过显卡的I/O端口开控制。 VGA显卡内部有一系列寄存器可以用来控制显卡的状态。在标准的PC机上。 0x3d4和0x3d5两个端口可以用来读写显卡的内部寄存器。方法是先向0x3d4端口写入要访问的寄存器编号,再通过0x3d5端口来读写寄存器数据。存放光标位置的寄存器编号为14和15。两个寄存器合起来

2009-08-12 14:19:00 3082

原创 简单的VGA字符模式驱动(一)

进入保护模式后,我们就彻底与BIOS例程说再见了。BIOS下的几乎所有中断例程都是实模式的代码。int 10h 的显示功能自然也是如此。 如今我们已经处于保护模式,因此为了在屏幕上显示东西,我们只有自己通过直接访问硬件来实现了。幸好,作为第一个必须实现的驱动,字符模式下的显卡驱动并不是太复杂。 历史上显卡的标准有许多个,从最早的CGA到现在的VESA都曾经占有过市场。幸好,如今的显卡全部支

2009-08-11 22:09:00 4713 5

原创 Rome自举部分代码已上传

 刚整理了一下代码,把整个自举部分的框架传到了网上,大家可以在这里下载到:http://download.csdn.net/source/1552695 解压后,进入Gemini/Build目录下,运行BuildOS.exe。在这个窗口中输入Gemini目录的绝对路径  点击Build后,你应该会看到一个蓝色的命令行窗口。我的Visual Studio安装在D:/P

2009-08-06 23:07:00 944

原创 自己的CRT (一)

已经2天没有更新了。这两天有点忙。下面继续:) 当我们用C++来编写操作系统的时候,我们不能随便制定一个程序的入口点。 在C++中,静态对象必须在main函数之前被构造。换句话说,我们在C++的入口函数中必须要做的一件事是调用静态对象的构造函数。但是我们怎么去调用那些构造函数呢? 在Visual C++里,编译器会做一些处理,使得我们可以拿到静态对象初始化的入口点。下面的代码可以用

2009-07-29 15:39:00 1032 2

原创 Visual C++ 编译链接选项的设置

上一节说道,汇编语言的代码已经告一段落了,接下来我们将进入C++的世界了。但是Visual C++不是被设计用来开发操作系统的。假如我们用Visual C++设计一个程序,那么在默认情况下,它必须跑在Windows下。所以我们必须做一些工作使得我们的程序能够脱离Windows运行。 因此,为了达到这个目的,我们必须对Visual C++的编译选项做一些特殊的配置。 首先,我们不能链接 Vi

2009-07-26 20:56:00 1498 2

原创 操作系统的引导(三)

再学习了前面那些背景知识后,我们可以继续引导操作系统了。 在《操作系统的引导(二)》一篇中,我们已经通过分区引导程序将文件系统中的引导程序RMOSLDR加载到了内存5000:7C00的地方。现在我们来编写RMOSLDR把操作系统的内核从硬盘加载到内存中。RMOSLDR有两部分,第一部分是实模式汇编语言的部分,而第二部分则是C++的代码。这一节中我们先来编写汇编语言的部分 ;;;

2009-07-23 20:11:00 918 2

原创 PC寻址方式遗留问题——A20地址线

在8086/8088CPU上,总共有20根地址线,可以寻址1M内存空间。但是8086的寻址方式却事实上可以访问到1M+64K的地址空间。想象一下,当段寄存器的值为FFF0h,而断内偏移为1000h的时候,通过段地址*16+偏移地址计算出来的物理地址是100F00h,而这已经超过了1M的地址范围!但是由于8086/8088只有20根地址线,因此,第20位被丢失了。实际上这个段地址和偏移地址的组合

2009-07-22 11:15:00 1510

原创 Intel CPU的保护模式和段式内存管理简介

在操作系统原理的教材上,我们学到虚拟内存的管理方式有3种,段式内存,页式内存,和段页式内存。Intel的CPU同时支持段式内存和页式内存。我们在这一篇中先介绍段式内存。我们知道,Intel CPU在启动后处于实模式(Real Mode)。在实模式下,CPU可以管理1M内存。由于现代计算机上的内存早以远远超过了1M,Intel CPU从80386开始提供了一个新的模式,保护模式,在保护模

2009-07-21 20:48:00 3179

原创 内存大小的检测

 在上一篇中,我们已经实现了由引导程序加载FAT16系统上的引导装载程序。从现在开始我们将开始编写这个引导装载程序RMOSLDR。这个程序将由2部分组成。第一部分依然是一个汇编语言的程序。它将会把CPU切换到保护模式,并且设置C++的运行环境。而RMOSLDR的第二部分将由C++编写,这段C++代码将会负责把PE格式的操作系统内核从文件系统中加载到内存。在编写这段程序之前,我们还是要先

2009-07-20 13:35:00 2755 1

原创 操作系统的引导(二)

在操作系统引导(一) 一篇中,我们已经完成了MBR程序的编写。通过BOCHS调试,我们可以看到分区引导扇区被读入了07c0:0000处。 现在我们要完成分区引导扇区的编写。在分区引导扇区中,最主要的任务就是从FAT16文件系统中加载真正的操作系统装载程序到内存5000:7C00处。和MBR代码一样,这段代码基本参考了Singularity的代码。 由于我们已经掌握了基本的FAT16

2009-07-17 22:05:00 988 1

原创 16位链接器

我在《操作系统的引导(一)》一文中提到了一个16位的链接器。但是这个链接器不是Visual Studio2005的一部分。读者可以在下面的链接出下载到这个链接器Link16.exe http://download.csdn.net/source/1495637

2009-07-16 22:11:00 952

原创 FAT16文件系统简介(二)

上篇我们介绍了FAT16文件系统的引导扇区,本篇将继续介绍FAT16文件系统紧接着引导扇区的就是文件分配表结构。文件分配表到底是一个什么东西呢?大家可以回忆一下操作系统原理课程上讲过,文件系统的组织方式有两种:索引和链表。其中链表式组织方式的典型代表就是FAT文件系统家族。在FAT16文件系统中,磁盘空间以簇为单位分配。每簇为2-64个扇区。文件分配表是一个16位整数类型的大数组,数组

2009-07-15 14:46:00 2254

原创 FAT16文件系统简介(一)

 我们在前面已经完成了主引导扇区程序的编写。通过主引导记录,我们已经实现了装入分区引导扇区执行的操作。和主引导扇区一样,分区引导扇区也只有区区512个字节,根本不可能放得下所有的代码来将以操作系统内核装入内存,完成重定位工作并设置内核的运行环境。 应次,分区引导扇区也只能做一件事,那就是把真正的操作系统装载程序(RMOSLDR)从文件系统读入内存

2009-07-12 21:40:00 3367

原创 硬盘分区表简介

毫无疑问,大多数人都有过对硬盘分区的经验。一块刚买来的新硬盘,必须要经过分区之后才能使用。但是具体的分区信息在硬盘上是怎么存储的呢?分区后的硬盘上有一个重要的数据结构,叫做硬盘分区表。这个数据结构就是保存分区信息的地方。一般来说,硬盘分区表的第一部分(主分区表)位于硬盘的第一个扇区(主引导记录)中。占据这个扇区的第446-510个字节。这是一个4个元素的数组,每一项代表

2009-07-10 23:26:00 1955 1

原创 操作系统的引导(一)

操作系统执行的第一步,自然是将自身装入内存。自己将自己装入内存,这听起来有点不可思议:操作系统不可能是全部由自身装入的。因为在自身被装入系统前,操作系统根本不可能运行。因此,操作系统的某一部分必然是被硬件直接装入内存的。一般来说,一个计算机系统会和操作系统约定:系统启动后会将启动设备(如硬盘)上的某个固定位置的程序装入内存。而操作系统则将它的第一部分放在约定的位置,从而可以被硬件装入内存

2009-07-08 21:24:00 1643 1

原创 开始动工

正如大家所知,操作系统是一个计算机系统最底层,最核心的软件。我自从最早学习计算机开始,就对操作系统非常着迷。学习操作系统最好的办法自然是自己编写一个操作系统。我在高中时就自学了操作系统原理。后来也曾自己编写过一个迷你型的操作系统,大约有10000行左右的源代码。但是,那个系统写的并不好,到处是BUG。内存泄露严重。经常莫名其妙死机。同时我也没有实现太多的API。仅仅实现了fork, open, r

2009-07-07 15:16:00 1389 7

Rome OS 自举部分代码框架

这是我整理出来的Rome OS自举部分的框架。

2009-08-06

link16.exe

微软的16位链接器.可以将16位目标文件链接成BIN格式。

2009-07-16

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除