Chinaunix首页 | 论坛 | 博客
  • 博客访问: 267169
  • 博文数量: 107
  • 博客积分: 305
  • 博客等级: 二等列兵
  • 技术积分: 417
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-22 09:42
文章分类

全部博文(107)

文章存档

2014年(3)

2013年(41)

2012年(34)

2011年(28)

2008年(1)

分类:

2011-06-13 00:31:45

原文地址:我的OS(5)---- boot加载 作者:fireaxe

本文乃fireaxe原创,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,并注明原作者及原链接,严禁用于任何商业用途。
作者:fireaxe_hq@hotmail.com
博客:fireaxe.blog.chinaunix.net 
  Boot加载 1.1      为何要有boot

电脑启动后,cpu会把软盘的第一个扇区(512字节),也就是所说的引导扇区,读入内存的0x7c00处执行。512实在是太小了,一个最简单的实模式转入保护模式的代码就会耗尽这512字节。如果在实模式中加载内核,则会把内核限制在1M以内(实际还要小些)。

由于这些缺点,需要首先用引导扇区加载一个boot程序,这个boot程序最大可以有几百K大小,虽然也不是很大,但对于之前的512字节来说,则已经是大的让人惊喜了。

boot中,我们可以完成加载kernel的所有准备工作了。

1.2      加载boot到内存

此处是引导程序。该程序会读入一个扇区到0x8000h开始的内存处,并移动bx到下一个扇区的开始处。

; ch 磁道

; cl 扇区

; dh 磁头

; bx会被加512

ReadFloopy:

       push ax

       push cx

       push dx

       push es

      

       mov ax, 0800h ; 加载到08000h,所以要把0800h移入段寄存器es

       mov es, ax

    mov ah, 02h  ; 读操作

    mov al, 01h   ; read sector no.

    mov dl, 00h   ; 0号软驱

       int 13h

       add bx, 512   ; 每次把bx向后移一个扇区

 

       pop es

       pop dx

       pop cx

       pop ax

       ret

下面的程序会读入60个扇区的内容到0x8100处。注意最后的跳转指令,该指令会设置cs寄存器为0x800,设置ip寄存器为0x100,也就是boot程序的入口。

LABEL_BEGIN:

    mov ax, cs

    mov ds, ax

    mov ss, ax

    mov es, ax

       mov sp, BaseOfStack

       

       call ResetFloopy            ; reset floopy

      

    ; read sectors to memory

       mov ax, 1

       mov bx, 0100h         ; 程序开始的偏移量

.loop:

       push ax

       mov cl, 18

       div cl

       mov cl, ah

       add cl, 1

       mov ch, al

       shr ch, 1

       mov dh, al

       and dh, 1

       call ReadFloopy    ; 读扇区

       pop ax

       add ax, 1

       cmp ax, 60        ; 60个扇区

       jnz .loop

 

       jmp 0800h:0100h    ; 跳入boot的开始处

 

1.3      Boot编译

由于boot中要做的事情比较多,所以现在的编译模式改为汇编与c程序的汇编,其makefile写法如下:

default:rt/hboot.bin

       objdump -d rt/hboot.elf > rt/dump.txt

 

rt/hboot.bin:rt/hboot.elf

       objcopy --gap-fill=0xff -O binary $< $@

 

rt/hboot.elf:rt/bootInit.o main.o

       ld -s -Ttext 0100 $^ -o $@

 

rt/%.o:%.c

       mkdir -p rt

       gcc -c -fno-builtin $< -o rt/$*.o

 

rt/%.o:%.s

       mkdir -p rt

       nasm -f elf $< -o rt/$*.o

由于boot开始时还是在实模式下,所以要在汇编中标注[BITS 16]global _Start_Boot用于说明这个是一个全局符号,这是为了让编译器能够找到。此处只是一个打印字符串的延时程序。

[BITS 16]

global _Start_Boot

_Start_Boot:

       mov ax, cs

       mov ds, ax

       mov es, ax

       mov ss, ax

       mov sp, 08100h

 

       mov ax, BootMessage

       mov bp, ax

       mov cx, 15

       mov ax, 01301h

       mov bx, 000ch

       mov dl, 0

       int 10h

 

       jmp $

 

本文乃fireaxe原创,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,并注明原作者及原链接,严禁用于任何商业用途。
作者:fireaxe_hq@hotmail.com
博客:fireaxe.blog.chinaunix.net 
阅读(773) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~