/* file: load.c */
/*这个程序如此简单,功能只有两个,接受字符和显示,又编译连接吧。
现在我们生成了两个文件boot.exe,kernel.exe。其中boot.exe不要执行,你可以在dos
下运行的是kernel.exe,可以看看写对没有。
现在就差把这两个文件写入软盘的1,2扇区了。可是你会发现很怪的问题,boot有603字
节,kernel有522字节,但是一个扇区只有512字节,怎么写得下?这个问题我最先也迷
惑,后来把两个exe文件反汇编才知道真正我们写的代码出现在exe文件的513字节处,
exe文件的前512字节是mircosoft定义的exe文件的前缀,其中有exe文件标识,大小,
段定位指针等东西,这512字节我们不需要我们就只要后面的,那么我们就来写个程序
把boot.exe 和kernel.exe 写入软盘吧,(注意写入引导扇区的时候最后两个字节必须
是55aa这是规定的引导扇区的标识。)我这里选的是用tc2.0了,当然也可以用汇编写,
下面是writebt.c
*/
#include
#include
union REGS inreg,outreg;
struct SREGS segreg;
main()
{
int i;
char boot_buf[512]; /*暂存放boot.exe的内容*/
char kernel_buf[512]; /*暂存放kernel.exe的内容*/
FILE *fp;
for(i=0;i<512;i++)
{ /*先把这两个缓冲区清0*/
boot_buf[i]=0;
kernel_buf[i]=0;
}
if((fp=fopen("boot.exe","rb"))==NULL)
{
printf("cannot find boot.exe");exit(0);
} /*打开boot.exe*/
fseek(fp,512L,0); /*直接定位到文件第513个字节处,即512L*/
i=0;
while(1)
{
fread(&boot_buf[i],1,1,fp); /*读入后面的所有内容直到结束*/
i++;
if(feof(fp))
{
fclose(fp);
break;
}
}
boot_buf[510] = 0x55; /*最后两个字节必须为55aa*/
boot_buf[511] = 0xaa;
/* 设置:将boot中的引导程序写入A盘的第0磁道1扇区*/
inreg.h.ah=0x03; /*调用bios13h的3号写盘功能*/
inreg.h.al=0x1; /*要读的扇区数为1*/
inreg.h.ch=0; /*磁道号为0*/
inreg.h.cl=1; /*扇区号为1*/
inreg.h.dh=0; /*磁头号为0*/
inreg.h.dl=0; /*驱动器号为0,即a盘*/
inreg.x.bx=FP_OFF(boot_buf); /*bx中写boot_buf的内存偏移地址*/
segreg.es=FP_SEG(boot_buf); /*es中写它的内存段地址*/
int86x(0x13,&inreg,&outreg,&segreg); /*调中断写盘*/
if (_AH!=0) /*ah为0刚写盘成功,否则退出*/
{
printf("error writing");exit(0);
}
else
{
printf("ok");
}
if((fp=fopen("kernel.exe","rb"))==NULL) /*打开kernel.exe*/
{
printf("cannot find kernel.exe");exit(0);
}
fseek(fp,512L,0); /*直接定位到文件第513个字节处,即512L*/
i=0;
while(1)
{
fread(&kernel_buf[i],1,1,fp); /*读入后面的所有内容直到结束*/
i++;
if(feof(fp))
{
fclose(fp);
break;
}
}
/* 设置:将kernel中的程序写入A盘的第0磁道2扇区*/
inreg.h.ah=0x03;
inreg.h.al=0x1;
inreg.h.ch=0;
inreg.h.cl=2; /*扇区号为2*/
inreg.h.dh=0;
inreg.h.dl=0;
inreg.x.bx=FP_OFF(kernel_buf);
segreg.es=FP_SEG(kernel_buf);
int86x(0x13,&inreg,&outreg,&segreg);
if (_AH!=0)
{
printf("error writing");exit(0);
}
else
{
printf("ok");
}
}
本文转自
http://blog.csdn.net/lvjinhua/archive/2005/04/16/350429.aspx