📄 asm.s
字号:
movl %cs:ABS(original_registers) + 16, %eax movl %cs:ABS(original_registers) + 20, %ebx movl %cs:ABS(original_registers) + 24, %ecx movl %cs:ABS(original_registers) + 28, %edx movl %cs:ABS(original_registers) + 32, %esi movl %cs:ABS(original_registers) + 36, %edi movl %cs:ABS(original_registers) + 40, %ebp /* stack is available, so we can push and pop. */ pushw %bp pushw %ax movw %sp, %bp movw %cs:ABS(original_registers) + 44, %ax #; return IP movw %ax, 4(%bp) popw %ax popw %bp pushl $1 #; CF=1 indicating error popfl #; CLD, CLI, and many more... call unset_fault_recovery_handler ret /* never come here. */ iret .code32/* * set_int15_handler(void) * * Set up int15_handler. */ENTRY(set_int15_handler) .code32 pushl %edi /* save the original int15 handler */ movl $0x54, %edi#if 0 movw (%edi), %ax movw %ax, ABS(int15_offset) movw 2(%edi), %ax movw %ax, ABS(int15_segment) /* save the new int15 handler */ movw $ABS(int15_handler), %ax movw %ax, (%edi) xorw %ax, %ax movw %ax, 2(%edi)#else movl (%edi), %eax movl %eax, ABS(int15_offset) /* set the new int15 handler */ movl $ABS(int15_handler), %eax stosl#endif popl %edi ret/* * unset_int15_handler(void) * * Restore the original int15 handler */ENTRY(unset_int15_handler) .code32 pushl %edi /* check if int15_handler is set */ movl $0x54, %edi#if 0 movw $ABS(int15_handler), %ax cmpw %ax, (%edi) jne 1f xorw %ax, %ax cmpw %ax, 2(%edi) jne 1f /* restore the original */ movw ABS(int15_offset), %ax movw %ax, (%edi) movw ABS(int15_segment), %ax movw %ax, 2(%edi)#else movl $ABS(int15_handler), %eax cmpl %eax, (%edi) jne 1f /* restore the original */ movl ABS(int15_offset), %eax stosl#endif1: popl %edi ret/* * Translate a key code to another. * * Note: This implementation cannot handle more than one length * scancodes (such as Right Ctrl). */ .code16int15_handler: /* if non-carrier, ignore it */ jnc 1f /* check if AH=4F */ cmpb $0x4F, %ah jne 1f /* E0 and E1 are special */ cmpb $0xE1, %al je 4f cmpb $0xE0, %al /* this flag is actually the machine code (je or jmp) */int15_skip_flag: je 4f pushw %bp movw %sp, %bp pushw %bx pushw %dx pushw %ds pushw %si /* 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, %dl3: /* 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 0xeaint15_offset: .word 0int15_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) .code32 pushl %ebp movl %esp, %ebp pushl %edi pushl %esi /* copy MAP to the drive map */ movl $(DRIVE_MAP_SIZE * DRIVE_MAP_SLOT_SIZE / 4), %ecx 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(ROM_int13) /* 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), %ecx1: cmpb $0xff, 1(%esi) /* Is there a mapped memdrive? */ jne 2f /* No. Try next slot */ testb $0x40, 5(%esi) /* Is To_DRIVE a CDROM? */ jz 1f /* No. Memdrive indeed. Hook int15 */2: /* try next slot */ addl $DRIVE_MAP_SLOT_SIZE, %esi 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, 0x542: /* 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) .code32 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 */ /* check our int13 signature "$INT13SFGRUB4DOS" */ cmpl $0x544E4924, 0x103(%edi) /* $INT */ jnz 1f cmpl $0x46533331, 0x107(%edi) /* 13SF */ jnz 1f cmpl $0x42555247, 0x10B(%edi) /* GRUB */ jnz 1f cmpl $0x534F4434, 0x10F(%edi) /* 4DOS */ jnz 1f //cmpl $0x9A000000, 0x1C(%edi) /* old int 13 */ cmpl $0x5A000000, 0x1C(%edi) /* old int 13 */ jb 1f //cmpl $0x9A000000, 0x0C(%edi) /* old int 15 */ cmpl $0x5A000000, 0x0C(%edi) /* old int 15 */ jb 1f movl ABS(ROM_int13), %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(ROM_int13), %eax movl %eax, 0x4c xorl %eax, %eax /* success */1: /* return non-zero for failure */ popl %edi popl %ebp ret/* * Map a drive to another drive or a disk image file. */ .code16 .align 4ENTRY(bios_drive_map) .space (DRIVE_MAP_SIZE + 1) * DRIVE_MAP_SLOT_SIZE /* align it this way so that int13_handler can be used as a segment * base address. The `cdrom' command requires this. */ .align 16int13_handler: /* memory size in K that int13 handler uses. */ .byte ((int13_handler_end - int13_handler + 0x3ff) / 0x400) /* 3-byte space reserved. */ . = int13_handler + 0x4 /* Signature */ .ascii "G4DS" /* Version number */ .word 1 . = int13_handler + 0x0AVARIABLE(floppies_orig) .byte 0 /* original value at 0040:0010 */ . = int13_handler + 0x0BVARIABLE(harddrives_orig) .byte 0 /* original value at 0040:0075 */ . = int13_handler + 0x0CVARIABLE(ROM_int15) .long 0 /* original int15 vector */ . = int13_handler + 0x10 /* 12-byte space reserved. */ . = int13_handler + 0x1CROM_int13: .long 0 /* original int13 vector */ . = int13_handler + 0x20 /* drive map table begins at 0x20 */ENTRY(hooked_drive_map) .space (DRIVE_MAP_SIZE + 1) * DRIVE_MAP_SLOT_SIZE /* 8-byte space reserved. */ . = int13_handler + 0x100 /* real int13 handler entry at 0x100 */ jmp 1f . = int13_handler + 0x103 /*******************************************************************/ /* ----------------- SafeMBRHook structure begin ----------------- */ .ascii "$INT13SF" /* Win9x use this! Don't touch! */ .ascii "GRUB4DOS" /* 8-byte Vender ID */ . = int13_handler + 0x113ROM_int13_dup: /* Win9x Safe-MBR-Hook structure requires this! */ .long 0 . = int13_handler + 0x117VARIABLE(safe_mbr_hook) .long 0x00000001 /* safe MBR hook flag */ /* ----------------- SafeMBRHook structure end ----------------- */ /*******************************************************************/ /* But Win9x may expect additional data after SafeMBRHook structure. * This is undocumented, and mysterious. If this area is not what * Win9x expected, Win9x could hang. */ . = int13_handler + 0x11BVARIABLE(int13_scheme) /* bit 0 controls how we access sectors in protected mode. * bit0=0: use pushf and far call for ROM int13 service. * bit0=1: use the `int $0x13' instruction. */ .long 0x00000001 /* space reserved. */ . = int13_handler + 0x140#if 11: /* backup far return address */ //popl %cs:(int13_handler_end - 6 - int13_handler) popl %cs:(int13_old_cs_ip - int13_handler) /* build new stack: flags */ popw %cs:(int13_handler_end - 2 - int13_handler) /* backup old stack */ movw %sp, %cs:(int13_old_sp - int13_handler) movw %ss, %cs:(int13_old_ss - int13_handler) /* build new stack pointer */ movw $(int13_handler_end - 2 - int13_handler), %cs:(int13_new_sp - int13_handler) movw %cs, %cs:(int13_new_ss - int13_handler) /* switch to new stack */ lssw %cs:(int13_new_sp - int13_handler), %sp //pushfw /* flags already on stack */ pushw %cs call 1f /* restore old stack */ lssw %cs:(int13_old_sp - int13_handler), %sp /* transfer control to caller */ ljmp *%cs:(int13_old_cs_ip - int13_handler) //iret /* never reach here */ .align 4int13_old_cs_ip: .long 0int13_old_sp: .word 0int13_old_ss: .word 0int13_new_sp: .word 0int13_new_ss: .word 0 #endif1: cmpb $0x1a, %ah /* PS/2 low level format ESDI drive!!!! */ je error_01_disable2 /* disabled in any case */ /* (BP+10): old Flags */ /* (BP+8): return CS */ /* (BP+6): return IP */ cld pushl %eax /* (BP+2): old EAX */ pushw %bp /* (BP+0): old BP */ movw %sp, %bp /* BP->old 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -