分享
 
 
 

简易软盘镜像工具的实现及操作系统编写初步

王朝vc·作者佚名  2006-05-23
窄屏简体版  字體: |||超大  

简易软盘镜像工具的实现及操作系统编写初步

作者:liu_sir

下载源代码

摘要

本文给出了软盘镜像生成工具的实现,并用其把自己编译生成的引导文件制作成软盘镜像,写入软盘实现一个简单操作系统的引导。

关键词 软盘镜像工具 操作系统引导。

为了深入的了解80X86计算机的内部原理,参照别人的程序用汇编写了几个小程序。但生成软盘镜像的工具大都是DOS版本的,于是就想自己用VC也实现一个,并用把自己的引导程序写入软盘上验证一下。

1、镜像工具的基本原理

镜像工具读取磁盘上的文件,然后安装一定的格式生成软盘镜像文件,最后把软盘镜像文以512字节扇区为单位,写入软盘上。

2、镜像工具的界面设计及功能介绍

图1 主界面

2.1 【功能1】生成软盘镜像文件

(1)要生成镜像文件,需要先选择源文件,然后点击【生成…】,如MyDiskImg.img,点击【保存】生成镜像文件。

图2 生成镜像文件

(2)然后插入一张软盘,点击写软盘,选择刚生成的镜像文件。点击【打开】,系统便开始把选择的镜像文件写入软盘中。

图3 把镜像文件写入软盘

(3)重新启动计算机,选择从软盘启动,看操作是否成功。

3、具体代码编写

3.1 生成软盘镜像代码

基本原理为对列表中的源文件依次读取,然后写入到一个img文件中,具体的代码请参考(省略了部分不关键代码):

//生成镜像文件函数

UINT FuncGenImageFile(LPVOID pDialog)

{

//Begin 显示设置

省略…

//1.创建输出镜像文件

byte* pBuf = NULL;

DWORD count = 0,dwFileLength=0;

CFile outfile;//镜像文件

if(!outfile.Open(pCurDlg-m_ImgFileName,CFile::modeCreate | CFile::modeWrite))

{

错误提示…

return -1;

}

//2.依次对输入文件读取,写入输出镜像文件

for( int i = 0 ; i GetCount(); ++i )

{

CString sInFileName;

pList-GetText(i,sInFileName);

CFile infile;

if(!infile.Open(sInFileName,CFile::modeRead))

{

错误提示…

return -1;

}

dwFileLength = infile.GetLength();

if(i==0)

{

if(dwFileLength512)

{

sOut.Format(_T("文件%S不是一个有效的引导区文件,请使用[功能3]裁减该文件!"),sInFileName);

return -1;

}

}

if(i==0)//对0扇区文件进行特殊处理

{

pBuf = new byte[BlOCKSIZE];

::memset(pBuf,0,BlOCKSIZE);

infile.Read(pBuf,dwFileLength);

if(pBuf[510]!=0x55) pBuf[510]=0x55;

if(pBuf[511]!=0xAA) pBuf[510]=0xAA;

outfile.Write(pBuf,BlOCKSIZE);

dwFileLength = BlOCKSIZE;

}

else

{

pBuf = new byte[dwFileLength];

infile.Read(pBuf,dwFileLength);

outfile.Write(pBuf,dwFileLength);

}

infile.Close() ;

delete[] pBuf;

count += dwFileLength;

pProgCtrl-SetPos((int)(count*100/FLOPYBYTESIZE));

}

#ifdef ADISKMODE

//3.补充剩余的软盘字节为0

DWORD dwRet = FLOPYBYTESIZE-count;

pBuf = new byte[dwRet];

memset(pBuf,0,dwRet);

outfile.Write(pBuf,dwRet);

delete[] pBuf;

#endif

outfile.Close() ;

//end 显示设置

省略…

return 0;

}

3.2 写镜像文件到软盘代码

基本原理是读取生成的镜像文件,然后把其写入软盘启动器A中, 具体的代码请参考(省略了部分不关键代码):

//写镜像文件到软驱

UINT FuncWriteFlopy(LPVOID pDialog)

{

//begin显示设置

省略…

int nTotalBlocks = 80*18*2;

//1.打开A驱动器

HANDLE hFile = CreateFile(_T("\\\\.\\A:"),

GENERIC_WRITE,

FILE_SHARE_WRITE,

NULL,

OPEN_EXISTING,

0,

NULL);

if(hFile==NULL)

{

sOut = _T("不能打开驱动器A");//…

return -1;

}

PBYTE pBuffer = (PBYTE)malloc(BlOCKSIZE);

if(pBuffer==NULL)

{

sOut = _T("开辟内存空间失败!");//…

return -1;

}

memset(pBuffer,0,BlOCKSIZE);

//2.打开镜像文件

CFile fInFile;

BOOL b = fInFile.Open(pCurDlg-m_ImgFileName, CFile::modeRead);

if(!b)

{

sOut.Format(_T("不能打开镜像文件%s!"),pCurDlg-m_ImgFileName);

return -1;

}

//3.分块写入镜像文件

DWORD dwImgLen = fInFile.GetLength();

for(int i=0;i<nTotalBlocks;i++)

{

DWORD dwLen=0;

fInFile.Read(pBuffer, BlOCKSIZE);

WriteFile(hFile, pBuffer, BlOCKSIZE, &dwLen, NULL);

#ifndef ADISKMODE

if((DWORD)((i+1)*BlOCKSIZE)=dwImgLen) break;//镜像文件写入完毕

#endif

if(dwLen!=BlOCKSIZE)

{

sOut.Format(_T("写入镜像文件%s失败,请检查软驱!"),pCurDlg-m_ImgFileName);

//…

return -1;

}

pProgCtrl-SetPos((int)(i*100/nTotalBlocks));

}

//4.关闭文件

fInFile.Close();

CloseHandle(hFile);

free(pBuffer);

//end 显示设置

pProgCtrl-SetPos(100);

sOut.Format(_T("镜像文件%s写入软驱成功!"),pCurDlg-m_ImgFileName);

//…

return 0;

}

4、操作系统编写

4.1 PC机启动基本原理

(1) 开启电源后, 机器就会开始执行ROM BIOS的一系列系统测试动作,包括检查RAM,keyboard,显示器,软硬磁盘等等。

(2)执行完BIOS的系统测试之后,紧接着控制权会转移给ROM中的启动程序(ROM bootstrap

routine);这个程序会将磁盘上的第0轨第0扇区(叫boot sector或MBR

,系统的引导程序就放在此处)读入内存中,并放到自0x07C0:0x0000开始的512个字节处;然后处理机将跳到此处开始执行这一引导程序;也即装入MBR中的引导程序后,

CS:IP = 0x07C0:0x0000 。

注意: 如果这个扇区的最后两个字节是"55 AA",那么这就是一个引导扇区。如果最后两个字节不是"55 AA",那么BIOS

就检查下一个磁盘驱动器。

4.2 基本编译工具选择

NASM:编写系统级汇编代码的绝好的工具,而且分别支持Windows和Linux系统。本来原来用TASM编译的,可发现在编写的读取硬盘扇区的汇编代码裁剪去512字节的DOS头后居然不能还运行,郁闷了好多天,都没有解决,而用NASM编译出来可以的,所以决定改用NASM。

4.3 引导代码编写

文件boot.asm,具体代码及注释

org 07c00h ; 程序会被加载到7c00处,所以需要这一句

mov ax, cs

mov ds, ax

mov es, ax

Call DispStr ; 调用显示字符串例程

jmp $ ; 无限循环

DispStr:

mov ax, BootMessage

mov bp, ax ; ES:BP = 串地址

mov cx, 16 ; CX = 串长度

mov ax, 01301h ; AH = 13h, AL = 01h

mov bx, 000ch ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)

mov dl, 0

int 10h ; int 10h

ret

BootMessage: db " Hello, OS world!"

times 510-($-$$) db 0 ;填充剩下的空间,使生成的二进制代码恰好为512字节

dw 0aa55h ; 引导扇区需要以55AA结束

4.4 用NASM编译nasm boot.asm -o boot.bin

4.5 写入镜像文件及运行

按照2.1节所示的步骤把boot.Bin生成镜像文件,然后再写入软盘。下图是我再VMWare下的运行结果:

图4 系统运行显示

4.6 系统的其它功能实现

读取硬盘扇区,BIOS中断向量替换,实现文件系统,实虚模式转换及磁盘文件加载由于自己水平有限,不能详细介绍,网上有许多高手已经实现得很好了。如果感兴趣,可以参考相应的网址。详细请见:http://www.oldlinux.org

结语

本文中的部分代码来自网上及林永君老师的课件,在此表示感谢。当然,单纯做一个操作系统来说,其现实的意义已不是太大。但对于更好的了解PC机的运行机制及操作系统的中断向量,系统调动及实模式及虚模式还是有很大的意义的。另外,也可以为Linux或者Windows下的驱动及系统开发打下一个良好的基础。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有