📄 grub-0.97-patch4-emulation
字号:
+ /* save bits 0-6 of %al in %dl */+ movw %ax, %dx+ andb $0x7f, %dl+ /* save the highest bit in %bl */+ movb %al, %bl+ xorb %dl, %bl+ /* set %ds to 0 */+ xorw %ax, %ax+ movw %ax, %ds+ /* set %si to the key map */+ movw $ABS(EXT_C(bios_key_map)), %si++ /* find the key code from the key map */+2:+ lodsw+ /* check if this is the end */+ testw %ax, %ax+ jz 3f+ /* check if this matches the key code */+ cmpb %al, %dl+ jne 2b+ /* if so, perform the mapping */+ movb %ah, %dl+3:+ /* restore %ax */+ movw %dx, %ax+ orb %bl, %al+ /* make sure that CF is set */+ orw $1, 6(%bp)+ /* restore other registers */+ popw %si+ popw %ds+ popw %dx+ popw %bx+ popw %bp+ iret+ +4:+ /* tricky: jmp (0x74) <-> je (0xeb) */+ xorb $(0x74 ^ 0xeb), ABS(int15_skip_flag)+1:+ /* just cascade to the original */+ /* ljmp */+ .byte 0xea+int15_offset: .word 0+int15_segment: .word 0++ .code32++ .align 4 +ENTRY(bios_key_map)+ .space (KEY_MAP_SIZE + 1) * 2+ + +/*+ * set_int13_handler(map)+ *+ * Copy MAP to the drive map and set up int13_handler.+ */+ENTRY(set_int13_handler)+ pushl %ebp+ movl %esp, %ebp++ pushl %edi+ pushl %esi++ /* copy MAP to the drive map */+ movl $(DRIVE_MAP_SIZE * 12 / 4), %ecx /* sizeof(struct drive_map_slot) */+ movl $ABS(hooked_drive_map), %edi+ movl 8(%ebp), %esi+ cld+ repz movsl++// Now initialized early at the beginning of this file+//+// /* save the original int13 handler */+// movl $0x4c, %edi+// movl (%edi), %eax+// movl %eax, ABS(int13_offset)+ + /* decrease the lower memory size and set it to the BIOS memory */+ movl $0x413, %edi+ movl %edi, %esi++ lodsw+ /* KBytes that int13 handler occupies */+ subb ABS(int13_handler), %al+ stosw+ + /* compute the segment(high word) */+ shll $(16 + 6), %eax++ /* the offset(low word) should be 0x100 */+ movw $0x100, %ax++ /* save the new int13 handler */+ movl $0x4c, %edi+ stosl++ /* EDI points to the destination int13 handler in the reserved area */+ movl %eax, %edi /* the int13 vector just saved */+ shrl $12, %edi /* get base address of segment */++ /* set ESI to the drive map */+ movl $ABS(hooked_drive_map), %esi+ movl $(DRIVE_MAP_SIZE), %ecx+1:+ cmpb $0xff, 1(%esi) /* Is there a mapped memdrive? */+ je 1f /* Yes, hook int15 for e820 memory */+ /* try next slot */+ addl $12, %esi /* sizeof(struct drive_map_slot) */+ loop 1b+ jmp 2f /* no memdrives, don't hook int15 */++1:+ /* save the new int15 handler */+ movw $(int15_e820_handler - int13_handler), %ax /* segment still in high word */+ movl %eax, 0x54++2:+ /* copy int13_handler to the reserved area */+ movl $ABS(int13_handler), %esi+ movl $((int13_handler_end - int13_handler) / 4), %ecx+ cld+ repz movsl++ popl %esi+ popl %edi+ popl %ebp+ ret++/* int+ * unset_int13_handler(check_status_only)+ *+ * Restore the original int13 handler+ *+ * Return 0 for success and non-zero for failure.+ */+ENTRY(unset_int13_handler)+ pushl %ebp+ movl %esp, %ebp++ pushl %edi+ + /* check if int13_handler is set */+ movl $0x413, %edi+ movw (%edi), %ax+ cmpw $640, %ax+ jae 1f #; needn't unset+// cmpw $632, %ax+// jb 1f+ shll $(16 + 6), %eax++ /* the offset(low word) should be 0x100 */+ movw $0x100, %ax++ cmpl %eax, 0x4c+ jne 1f #; not hooked, unset failure+ movl %eax, %edi+ shrl $12, %edi /* segment base address */++ cmpl $0x9A000000, 0x1C(%edi) /* old int 13 */+ jb 1f++ cmpl $0x9A000000, 0x0C(%edi) /* old int 15 */+ jb 1f++ movl ABS(int13_offset), %eax+ cmpl 0x1C(%edi), %eax+ jnz 1f++ movl ABS(ROM_int15), %eax+ cmpl 0x0C(%edi), %eax+ jnz 1f++ xorl %eax, %eax++ cmpl %eax, 8(%ebp)+ jnz 1f++ /* increase the lower memory size */++ movzbw (%edi), %ax+ addw %ax, 0x413++ /* restore the original int15 handler */+ movl ABS(ROM_int15), %eax+ movl %eax, 0x54++ /* restore the original int13 handler */+ movl ABS(int13_offset), %eax+ movl %eax, 0x4c+1:+ /* return non-zero for failure */+ popl %edi+ popl %ebp+ ret+++/* + * Map a drive to another drive or a disk image file.+ */+ + .code16+ + .align 16++int13_handler:++ /* memory size in K that int13 handler uses. */++ .byte ((int13_handler_end - int13_handler + 0x3ff) / 0x400)++ /* 9-byte Space reserved for future use */++ . = int13_handler + 0x0A++VARIABLE(floppies_orig)+ .byte 0++ . = int13_handler + 0x0B++VARIABLE(harddrives_orig)+ .byte 0++ . = int13_handler + 0x0C++ROM_int15:+ .long 0++ . = int13_handler + 0x10++ /* 12-byte Space reserved for future use */++ . = int13_handler + 0x1C++int13_offset: .word 0+int13_segment: .word 0++ . = int13_handler + 0x20 /* drive map table begins at 0x20 */++ENTRY(hooked_drive_map)+ .space (DRIVE_MAP_SIZE + 1) * 12 /* sizeof(struct drive_map_slot) */++ /* Space reserved for future enlargement of the drive map table */++ . = int13_handler + 0x100 /* real int13 handler entry 0x100 */+++ cmpb $0x1a, %ah /* PS/2 low level format ESDI drive!!!! */+ je error_01_disable2 /* disabled in any case */++ cld+ pushl %eax+ pushw %bp+ movw %sp, %bp++/* EDD30 code imported from edd30.asm of Smart Boot Manager. */++/*+#; asmsyntax=nasm+#;+#; CD-ROM Boot Extension v 1.1 for Smart Boot Manager+#; +#; Copyright (C) 2000, Christopher Li <chrisl@gnuchina.org>.+#; Copyright (C) 2000, James Su <suzhe@gnuchina.org>+#;+#; This is free software, you can redistribute it and/or modify it+#; under the terms of the GNU General Public License version 2 or above.+#;+#; The ATAPI driver is based on the source code of atadrv written by+#; Hale Landis <hlandis@ibm.net>, Thanks him a lot!+#;+#; Without his great program, we could not implement the CD-ROM Boot feature+#; so quickly.+#;+*/+++//#define EDD_3_0++#define sane_check+#define check_extra_fail++//#define CB_DATA 0 //; data reg in/out pio_base_addr1+0+//#define CB_FR 1 //; feature reg out pio_base_addr1+1+//#define CB_SC 2 //; sector count in/out pio_base_addr1+2+//#define CB_SN 3 //; sector number in/out pio_base_addr1+3+//#define CB_CL 4 //; cylinder low in/out pio_base_addr1+4+//#define CB_CH 5 //; cylinder high in/out pio_base_addr1+5+//#define CB_DH 6 //; device head in/out pio_base_addr1+6+//#define CB_STAT 7 //; primary status in pio_base_addr1+7+//#define CB_CMD 7 //; command out pio_base_addr1+7+//#define CB_DC 8 //; device control out pio_base_addr2+6+//#define CB_ASTAT 8 //; alternate status in pio_base_addr2+6+//#define CB_DC_SRST 0x04 //; soft reset+#define CB_STAT_BSY 0x80 //; busy+#define CB_STAT_RDY 0x40 //; ready+#define CB_STAT_SKC 0x10 //; seek complete++#define CB_STAT_DRQ 0x08 //; data request+#define CB_STAT_ERR 0x01 //; error++#define CB_SC_P_TAG 0xf8 //; ATAPI tag (mask)+#define CB_SC_P_REL 0x04 //; ATAPI release+#define CB_SC_P_IO 0x02 //; ATAPI I/O+#define CB_SC_P_CD 0x01 //; ATAPI C/D++#define FAILBIT8 0x0100 //; SC( CD/IO bits) wrong at end of cmd+#define FAILBIT6 0x0040 //; byte count wrong at data packet xfer time+#define FAILBIT5 0x0020 //; SC (IO bit) wrong at data packet xfer time+#define FAILBIT4 0x0010 //; SC (CD bit) wrong at data packet xfer time+#define FAILBIT3 0x0008 //; byte count wrong at cmd packet xfer time+#define FAILBIT2 0x0004 //; SC wrong at cmd packet xfer time+#define FAILBIT0 0x0001 //; slow setting BSY=1 or DRQ=1 after AO cmd++#define CB_DC_HD15 0x08 //; bit should always be set to one+#define CB_DC_NIEN 0x02 //; disable interrupts+#define cmd_DC CB_DC_HD15+#define cmd_DC_ni CB_DC_HD15 | CB_DC_NIEN++#undef DEBUG++#ifdef DEBUG+#include "debug.h"+#endif++ cmpb $0, %cs:(atapi_dev_count - int13_handler)+ jz no_cdrom /* no cdrom */+ cmpb %cs:(min_cdrom_id - int13_handler), %dl+ jb not_cdrom_drv /* not cdrom drive */+ cmpb %cs:(max_cdrom_id - int13_handler), %dl+ jbe edd30_for_cdrom++not_cdrom_drv:+// cmpb %cs:(min_cdrom512_id - int13_handler), %dl+// jb not_cdrom512_drv /* not cdrom512 drive */+// cmpb %cs:(max_cdrom512_id - int13_handler), %dl+// jbe edd30_for_cdrom512+//+//not_cdrom512_drv:+ cmpb $0, %cs:(emu_disk_type - int13_handler)+ je not_emu_drv++ cmpb %cs:(edd30_cdemu_spec - int13_handler + 2), %dl #; struc_cdemu_spec.emu_drvid+ je cdemu_int13h++not_emu_drv:++no_cdrom:++ pushw %si++ /* set %si to the drive map */+ movw $(hooked_drive_map - int13_handler), %si+ /* find the drive number from the drive map */+ subw $12, %sp+1: + addw $12, %sp+ lodsl %cs:(%si), %eax+ pushl %eax+ lodsl %cs:(%si), %eax+ pushl %eax+ lodsl %cs:(%si), %eax+ pushl %eax++ movl -6(%bp), %eax /* FROM, TO, Hmax, Smax */++ /* check if this is the end */+ testl %eax, %eax+ jnz 3f /* not end, continue */+ movl -10(%bp), %eax /* StartLBA */+ testl %eax, %eax+ jnz 3f /* not end, continue */+ movl -14(%bp), %eax /* S_count */+ testl %eax, %eax+ jz 2f /* map whole drive to itself signals the end */+3:+ /* Now this is a valid drive map slot */+ movw -6(%bp), %ax /* AL=FROM, AH=TO */+ cmpb %al, %dl /* check if this matches the drive number */+ jne 1b /* no, continue to check the next map */++ /* yes, found the map corresponding to drive DL */+ movl -10(%bp), %eax /* StartLBA */+ testl %eax, %eax+ jnz drive_emulation+ movl -14(%bp), %eax /* S_count */+ shrl $1, %eax+ jnz drive_emulation+ movw -4(%bp), %ax /* AL=Hmax, AH=Smax */+ testb $62, %ah /* Sectors > 1 means force geom, this -- */+ jnz drive_emulation /* -- also leads to drive emulation */++ /* ignore geom and directly map a whole drive */+ + /* bits of AH:+ * 7 bit set means readonly/fakewrite+ * 6 bit set means disable LBA+ * 5 - 1 bits already cleared(=0)+ * 0 bit cleared means disable CHS+ * So, if AH!=1, it is a restricted disk access;+ * and if AH=1, it is a normal disk access.+ */+ cmpb $1, %ah+ je 1f+ call restricted_map+1:+ /* map a whole drive, normal access */+ movw -6(%bp), %ax /* AL=FROM, AH=TO */+ movb %ah, %dl /* Let DL access TO instead of FROM */+2:+ /* might map to itself, i.e., actually not mapped */+ + movw -2(%bp), %si /* restore SI */++ pushw 10(%bp) /* pushfw, simulate the interrupt call */+ + movl 2(%bp), %eax /* restore EAX */+ movw (%bp), %bp /* restore BP */++// .byte 0x9a /* lcall, simulate the interrupt call */+//int13_offset: .word 0+//int13_segment: .word 0+ lcall %cs:*(int13_offset - int13_handler)++ /* the original int13 vector must be stored in the first kilo bytes */++ . = . - (. - int13_handler) / 0x401++ pushw %ax /* save AX */+ pushfw /* save flags returned by int13 */+ popw %ax+ movw %sp, %bp /* set new BP */+ movw %ax, 26(%bp) /* update the flags in the stack */+ + /* check if should restore(reversely map) the drive number */+ jc 1f /* restore DL on error */+ movw 18(%bp), %ax /* lower word of the saved EAX */+ cmpb $0x08, %ah /* int13 AH=08h, read drive parameters */+ je 3f /* DL==number of drives, should not restore */+ //cmpb $0x15, %ah /* int13 AH=15h, read drive type */+ //je 3f /* CX:DX==total sectors, should not restore */+ //jne 1f+ xorb $0x15, %ah /* int13 AH=15h, read drive type */+ /* CF=0 for now. if ZF=1, then AH was 0x15, and it is "equal"+ * for the jxx class of instructions. if ZF=0, then AH was not 0x15,+ * and it is "above" for the jxx class of instructions.+ */+1:+ movw 10(%bp), %ax /* get the drive mapping */+ /* should not simply use "jne 2f" here because ZF is unknown when+ * error occurred for the above int13 call+ */+ ja 2f /* "above" means it is not int13 AH=15h */+ jc 2f /* "below" means error occurred for int13 */+ /* "equal" means int13 AH=15h */+ testb %al, %al /* the FROM drive is harddrive? */+ js 3f /* yes, do not restore DL */+ /* restore DL for floppy int13 AH=15h call */+2:+ /* try to restore DL if possible */+ cmpb %al, %ah /* check if the mapping was performed */+ je 3f /* not performed, so need not restore DL */+ cmpb %dl, %ah+ jne 3f /* DL changed by int13, so do not restore */+ movb %al, %dl /* restore DL back to the FROM drive */+3:+ movl 18(%bp), %eax /* restore the original EAX */+ popw %ax /* update the int13 status in AX */+ movw 16(%bp), %bp /* restore the original BP */+ addw $20, %sp+ iret++restricted_map:+ movw 2(%bp), %ax /* lower word of the saved EAX */++ /* CHS read functions */+ cmpb $0x02, %ah /* read sectors */+ je 2f+ cmpb $0x04, %ah /* verify sectors, also a read operation */+ je 2f+ cmpb $0x0a, %ah /* read long sectors */+ je 2f+ cmpb $0x0c, %ah /* seek to cylinder */+ je 2f+ cmpb $0x21, %ah /* PS/1 and newer PS/2 - read multiple disk sectors */+ jne 1f+2:+ movb -3(%bp), %ah /* AH=Smax */+ testb $63, %ah /* check if Sectors=0, i.e., disable CHS */+ jz error_01_disable+ ret+1:+ /* CHS write functions */+ cmpb $0x03, %ah /* CHS write sectors */+ je 2f+ cmpb $0x05, %ah /* PC/XT/AT/EISA format tracks */+ je 2f+ cmpb $0x06, %ah /* PC/XT format tracks with bad sectors */+ je 2f+ cmpb $0x07, %ah /* PC/XT format multiple cylinders */+ je 2f+ cmpb $0x0b, %ah /* PC/XT/AT/EISA write sectors with ECC */+ je 2f+ cmpb $0x0f, %ah /* PC/XT/PS/1 write sector buffer */+ je 2f+ cmpb $0x22, %ah /* PS/1 and newer PS/2 - write multiple disk sectors */+ jne 1f+2:+ movb -3(%bp), %ah /* AH=Smax */+ testb $63, %ah /* check if Sectors=0, i.e., disable CHS */+ jz error_01_disable+ testb $0x80, %ah /* readonly access? */+ jnz readonly_fakewrite+ ret+1:+ /* LBA read functions */+ cmpb $0x41, %ah /* Extensions - INSTALLATION CHECK */+ je 2f+ cmpb $0x42, %ah /* Extensions - EXTENDED READ */+ je 2f+ cmpb $0x44, %ah /* Extensions - verify sectors */+ je 2f+ cmpb $0x45, %ah /* Extensions - LOCK/UNLOCK DRIVE */+ je 2f+ cmpb $0x46, %ah /* Extensions - EJECT MEDIA */+ je 2f+ cmpb $0x47, %ah /* Extensions - EXTENDED SEEK */+ je 2f+ cmpb $0x48, %ah /* Extensions - GET DRIVE PARAMETERS */+ je 2f+ cmpb $0x49, %ah /* Extensions - detect media change */+ je 2f+ cmpb $0x4a, %ah /* Bootable CDROM - INITIATE DISK EMULATION */+ je 2f+ cmpb $0x4b, %ah /* Bootable CDROM - TERMINATE DISK EMULATION */+ je 2f+ cmpb $0x4c, %ah /* Bootable CDROM - INITIATE DISK EMULATION AND BOOT */+ je 2f+ cmpb $0x4d, %ah /* Bootable CDROM - RETURN BOOT CATALOG */+ je 2f+ cmpb $0x4e, %ah /* Extensions v2.1 - SET HARDWARE CONFIGURATION */+ jne 1f+2:+ movb -3(%bp), %ah /* AH=Smax */+ testb $64, %ah /* disable LBA? */+ jnz error_01_disable+ ret+1:+ /* LBA write functions */+ cmpb $0x43, %ah /* Extensions - EXTENDED WRITE */+ jne 1f+2:+ movb -3(%bp), %ah /* AH=Smax */+ testb $64, %ah /* disable LBA? */+ jnz error_01_disable+ testb $0x80, %ah /* readonly access? */+ jnz readonly_fakewrite+1:+ /* no restrictions, return and continue */+ ret++error_01_disable:+ /* function not supported, or the input CHS is invalid */+ addw $14, %sp /* adjust SP */+ popw %si+ popw %bp+ popl %eax+error_01_disable2:+ movb $0x01, %ah /* signal invalid function call */+ stc /* signal error */+ lret $2 /* far return discard the original flags */++readonly_fakewrite:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -