REACTOS分析(1)Dosmbr.asm源码分析
ReactOs引导代码dosmbr.asm ; normal DOS boot sector ; Ported to nasm from FreeDOS fdisk 1.2.0 by: ; Casper Hornstrup (chorns@users.sourceforge.net) ; align 2,db 0 global _bootnormal_code _bootnormal_code: ;----------------------------------------------------------------------- ; ENTRY (copied from freedos bootsector) ; IN: DL = boot drive ;OUT: DL = boot drive ;----------------------------------------------------------------------- real_start: cli cld xor ax,ax mov ss,ax ; initialize stack mov ds,ax mov bp,0x7c00 lea sp,[bp-0x20] sti mov ax,0x1FE0 mov es,ax mov si,bp mov di,bp mov cx,0x0100 rep movsw jmp word 0x1FE0:0x7c00+ cont-real_start //BIOS会将磁盘MBR读到内存中 0x0000:0x7c00 //首先将MBR代码移动到 0x1FE0:0x7c00 //注意下面两条规则: //1)在改变SS:SP之前,必须用cli指令屏蔽中断,然后等操作执行完立即用sti指令恢复 //2)SS:SP需要设置在空闲的内存地址,不要建立在其他的程序(尤其是系统的)代码区 cont:mov ds,ax xor ax,ax mov es,ax //重新设置数据、堆栈段寄存器->0x1FE0 //搜索MBR的4个分区表,找到引导分区 ; search for active partition lea di,[bp+0x1be] ; start of partition table test_next_for_active: test byte [di],0x80 jne active_partition_found add di,0x10 ; next table cmp di,07c00h+0x1fe; scanned beyond end of table ?? jb test_next_for_active ;***************************************************************** call print db 'no active partition found',0 WAIT_FOR_REBOOT: jmp $ ;***************************************************************** trouble_reading_drive: call print db 'read error while reading drive',0 jmp WAIT_FOR_REBOOT ;***************************************************************** invalid_partition_code: call print db 'partition signature != 55AA',0 jmp WAIT_FOR_REBOOT ;***************************************************************** active_partition_found: ; call print ; db 'loading active partition',0 //准备载入引导分区 call read_boot_sector jc trouble_reading_drive cmp word [es:0x7c00+0x1fe],0xaa55 jne invalid_partition_code //执行引导代码 jmp word 0x0:0x7c00 ; and jump to boot sector code ;***************************** ; read_boot_sector ; IN: DI--> partition info ;OUT:CARRY ;***************************** read_boot_sector: ; /* check for LBA support */ mov bx,0x55aa mov ah,0x41 int 0x13 //使用 BIOS int 13测试LBA支持 jc StandardBios ; if (regs.b.x != 0xaa55 || (regs.flags & 0x01)) cmp bx,0xaa55 ; goto StandardBios; jne StandardBios ; /* if DAP cannot be used,don't use LBA */ ; if ((regs.c.x & 1) == 0) ; goto StandardBios; test cl,1 jz StandardBios jmp short LBABios //使用LBA地址以及BIOS int13扩展IO指令读磁盘,参考int 13扩展指令资料 //读取4个扇区->0x0000:0x7c00 _bios_LBA_address_packet: db 0x10 db 0 db 4 ; read four sectors - why not db 0 dw 0x7c00 ; fixed boot address for DOS sector dw 0x0000 _bios_LBA_low dw 0 _bios_LBA_high dw 0 dw 0,0 LBABios: ; copy start address of partition to DAP mov ax,[di+8] mov [0x7c00+ (_bios_LBA_low-real_start)],ax mov ax,[di+8+2] mov [0x7c00+ (_bios_LBA_high-real_start)],ax mov ax,0x4200 ; regs.a.x = LBA_READ; mov si,0x7c00+ (_bios_LBA_address_packet-real_start); regs.si = FP_OFF(&dap); int 0x13 ret ;***************************************************************** ; read disk,using standard BIOS ; StandardBios: mov ax,0x0204 ; regs.a.x = 0x0201; mov bx,0x7c00 ; regs.b.x = FP_OFF(buffer); mov cx,[di+2] ; regs.c.x = ; ((chs.Cylinder & 0xff) << 8) + ((chs.Cylinder & 0x300) >> 2) + ; chs.Sector; ; that was easy ;-) mov dh,[di+1] ; regs.d.b.h = chs.Head; ; regs.es = FP_SEG(buffer); int 0x13 ret ; prints text after call to this function. print_1char: xor bx,bx ; video page 0 mov ah,0x0E ; else print it int 0x10 ; via TTY mode print: pop si ; this is the first character print1: lodsb ; get token push si ; stack up potential return address cmp al,0 ; end of string? jne print_1char ; until done ret ; and jump to it
times 0x1fe-$+$$ db 0 db 0x55,0xaa
; http://en.wikipedia.org/wiki/INT_13 ; http://en.wikipedia.org/wiki/INT_10 硬盘主引导扇区 = 硬盘主引导记录(MBR)+ 硬盘分区表(DPT) 详解:
000H--002H 3 BYTE的跳转指令(去启动程序,跳到03EH)
01BE 1 分区类型:00表示非活动分区:80表示活动分区;其他为无效分区。 01BF~01C1 3 *分区的起始地址(面/扇区/磁道),通常第一分区的起始地址开始 01C2 1 #分区的操作系统的类型。 01C3~01C5 3 *该分区的结束地址(面/扇/道) 01C6~01C9 4 该分区起始逻辑扇区 01CA~01CD 4 该分区占用的总扇区数 注释: * 注意分区的起始地址(面/扇区/磁道)和结束地址(面/扇/道)中字节分配: 00000000 01000001 00010101 ~ 面(磁头) 8 位 # 分区的操作系统类型(文件格式标志码) 4---DOS FAT16<32M
例如: 以下是一个硬盘的分区情况. 道 面 扇 道 面 扇 起始扇(逻辑) 结束扇 总共扇区
实际使用这种方法比较麻烦,如果知道每个分区的大小,则可以通过使用PQ MAGIC 5 将磁盘重新分区为原来大小(注意: 千万不能应用,我们只是通过它来获得数据),并查看INFO来获得以上 该例所对应的分区表数据: 80 01 扩展分区表数据:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |