作者:孙靖(Jig)
若要转贴或使用本文章介绍的技术,请在你发布的文章或作品中注明出处。
前面我认识了引导程序的编写,可发现软盘中的有关信息被破坏,那我们现在就要来研究 FAT12 磁盘格式吗?呵呵,那还太早了。
记得吗?我们把引导程序写入磁盘后是重启机器并改了BIOS设置才看到的效果,难道你想每次调试程序都关机重启?呵呵,那样太费事了。其实大家也都知道我要说的点子,装个虚拟机,在虚拟机上跑,要是真的程序崩溃了也是虚拟机。(还记得我前面说过我们TC编译的核,也可以在WIN平台下跑,可那很危险就是这个意思)那么我重点推荐的就是 Virtual PC,哈哈用过的人都知道,他是虚拟机中最快的。(在于渊的书中是那么介绍的,而且我用过书中介绍的3中虚拟机,的确是 Virtual PC 最快)
好的,我们要在虚拟机上装个DOS系统,好对我们编译的内核进行调试。(当然也可以创建一台裸机,好让我们来查看真实的效果。我的裸机名就是 Jig)
那接下来,我们当然也是要使用虚拟软盘来进行实验。我想大家也不想总是使用真的软区用我们的写软盘工具一遍遍的去写那软盘吧,那太慢,而且不一定大家都有软区啦。那我们就来写个制作虚拟软盘的软件。而且我们为了后面学习磁盘格式,我们还得在这个软件中添加一个16进制查看的功能,好查看软盘里的16进制信息。
好的,我们先用虚拟机去创建一张软盘,(我取名为 Jig.vfd)然后查看属性,我们可以看到他的大小为 1.44M,1,474,560 字节。恰好是我们真实软盘的大小。然后,我们先抛开磁盘的具体格式,来计算总共有 1,474,560 / 512 = 2880 个扇区。
那我的第一想法就是先将我们上文中的 shiyan.bin 复制到 Jig.vfd 的最开头,而剩下的2879 个扇区用空格填充。而我们查看16进制的功能,正好和前面的相反,依次读取 Jig.vfd 中的各个扇区,然后将其用16进制和字符打印在一个文本文件中,以便我们查看软盘的内容,好在后面学习磁盘格式,进而搞定文件系统。
好的有了以上想法,让我们来实施,编写以下程序:
/* writefolly.c */
#include <stdio.h>
#include <io.h>
void write_flloy(void);
void look_binary(void);
int main(void)
{
int key;
printf("写软盘 1 查看器 2n"); /* 功能选择 */
scanf("%d", &key); /* 选择 */
printf("nnn");
(key == 1) write_flloy():look_binary();
}
void write_flloy(void) /* 写软盘 */
{
FILE *name;
FILE *file_key;
int key = 0;
long i;
long file_long;
char file_name[2][40];
unsigned char buffer[512];
printf("请输入源文件:");
scanf("%s", file_name[0]);
printf("n");
file_key = fopen(file_name[0], "rb");
file_long = 512; /*得到源文件长度 */
fread(buffer, file_long, 1, file_key);
fclose(file_key);
printf("请输入输出文件:");
scanf("%s", file_name[1]);
printf("nn");
name = fopen(file_name[1], "wb+");
fwrite(buffer, file_long, 1, name);
buffer[0] = 0;
printf("拷贝进度:n"); /* 写软盘 */
for (i = 0; i < 1474560-file_long; i++)
{
if (key != (i+512)*100/1474560)
{
key = (i+512)*100/1474560;
printf("%c%dn", '%', key);
}
fwrite(buffer, 1, 1, name);
}
fclose(name);
printf("拷贝完成!");
}
void look_binary(void) /* 查看软盘 */
{
FILE *name, *fp;
int i, j, k, m[2];
char file_name[40];
unsigned char buffer[512];
printf("请输查看文件:");
scanf("%s", file_name);
printf("n");
printf("请输入启始扇区:");
scanf("%d", &m[0]);
printf("n");
printf("请输入结束扇区:");
scanf("%d", &m[1]);
printf("n");
name = fopen(file_name, "rb");
fp = fopen("查看.txt", "w");
for (i = 0; i < m[0]; i++)
{
fread(buffer, 512, 1, name);
}
for (i = m[0]; i < m[1]; i++)
{
fread(buffer, 512, 1, name);
printf("%d 扇区nn", i);
fprintf(fp, "%d 扇区nn", i);
for (j = 0; j < 32; j++)
{
printf("%x ", i*512+j*16);
fprintf(fp, "%x ", i*512+j*16);
for (k = 0; k < 8; k++)
{
if (buffer[j*16+k] > 15)
{
printf("%x ", buffer[j*16+k]);
fprintf(fp, "%x ", buffer[j*16+k]);
}
else
{
printf("0%x ", buffer[j*16+k]);
fprintf(fp, "0%x ", buffer[j*16+k]);
}
}
printf(" ");
fprintf(fp, " ");
for (k = 8; k < 16; k++)
{
if (buffer[j*16+k] > 15)
{
printf("%x ", buffer[j*16+k]);
fprintf(fp, "%x ", buffer[j*16+k]);
}
else
{
printf("0%x ", buffer[j*16+k]);
fprintf(fp, "0%x ", buffer[j*16+k]);
}
}
printf(" ");
fprintf(fp, " ");
for (k = 0; k < 16; k++)
{
printf("%c", buffer[j*16+k]);
fprintf(fp, "%c", buffer[j*16+k]);
}
printf(" n");
fprintf(fp, " n");
}
}
fclose(name);
fclose(fp);
while(1);
}
OK,编译连接。(为了可以显示汉字,我们可以用VC或DEV来编译,这样方便)我们便有了 writefolly.exe 的软盘读写工具。让我们来做个实验。
运行 writefolly.exe,选择1。按提示输入源文件名 shiyan.bin,和输出文件 Jig.vfd。等程序运行完毕,好的,我们的 Jig.vfd 虚拟软盘内容已经改变。让我们来证实一下。启动虚拟机,将 Jig.vfd 当作映像文件加载到裸机上(当然也可以是装有DOS系统的虚拟机),等一会。看到了没有~~!?虚拟机屏幕上显示出一个字母 't',哈哈,我们实验成功,初步看来软盘信息就是我们想的那样。好的,再让我们运行 writefolly.exe,选择2,按提示输入查看文件 Jig.vfd,启始扇区 0,和结束扇区 2879(软盘共有2880个扇区)。这样得到一个 查看.txt 的文本文件,让我们来看看他的内容:
查看.txt:
0 扇区
0 b4 0e b0 74 b3 07 cd 10 00 00 00 00 00 00 00 00 皌
10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa U
1 扇区
200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
......
好的让我们仔细查看第0扇区的内容,然后我们把 shiyan.bin 用记事本打开。查看他的内容:
皌 U
看!是不是和查看中的一致(废话当然一致,我们是用自己写的工具写出的Jig.vfd)呵呵,其实你写个实际的软盘的读写工具,在真实的软盘上做也是同样的效果(因为我就是先在实际的软盘上操作,知道其中的具体格式才写出writefolly)。
好的,现在我们有个这么好的虚拟软盘工具啦,那我们后面就可以方便的来具体研究磁盘格式。
发表于 @ 2006年05月23日 11:54:00|评论(loading...)|编辑