您的位置:首页 > 其它

grub-0.97源码分析(1)

2009-11-29 22:09 302 查看


#include <stage1.h>

#define ABS(x) (x-_start+0x7c00) //计算物理地址,不依赖编译器
/* Print message string */

#define MSG(x) movw $ABS(x), %si; call message
/* XXX: binutils-2.9.1.0.x doesn't produce a short opcode for this. */

#define MOV_MEM_TO_AL(x) .byte 0xa0; .word x //这个不用管它,只是为了实现兼容性用了机器码

.file "stage1.S"
.text
.code16
.globl _start; _start:

jmp after_BPB

nop /* do I care about this ??? */
. = _start + 4 //跳过上面两条指令
/* scratch space BIOS参数的定义*/

mode:

.byte 0

disk_address_packet:

sectors:

.long 0

heads:

.long 0

cylinders:

.word 0

sector_start:

.byte 0

head_start:

.byte 0

cylinder_start:

.word 0

/* more space... */
. = _start + STAGE1_BPBEND
/*

* End of BIOS parameter block.

*/
/*与启动有关的参数的定义*/
stage1_version:

.byte COMPAT_VERSION_MAJOR, COMPAT_VERSION_MINOR

boot_drive:

.byte GRUB_INVALID_DRIVE /* the disk to load stage2 from */

force_lba:

.byte 0

stage2_address:

.word 0x8000

stage2_sector:

.long 1

stage2_segment:

.word 0x800
after_BPB:
/* general setup */

cli /* we're not safe here! */

boot_drive_check: /*这段代码有什么用? jmp 1f 后面的代码能执行吗?我没看明白*/

jmp 1f

testb $0x80, %dl

jnz 1f

movb $0x80, %dl

1:
/*

* ljmp to the next instruction because some bogus BIOSes

* jump to 07C0:0000 instead of 0000:7C00.

*/

ljmp $0, $ABS(real_start) /*cs = 0*/
real_start:
/* set up %ds and %ss as offset from 0 */

xorw %ax, %ax

movw %ax, %ds

movw %ax, %ss
/* set up the REAL stack */

movw $STAGE1_STACKSEG, %sp /*STAGE1_STACKSEG = 0x2000*/
sti /* we're safe again */
/*

* Check if we have a forced disk reference here

*/

MOV_MEM_TO_AL(ABS(boot_drive)) /* movb ABS(boot_drive), %al */

cmpb $GRUB_INVALID_DRIVE, %al /* 如果boot_drive=0xff,则表示从默认的位置加载stage2

* 如果不是默认,把驱动器号保存在dl中

*/

je 1f

movb %al, %dl

1:

/* save drive reference first thing! */

pushw %dx /*不是默认的话,保存才是有用的,否则没用*/
/* print a notification message on the screen */

MSG(notification_string)
/* do not probe LBA if the drive is a floppy */

testb $STAGE1_BIOS_HD_FLAG, %dl /*如果是软盘,即STAGE1_STACKSEG=0,直接跳入chs模式*/

jz chs_mode

/* check if LBA is supported */

movb $0x41, %ah /*此时dl=80,ah=41h,bx=0x55aa,int 13h 检测第一块硬盘的CF位*/

movw $0x55aa, %bx /*即检查是否支持LBA寻址,不支持则CF=1*/

int $0x13
/**

*AH 41h = function number for extensions check

   *DL drive index (e.g. 1st HDD = 80h)

   *BX 55AAh

*CF Set On Not Present, Clear If Present
***/
/*

* %dl may have been clobbered by INT 13, AH=41H.

* This happens, for example, with AST BIOS 1.04.

*/

popw %dx

pushw %dx
/* use CHS if fails */

jc chs_mode

cmpw $0xaa55, %bx /*测试后,正常情况下bx=0xaa55*/

jne chs_mode
/* check if AH=0x42 is supported if FORCE_LBA is zero */

MOV_MEM_TO_AL(ABS(force_lba)) /* movb ABS(force_lba), %al */

testb %al, %al

jnz lba_mode

andw $1, %cx /*CX Interface support bitmask:
   * 1 - Device Access using the packet structure
   * 2 - Drive Locking and Ejecting
   * 4 - Enhanced Disk Drive Support (EDD)
*/

jz chs_mode

lba_mode:

/* save the total number of sectors */

movl 0x10(%si), %ecx /*这是在干什么*/

/* set %si to the disk address packet */

movw $ABS(disk_address_packet), %si /* si指向BIOS的参数*/
/* set the mode to non-zero mode =1*/

movb $1, -1(%si)

movl ABS(stage2_sector), %ebx
/* the size and the reserved byte */

movw $0x0010, (%si) /**/
/* the blocks */

movw $1, 2(%si)

/* the absolute address (low 32 bits) */

movl %ebx, 8(%si)
/* the segment of buffer address */

movw $STAGE1_BUFFERSEG, 6(%si)
xorl %eax, %eax

movw %ax, 4(%si)

movl %eax, 12(%si)

/*

* BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory

* Call with %ah = 0x42

* %dl = drive number

* %ds:%si = segment:offset of disk address packet

* Return:

* %al = 0x0 on success; err code on failure

*/
movb $0x42, %ah

int $0x13
/* LBA read is not supported, so fallback to CHS. */

jc chs_mode
movw $STAGE1_BUFFERSEG, %bx

jmp copy_buffer

chs_mode:

/*

* Determine the hard disk geometry from the BIOS!

* We do this first, so that LS-120 IDE floppies work correctly.

*/

movb $8, %ah

int $0x13 /*INT 13h AH=08h: Read Drive Parameters AH Return Code

   *DL number of hard disk drives

   *DH logical last index of heads = number_of - 1 (because index starts with 0)

   *CX logical last index of cylinders = number_of - 1 (because index starts with 0)

*/

jnc final_init /* CF Set On Error, Clear If No Error */

/*

* The call failed, so maybe use the floppy probe instead.

*/

testb $STAGE1_BIOS_HD_FLAG, %dl

jz floppy_probe
/* Nope, we definitely have a hard disk, and we're screwed. */

jmp hd_probe_error
final_init:

movw $ABS(sectors), %si
/* set the mode to zero */

movb $0, -1(%si)

/* save number of heads */

xorl %eax, %eax

movb %dh, %al

incw %ax

movl %eax, 4(%si)
xorw %dx, %dx

movb %cl, %dl

shlw $2, %dx

movb %ch, %al

movb %dh, %ah
/* save number of cylinders */

incw %ax

movw %ax, 8(%si)
xorw %ax, %ax

movb %dl, %al

shrb $2, %al
/* save number of sectors */

movl %eax, (%si)
setup_sectors:

/* load logical sector start (bottom half) */

movl ABS(stage2_sector), %eax
/* zero %edx */

xorl %edx, %edx
/* divide by number of sectors */

divl (%si)
/* save sector start */

movb %dl, 10(%si)
xorl %edx, %edx /* zero %edx */

divl 4(%si) /* divide by number of heads */

/* save head start */

movb %dl, 11(%si)
/* save cylinder start */

movw %ax, 12(%si)
/* do we need too many cylinders? */

cmpw 8(%si), %ax

jge geometry_error
/*

* This is the loop for taking care of BIOS geometry translation (ugh!)

*/
/* get high bits of cylinder */

movb 13(%si), %dl
shlb $6, %dl /* shift left by 6 bits */

movb 10(%si), %cl /* get sector */
incb %cl /* normalize sector (sectors go

from 1-N, not 0-(N-1) ) */

orb %dl, %cl /* composite together */

movb 12(%si), %ch /* sector+hcyl in cl, cylinder in ch */
/* restore %dx */

popw %dx

/* head number */

movb 11(%si), %dh
/*

* BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory

* Call with %ah = 0x2

* %al = number of sectors

* %ch = cylinder

* %cl = sector (bits 6-7 are high bits of "cylinder")

* %dh = head

* %dl = drive (0x80 for hard disk, 0x0 for floppy disk)

* %es:%bx = segment:offset of buffer

* Return:

* %al = 0x0 on success; err code on failure

*/
movw $STAGE1_BUFFERSEG, %bx

movw %bx, %es /* load %es segment with disk buffer */
xorw %bx, %bx /* %bx = 0, put it at 0 in the segment */

movw $0x0201, %ax /* function 2 */

int $0x13
jc read_error
movw %es, %bx

copy_buffer:

movw ABS(stage2_segment), %es
/*

* We need to save %cx and %si because the startup code in

* stage2 uses them without initializing them.

*/

pusha

pushw %ds

movw $0x100, %cx

movw %bx, %ds

xorw %si, %si

xorw %di, %di

cld

rep

movsw
popw %ds

popa
/* boot stage2 */

jmp *(stage2_address)
/* END OF MAIN LOOP */
/*

* BIOS Geometry translation error (past the end of the disk geometry!).

*/

geometry_error:

MSG(geometry_error_string)

jmp general_error
/*

* Disk probe failure.

*/

hd_probe_error:

MSG(hd_probe_error_string)

jmp general_error
/*

* Read error on the disk.

*/

read_error:

MSG(read_error_string)
general_error:

MSG(general_error_string)
/* go here when you need to stop the machine hard after an error condition */

stop: jmp stop
notification_string: .string "GRUB "

geometry_error_string: .string "Geom"

hd_probe_error_string: .string "Hard Disk"

read_error_string: .string "Read"

general_error_string: .string " Error"
/*

* message: write the string pointed to by %si

*

* WARNING: trashes %si, %ax, and %bx

*/
/*

* Use BIOS "int 10H Function 0Eh" to write character in teletype mode

* %ah = 0xe %al = character

* %bh = page %bl = foreground color (graphics modes)

*/

1:

movw $0x0001, %bx

movb $0xe, %ah

int $0x10 /* display a byte */

message:

lodsb

cmpb $0, %al

jne 1b /* if not end of string, jmp to display */

ret
/*

* Windows NT breaks compatibility by embedding a magic

* number here.

*/
. = _start + STAGE1_WINDOWS_NT_MAGIC

nt_magic:

.long 0

.word 0
/*

* This is where an MBR would go if on a hard disk. The code

* here isn't even referenced unless we're on a floppy. Kinda

* sneaky, huh?

*/
part_start:

. = _start + STAGE1_PARTSTART
probe_values:

.byte 36, 18, 15, 9, 0%3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: