`
cloudtech
  • 浏览: 4612419 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

grub-0.97源码分析(1)

 
阅读更多
#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. */
#defineMOV_MEM_TO_AL(x).byte 0xa0; .word x //这个不用管它,只是为了实现兼容性用了机器码

.file"stage1.S"
.text
.code16
.globl _start; _start:
jmpafter_BPB
nop/* do I care about this ??? */
. = _start + 4 //跳过上面两条指令
/* scratch space BIOS参数的定义*/
mode:
.byte0
disk_address_packet:
sectors:
.long0
heads:
.long0
cylinders:
.word0
sector_start:
.byte0
head_start:
.byte0
cylinder_start:
.word0
/* more space... */
. = _start + STAGE1_BPBEND
/*
* End of BIOS parameter block.
*/
/*与启动有关的参数的定义*/
stage1_version:
.byteCOMPAT_VERSION_MAJOR, COMPAT_VERSION_MINOR
boot_drive:
.byteGRUB_INVALID_DRIVE/* the disk to load stage2 from */
force_lba:
.byte0
stage2_address:
.word0x8000
stage2_sector:
.long1
stage2_segment:
.word0x800
after_BPB:
/* general setup */
cli/* we're not safe here! */
boot_drive_check: /*这段代码有什么用? jmp 1f 后面的代码能执行吗?我没看明白*/
jmp1f
testb$0x80, %dl
jnz1f
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中
*/
je1f
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模式*/
jzchs_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 */
jcchs_mode
cmpw$0xaa55, %bx /*测试后,正常情况下bx=0xaa55*/
jnechs_mode
/* check if AH=0x42 is supported if FORCE_LBA is zero */
MOV_MEM_TO_AL(ABS(force_lba))/* movbABS(force_lba), %al */
testb%al, %al
jnzlba_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)
*/
jzchs_mode

lba_mode:
/* save the total number of sectors */
movl0x10(%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)

movlABS(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. */
jcchs_mode
movw$STAGE1_BUFFERSEG, %bx
jmpcopy_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)
*/
jncfinal_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
jzfloppy_probe
/* Nope, we definitely have a hard disk, and we're screwed. */
jmphd_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) */
movlABS(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 */
divl4(%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? */
cmpw8(%si), %ax
jgegeometry_error
/*
* This is the loop for taking care of BIOS geometry translation (ugh!)
*/
/* get high bits of cylinder */
movb13(%si), %dl
shlb$6, %dl/* shift left by 6 bits */
movb10(%si), %cl/* get sector */
incb%cl/* normalize sector (sectors go
from 1-N, not 0-(N-1) ) */
orb%dl, %cl/* composite together */
movb12(%si), %ch/* sector+hcyl in cl, cylinder in ch */
/* restore %dx */
popw%dx

/* head number */
movb11(%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
jcread_error
movw%es, %bx

copy_buffer:
movwABS(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)
jmpgeneral_error
/*
* Disk probe failure.
*/
hd_probe_error:
MSG(hd_probe_error_string)
jmpgeneral_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:jmpstop
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
jne1b/* 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:
.byte36, 18, 15, 9, 0%3
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics