Chinaunix首页 | 论坛 | 博客
  • 博客访问: 657909
  • 博文数量: 151
  • 博客积分: 3498
  • 博客等级: 中校
  • 技术积分: 1570
  • 用 户 组: 普通用户
  • 注册时间: 2005-02-28 18:10
文章分类

全部博文(151)

文章存档

2014年(12)

2013年(17)

2012年(17)

2011年(5)

2010年(12)

2009年(2)

2007年(26)

2006年(22)

2005年(38)

分类: LINUX

2006-06-15 22:33:40

下面是实现一个简单的引导程序的代码,我把它取名为boot.s,它的作用就是把软盘第2个扇区的内容读到内存中地址0x5000,然后跳转到该处执行, 其中es是数据所要放入的段,bx是偏移地址;顾此处我们把第二扇区的内容读入0x5000中;然后指令 jmpi 0,LOC1的
中LOC1表示段,0表示偏移;

;file name:boot.s
;this boot code must be load at 0x07c0 cs ,
;and the absolutely physical address is 0x07c0:0=0x07c00
;so we read the second floppy sector content will not overlapp with the boot code physical address
;then the 2nd addr is 0x500:0=0x5000

LOC1=0x500
entry start
start:
 
   mov ax,#LOC1
   mov es,ax
   mov bx,#0

   mov dl,#0
   mov dh,#0

   mov ch,#0
   mov cl,#2

   mov al,#1
   mov ah,#2
   int 0x13
   jmpi 0,LOC1

;this decide the boot file offset,we can use this ,then we directly read the boot file 512 byte
;if not so!we mus add the boot flag

!.org 508
!.word 0
!bootflag:
!      .word 0xAA55

下面文件为软盘第二个扇区中的内容,名称为:sect.s作用是通过0x10中断在屏幕上显示一行字,但是为什么要多加2个字节才能显示出来呢?调试了好几次才发现这个问题的.

;file name:sect.s
entry start
start:
   mov ah,#0x03
   xor bh,bh
   int 0x10

   mov cx,#28    
   mov bx,#0x0007
   mov bp,#mymsg
   mov ax,#0x1301
   int 0x10

loop1: jmp loop1
mymsg:
    .byte 13,10
    .ascii "Handling BIOS interrupts"
    .byte 13,10      ;this 2 byte must add,  or it don't show the mymsg!
 
 以上两个文件的编译环境为linux下面,通过as86 和ld86实现:
as86 boot.s -o boot.o
ld86 -d boot.o -o boot

下面这个函数为VC中重的一个函数,其中boot,sect为上面编译的汇编文件,fpos.img为bochs中bximage创建的软盘影像文件;内容写入fpos.img后,就可以通过bochs启动了;

void CTestDlg::OnButtonwrite()

     char boot_buf[512];
    FILE * floppy_desc, * file_desc;
    file_desc =  fopen("boot", "r");
    if(!file_desc)AfxMessageBox("error");
     fread(boot_buf, 510,1,file_desc);
    fclose(file_desc);

    boot_buf[510] = 0x55;
    boot_buf[511] = 0xaa;

    floppy_desc = fopen("fpos.img", "w");
    fseek(floppy_desc, 0, SEEK_SET);
    fwrite(boot_buf, 512,1,floppy_desc);
   
     file_desc =  fopen("sect", "r");
    if(!file_desc)AfxMessageBox("error");
    memset(boot_buf,0,512);
     fread(boot_buf, 512,1,file_desc);
    fclose(file_desc);
 
 
    fseek(floppy_desc, 512, SEEK_SET);
    fwrite(boot_buf, 512,1,floppy_desc);
    fclose(floppy_desc);
}

以上还是在LINUX环境中编译的文件,我们也可以在WINDOWS环境中全部完成这个任务,当然我们得把准备工作做好;其中:
1.下载nasm(netwide assemble)(nasm.sourceforge.com)汇编编译器;感觉这个编译器的语法比之INTEL的86汇编编译器要成熟多了;
2.下载WINDOWS平台下的GCC和LD工具,就如osdever网站所说,就用DJGPP套件吧,挺方便的,而且还发现几点:
    RH9下面编译后的gcc -c main.c 后的.o文件中main函数为main;而DJGPP中gcc编译后卫_main;
    命令objcopy -R .note -R .comment -S -O binary kernel.o kernel.bin在RH9上生成的文件有9个扇区,而使用DJGPP的刚好就2个扇区;所以这一点很是不懂.
    还有就是我在RH9上编译了,但是我在把读入的扇区数改为9了,写到软盘映像中,启动还是不能跳转到main函数中,这让我怀疑RH的objcopy 后生成的文件是错误的.
 3.下载bochs吧,很好的工具.

以上所使用的例子都是我的BLOG中关于操作系统文章的例子.

阅读(1764) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~