📄 grub-0.97-patch4-emulation
字号:
+ shrl $1, %eax+ jnz 2f+ clc /* map whole drive, signal no restrictions */+ popw %ax+ pushfw+ pushw %ax+ xorb %ah, %ah /* no restrictions, all sectors transferred */+ ret+2:+ movl 12(%si), %eax+ testl %eax, %eax+ jnz 3f+ movl -14(%bp), %eax /* S_count */+ andb $0xfe, %al+ cmpl %eax, 8(%si)+ jb 2f+3:+ movb $4, %ah /* all sectors exceed the bound, exit immediately */+ xorb %al, %al /* no sectors transferred */+ movb %al, 2(%si)+ stc+ ret+2:+ subl 8(%si), %eax+ pushl %ebx+ xorl %ebx, %ebx+ movw 2(%si), %bx+ cmpl %eax, %ebx+ popl %ebx+ ja 2f+ clc /* signal no restrictions */+ popw %ax+ pushfw+ pushw %ax+ xorb %ah, %ah /* no restrictions, all sectors transferred */+ ret+2:+ movb %al, 2(%si)+ stc+ popw %ax+ pushfw+ pushw %ax+ movb $1, %ah /* not all sectors tranferred */+ ret++real_int13_service:++ cmpb $0xff, %dl /* mem drive */+ jne 2f+ cmpb $0x42, %ah+ je 3f+ cmpb $0x43, %ah+ jne 5f+ /* DS:SI points to disk address packet */+ /* 2(%si), byte, sectors(1-127) */+ /* 4(%si), word, offset */+ /* 6(%si), word, segment */+ /* 8(%si), qword, lba */+3:+ /* AH = 0x42 or 0x43 */+ pushw %es+ pushal+ sahf /* Store AH into flags SF ZF xx AF xx PF xx CF */+ pushf+ movzwl 4(%si), %ebx #; BX=offset, EBX_high_word=0+ movzwl 6(%si), %eax #; AX=segment+ movl 8(%si), %ecx #; ECX=LBA of MEMDRIVE SECTOR+ shll $9, %ecx #; ECX=linear address of SECTOR(above 1M)+ shll $4, %eax #; EAX=linear base address of segment+ addl %ebx, %eax #; EAX=linear address of BUFFER(below 1M)+ popf+ jc 4f /* write */+ xchgl %eax, %ecx+4:+ cmpl $0, %cs:(memdisk_raw - int13_handler)+ je 4f /* do not use raw mode */++ /* raw mode as in memdisk, contributed by Bean */++ /* Data transfer: %eax -> %ecx, number of sector 2(%si) */+ +// pushw %ax+ smsw %bx+ testb $1, %bl+// popw %ax+ jnz 4f /* protected mode */++ /* switch to protected mode myself */+ /* ebx destroy */+ + pushfl+ pushw %ds+ pushw %es++ movl %ecx, %edi+ movzbl 2(%si), %ecx #; ECX=number of sectors to transfer+ movl %eax, %esi #; ESI changed!!++ cli++ #;xorl %ebx, %ebx+ movw %cs, %bx #; EBX_high_word=0+ shll $4, %ebx+ addl $(MyGDT - int13_handler), %ebx+ movl %ebx, %cs:MyGDT - int13_handler + 2+ + /* Test to see if A20 is enabled or not */+ xorw %ax, %ax+ movw %ax, %ds /* DS=0 */+ decw %ax+ movw %ax, %es /* ES=0xFFFF */++ movw %ds:0, %ax+ movw %ax, %bx+ xorw %es:0x10, %bx+ notw %ax+ movw %ax, %ds:0+ movw %ax, %dx+ xorw %es:0x10, %dx+ notw %ax+ movw %ax, %ds:0++ orw %bx, %dx+ pushw %dx /* 0=A20 off, 1=A20 on */+ jnz 1f+ movb $1, %dl /* A20 is off, so it need turn on. */+ call int13_enable_a20+1:++ shll $7, %ecx /* 128 dwords per sector */++ lgdt %cs:MyGDT - int13_handler+ movl %cr0, %eax+ orb $1, %al+ movl %eax, %cr0 /* Switch to protected mode */++ movw $16, %bx /* Switch to 4G data segment */+ movw %bx, %ds+ movw %bx, %es++ cld++ addr32 rep movsl++// movw $8, %bx /* Switch back to 64K data segment */+// movw %bx, %ds+// movw %bx, %es++ andb $0xFE, %al+ movl %eax, %cr0 /* Back to real mode */+ + popw %dx+ popw %es+ popw %ds++ /* Keep A20 on. This should hurt nothing. */+#if 0+ /* Disable A20 if necessary ! */+ andw %dx, %dx /* 0=orig A20 off, 1=orig A20 on */+ jnz 1f+ call int13_enable_a20+1:+#endif++ popfl++ popal+ popw %es+ xorb %ah, %ah+ ret+4:+ movb 2(%si), %bl /* number of sectors to be moved */+ pushw %cs+ popw %es+ movw $(GDT_data - int13_handler), %si /* SI changed!! */+ movw %ax, %es:0x12(%si) #; source physical address low 16 bits+ shrl $16, %eax+ movb %al, %es:0x14(%si) #; source physical address bit 16-23+ movb %ah, %es:0x17(%si) #; source physical address bit 24-32+ movw %cx, %es:0x1a(%si) #; dest physical address low 16 bits+ shrl $16, %ecx+ movb %cl, %es:0x1c(%si) #; dest physical address bit 16-23+ movb %ch, %es:0x1f(%si) #; dest physical address bit 24-32++ xorw %cx, %cx /* ECX is 0 */+ movl %ecx, %es:(%si)+ movl %ecx, %es:0x04(%si)+ movl %ecx, %es:0x08(%si)+ movl %ecx, %es:0x0c(%si)+ movl %ecx, %es:0x20(%si)+ movl %ecx, %es:0x24(%si)+ movl %ecx, %es:0x28(%si)+ movl %ecx, %es:0x2c(%si)+ movb %bl, %ch /* CX=number of words to be moved */+ movb $0x87, %ah /* access extended memory */++ pushw %ax+ smsw %ax+ testb $1, %al+ popw %ax+ jnz 4f /* protected mode */+#if 0+ pushw %ax+ pushw %ds+ xorw %ax, %ax+ movw %ax, %ds+ movl 0x0054, %eax /* point to int15 vector */+ popw %ds+ cmpl %eax, %cs:(ROM_int15 - int13_handler)+ popw %ax+ je 4f+ /* real mode with int15 vector changed */+#endif+ /* real mode */+ pushfw+ lcall %cs:*(ROM_int15 - int13_handler)+ +#if 0+ /* ensure A20 is on when we return to caller. */++ /* A20 control is a slow operation. Enabling A20 here in int13 handler+ * could cause problems on some machines.+ */++ pushfw++ cli /* yes, keep interrupt off when controlling A20 */++ movw $0x00ff, %cx # try so many times on failure+ movw $0x0001, %dx # non-zero means `enable'+ call enable_disable_a20+ //sete %dl # DL=1 means success++ popfw+#endif++ jmp 6f+4:+ ///* protected mode, or real mode with int15 vector unchanged */+ /* protected mode */+ int $0x15+6:+ popal+ popw %es+ jc 6f+ xorb %ah, %ah+ ret+6:+ movb $0, 2(%si) /* signal no sectors successfully moved */+5:+ /* sector not found */+ movb $4, %ah+ stc+ ret+2:+ /* normal disk drive */+ pushw %si /* save SI */+ pushl %eax /* save EAX */+#if 1+ smsw %ax+ testb $1, %al+ jnz 2f /* protected mode */+#else+ xorw %ax, %ax+ pushw %ds+ movw %ax, %ds+ movw $0x004c, %si /* point to int13 vector */+ ldsw (%si), %si /* point to int13 service routine */+ cmpb $0x63, (%si) /* win98 places ARPL here */+ popw %ds+ je 2f+#endif+ /* in real mode DOS, call original real mode int13 */+ popl %eax+ popw %si+ pushfw+ lcall %cs:*(int13_offset - int13_handler)+ ret+2:+ /* now inside win98, will call protected mode int13 */++ pushl %ebx /* save EBX */++ /* set SI to the drive map */+ movw $(hooked_drive_map - int13_handler), %si+ /* find the drive number from the drive map */+ cld+ subw $8, %si+2: + addw $8, %si+ lodsl %cs:(%si), %eax+ testl %eax, %eax /* end of map table? */+ movl %eax, %ebx /* save the map to EBX */+ jz 2f /* yes, no map found */+ cmpb %dl, %ah /* found the map? */+ jne 2b /* no, check the next slot */++ /* drive is mapped. check if map a whole drive */+ shrl $16, %eax+ testb $62, %ah+ jnz 2b /* no, check the next slot */+ movl %cs:(%si), %eax /* StartLBA */+ testl %eax, %eax+ jnz 2b /* no, check the next slot */+ movl %cs:4(%si), %eax/* S_count */+ shrl $1, %eax+ jnz 2b /* no, check the next slot */+2:+ testl %ebx, %ebx /* mapped or not mapped ? */+ jz 2f /* not mapped, do nothing */+ movb %bl, %dl /* use the mapped FROM_DRIVE for win98 */+2:+ movb -6(%bp), %al /* AL=FROM_DRIVE */+ testb %al, %al /* hard drive emulation? */+ jns 2f /* floppy, jump */+ cmpb %al, %dl+ jb 2f+ incb %dl+2:+ popl %ebx+ popl %eax+ popw %si+ int $0x13+ ret++modify_boot_sectors:++ pushl %eax+ movw 2(%bp), %ax /* get original AX */+ cmpb $0x02, %ah /* is it read? */+ jne 4f+ cmpw $0x0001, %cx /* read from cylinder 0, sector 1? */+ jne 4f+#; testb %dl, %dl /* The TO_DRIVE is hard drive? */+#; jns 4f /* no, do nothing */+ cmpw $0xaa55, %es:0x1fe(%bx)+ jne 4f+ movl -14(%bp), %eax /* S_count */+ shrl $1, %eax+ jz 4f+ movl -10(%bp), %eax /* StartLBA */+ testl %eax, %eax+ jz 4f+ movl -6(%bp), %eax /* FROM_DRIVE, TO_DRIVE, H, S */+ testb %al, %al /* The FROM_DRIVE is hard drive? */+ jns modify_floppy /* no, goto floppy boot record modification */+ testb %dh, %dh /* read from head 0? */+ jnz modify_HD_DOS /* no, goto HD DOS boot record modification */+ shrl $16, %eax /* AL=MaxH, AH=MaxS */+ andb $63, %ah /* AH=MaxS */+ cmpb $1, %ah+ jbe 4f /* do not modify partition table when disable CHS mode */++ pushl %edx+ pushl %ecx+ pushw %si+ pushl %edi+ pushl %ebx++ movw %ax, %di /* save AX to DI */+ xorl %ecx, %ecx+ xorl %edx, %edx+ movb %ah, %cl+ mulb %ah /* AX = AH * AL */+ addw %ax, %cx /* CX = sectors per cylinder */+ movl -10(%bp), %eax /* EDX:EAX=StartLBA */+ divl %ecx /* EAX=cylinders, EDX=remainders */+ cmpl $1023, %eax+ ja 8f+ shll $16, %eax /* cylinders save to hi word */+ movw %dx, %ax /* remainders */+ movw %di, %dx /* DH=MaxS */+ divb %dh /* AL=heads, AH=sectors */+ movl %eax, %ecx /* ECX holds CHS differences */+ + movw $0x1bf, %si+ addw %bx, %si+ movw $8, %di /* 8 entries in partition table */+5:+ lodsl %es:(%si), %eax+ testl %eax, %eax+ jz 6f+ movl %ecx, %edx+ movl %eax, %ebx+ shrl $16, %edx /* DX=cylinder_difference */+ shrl $8, %ebx+ shrb $6, %bl+ xchgb %bl, %bh /* BX=old cylinder number */+ cmpw %dx, %bx+ jb 8f+ subw %dx, %bx /* BX=new cylinder number */+ movw %bx, %dx /* save BX to DX */+ shll $16, %ebx /* save new cylinder number to hi word */++ cmpb %cl, %al /* AL=old head number, CL=head_difference */+ jae 7f+ decw %dx /* DX holds the new cylinder number */+ jc 6f+ movw %dx, %bx /* update BX */+ shll $16, %ebx /* save new cylinder number to hi word */+ movb %cl, %dl+ subb %al, %dl+ decb %dl+ movb -4(%bp), %al /* AL=MaxH */+ subb %dl, %al /* AL holds the new head number */+ jmp 3f+7:+ subb %cl, %al /* AL holds the new head number */+3:+ movb %al, %bl /* put the new head number to BL */++ andb $63, %ah+ cmpb %ch, %ah /* AH=old sector number, CH=sector_diff */+ ja 7f+ testl %ebx, %ebx+ jz 6f+ testb %al, %al+ jnz 3f+ shrl $16, %ebx+ decw %bx+ shll $16, %ebx+ movb -4(%bp), %al /* AL=MaxH */+ incb %al /* no worry on overflow, see decb followed */+3:+ decb %al /* AL holds the new head number */+ subb %ah, %ch+ movb -3(%bp), %ah /* AH=MaxS */+ andb $63, %ah+7:+ subb %ch, %ah /* AH holds the new sector number */+ /* AL holds the new head number */+ shrl $16, %ebx+ shlb $6, %bh+ orb %bh, %ah+ xorb %bh, %bh+ shll $16, %ebx+ movw %ax, %bx+ shrl $24, %eax+ testw $1, %di+ jnz 7f+ cmpb $0x05, %al /* 0x05 is extended partition */+ je 3f+ cmpb $0x0f, %al /* 0x0f is LBA extended partition */+ jne 7f+3:+ xorb %al, %al /* disable the extended partition */+7:+ shll $24, %eax+ orl %ebx, %eax+ movl %eax, %es:-4(%si) /* update the CHS number */+6:+ decw %di+ jz 8f+ testw $1, %di+ jnz 7f /* jnz 5b */+ addw $8, %si+7:+ jmp 5b+8:+ popl %ebx+ popl %edi+ popw %si+ popl %ecx+ popl %edx+4:+ popl %eax /* end partition table modification */+ ret++modify_floppy:++ /* AL=FROM_DRIVE is the floppy drive number. */++ cmpb $0x00, %dh /* read from head 0? */+ jne 4b+#; xorl %eax, %eax+#; cmpl %eax, %es:0x1c(%bx) /* Number of hidden sectors */+#; je 4b+#; cmpl $0x33544146, %es:0x52(%bx) /* FAT32? */+#; je 5f+#; /* NTFS drive number is also at offset 0x24 */+#; //cmpl $0x31544146, %es:0x36(%bx) /* FAT16? */+#; //jne 4b+#; cmpw $0x80, %es:0x24(%bx) /* Physical drive number */+#; jne 4b+#; movb %al, %es:0x24(%bx) /* AL=floppy drive number */+#; jmp 6f+#;5:+#; cmpb $0x80, %es:0x40(%bx) /* Physical drive number */+#; jne 4b+#; movb %al, %es:0x40(%bx) /* AL=0 means floppy */+#;6:+#; movl %eax, %es:0x1c(%bx) /* let number of hidden sectors=0 */+#; /*movb $0xf0, %es:0x15(%bx)*/ /* set floppy media descriptor */+#; jmp 4b++ pushl %ecx+ pushw %si++ /* FAT12/FAT16/NTFS drive number is at offset 0x24. */+ movw $0x24, %si++ xorl %ecx, %ecx++ /* check if it is FAT32. */++ /* FAT32 should have 0 root_dir_entries and total_sectors_short. */+ cmpl %ecx, %es:0x11(%bx)+ jne 5f /* not FAT32 */++ /* FAT32 should have 0 sectors_per_fat. */+ cmpw %cx, %es:0x16(%bx)+ jne 5f /* not FAT32 */++ /* FAT32 should have non-zero total_sectors_long. */+ cmpl %ecx, %es:0x20(%bx)+ je 5f /* not FAT32 */++ /* FAT32 should have non-zero sectors_per_fat32. */+ cmpl %ecx, %es:0x24(%bx)+ je 5f /* not FAT32 */++ /* Now it is FAT32, and the drive number is at offset 0x40. */+ movw $0x40, %si+5:+ movb %al, %es:(%bx, %si) /* modify the boot drive number. */++ movl %ecx, %es:0x1c(%bx) /* let number of hidden sectors=0 */+ /*movb $0xf0, %es:0x15(%bx)*/ /* set floppy media descriptor */++ popw %si+ popl %ecx++ jmp 4b++modify_HD_DOS:++ cmpb $0x01, %dh /* read from head 1? */+ jne 4b+ movl -10(%bp), %eax /* StartLBA */+ testl %eax, %eax+ jz 4b+ cmpl %eax, %es:0x1c(%bx) /* Number of hidden sectors */+ jbe 4b+ subl %eax, %es:0x1c(%bx)+ movzbl -3(%bp), %eax /* AH=MaxS */+ cmpl %eax, %es:0x1c(%bx) /* Number of hidden sectors */+ jnb 4b+ movl %eax, %es:0x1c(%bx)+ jmp 4b++ENTRY(atapi_dev_count) .long 0+ENTRY(min_cdrom_id) .long 0xE0+max_cdrom_id: .long 0xE0+ENTRY(memdisk_raw) .long 1 /* set to 0 if accessing memdrives using int15/AH=87h */++minimum_mem_in_map:+ .long 0++int15_e820_handler:++ cmpw $0xe820, %ax //cmpl $0x0000e820, %eax+ jne 1f++ /* Newer BIOSes - GET SYSTEM MEMORY MAP */++ cmpl $0x534D4150, %edx /* "SMAP" */+ jne 1f+ cmpl $20, %ecx+ jb 2f+ pushfw+ lcall %cs:*(ROM_int15 - int13_handler)+ jc 3f+ cmpl $0x534D4150, %eax /* "SMAP" */+ jne 2f+ pushal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -