📄 asm.s
字号:
#endif /* compute the bss length */ subl %edi, %ecx /* zero %al */ xorb %al, %al /* set the direction */ cld /* clean out */ rep stosb 1: /* * Call the start of main body of C code, which does some * of it's own initialization before transferring to "cmain". */ call EXT_C(init_bios_info) call EXT_C(cmain)/* * This call is special... it never returns... in fact it should simply * hang at this point! */ENTRY(stop) call EXT_C(prot_to_real) /* * This next part is sort of evil. It takes advantage of the * byte ordering on the x86 to work in either 16-bit or 32-bit * mode, so think about it before changing it. */ /* No external program ever calls HARD_STOP. HARD_STOP is only called * by the asm.S itself, and all calls are from real mode. So we * could(and should) use .code16 here clearly. */ .code16//ENTRY(hard_stop)hard_stop: sti hlt //jmp EXT_C(hard_stop) jmp hard_stop#ifndef STAGE1_5/* If preset_menu == __bss_start, the new menu at end of pre_stage2 will be used. */VARIABLE(preset_menu)#if defined(PRESET_MENU_STRING)#if defined(HAVE_USCORE_USCORE_BSS_START_SYMBOL) //.word (__bss_start - main) & 0x0F, (__bss_start - main) >> 4 .long __bss_start#elif defined(HAVE_USCORE_EDATA_SYMBOL) //.word (_edata - main) & 0x0F, (_edata - main) >> 4 .long _edata#elif defined(HAVE_EDATA_SYMBOL) //.word (edata - main) & 0x0F, (edata - main) >> 4 .long edata#else /* ! HAVE_EDATA_SYMBOL */#error no bss starting address#endif /* ! HAVE_EDATA_SYMBOL */#else /* ! PRESET_MENU_STRING */ .long 0#endif /* PRESET_MENU_STRING */VARIABLE(debug_boot) .long 0#endif /* ! STAGE1_5 */ .code16 /* real mode print string *//* prints string DS:SI (modifies AX BX SI) */print_message:1: sti /* for hardware interrupt or watchdog */ cld lodsb (%si), %al /* get token */ xorw %bx, %bx /* video page 0 */ movb $0x0e, %ah /* print it */ int $0x10 /* via TTY mode */ cmpb $0, %al /* end of string? */ jne 1b /* until done */ retreset_disk_string: .ascii "Reseting the boot drive... \0"reset_disk_success_string: .ascii "Success.\r\n\0"reset_disk_failure_string: .ascii "Failure!\r\n\0"bochs_copygrght_string: .ascii "(c) 2002 MandrakeSoft S.A. Written by Kevin Lawton & the Bochs team.\0"ENTRY(bios_id) .long 0 /* 1 for bochs, 0 for unknown. */ .code32#ifndef STAGE1_5/* unsigned long pxe_scan(void) * * scan pxe runtime */ENTRY(pxe_scan) pushl %ebx call EXT_C(prot_to_real) .code16 sti /* for hardware interrupt or watchdog */ movw $0x5650, %ax int $0x1A cmpw $0x564E, %ax jnz 1f cmpl $0x4E455850, %es:(%bx) // PXEN(V+) jnz 1f cmpw $0x201, %es:6(%bx) // API version jb 1f lesw %es:0x28(%bx), %bx // !PXE structure cmpl $0x45585021, %es:(%bx) // !PXE jnz 1f movw %es, %cx jmp 2f1: xorw %bx, %bx xorw %cx, %cx2: DATA32 call EXT_C(real_to_prot) .code32 xorl %eax, %eax movw %cx, %ax shll $4, %eax andl $0xFFFF, %ebx addl %ebx, %eax jz 3f movl 0x10(%eax), %ebx movl %ebx, EXT_C(pxe_entry) xorl %ecx, %ecx movl 0x2A(%eax), %ebx cmpl 0x32(%eax), %ebx ja 1f movl 0x32(%eax), %ebx movw 0x36(%eax), %cx jmp 2f1: movw 0x2E(%eax), %cx2: addl %ecx, %ebx addl $1023, %ebx shrl $10, %ebx movw %bx, EXT_C(pxe_freemem)3: popl %ebx ret/* int pxe_call(int func,void* data) * * PXE function call */ENTRY(pxe_call) pushl %ebp movl %esp, %ebp pushl %esi pushl %edi pushl %ebx movl 8(%ebp), %ecx movl 12(%ebp), %edx movl %edx, %eax andl $0xF, %eax shrl $4, %edx shll $16, %edx addl %eax, %edx movl EXT_C(pxe_entry), %ebx call EXT_C(prot_to_real) .code16 sti /* for hardware interrupt or watchdog */ pushl %ebx pushl %edx pushw %cx movw %sp, %bx lcall *%ss:6(%bx) cld addw $10, %sp movw %ax, %cx DATA32 call EXT_C(real_to_prot) .code32 movzwl %cx, %eax popl %ebx popl %edi popl %esi popl %ebp ret#if PXE_FAST_READ/* int pxe_fast_read(void* data,int num) * * Read multiple packets */ENTRY(pxe_fast_read) pushl %ebp movl %esp, %ebp pushl %esi pushl %edi pushl %ebx movl 8(%ebp), %edx movl 12(%ebp), %esi movl EXT_C(pxe_blksize), %edi movl %edx, %eax andl $0xF, %eax shrl $4, %edx shll $16, %edx addl %eax, %edx movl EXT_C(pxe_entry), %ebx call EXT_C(prot_to_real) .code16 sti /* for hardware interrupt or watchdog */ pushl %ebx pushl %edx pushw $0x22 // PXENV_TFTP_READ movw %sp, %bx movw %si, %cx lesw %ss:2(%bx), %si1: lcall *%ss:6(%bx) cld cmpw $0, %es:(%si) jnz 2f movw %es:4(%si), %dx addw %dx, %es:6(%si) cmpw %di, %dx jb 2f loop 1b2: addw $10, %sp movw %ax, %cx DATA32 call EXT_C(real_to_prot) .code32 movzwl %cx, %eax popl %ebx popl %edi popl %esi popl %ebp ret#endif/* * stop_floppy() * * Stops the floppy drive from spinning, so that other software is * jumped to with a known state. */ENTRY(stop_floppy) pushal call EXT_C(prot_to_real) .code16 sti #; added 2006-11-30 xorb %dl, %dl#if defined(STAGE1_5) || 1 int $0x13#else call safe_int13#endif DATA32 call EXT_C(real_to_prot) .code32 popal ret/* * grub_reboot() * * Reboot the system. At the moment, rely on BIOS. */ENTRY(grub_reboot) call EXT_C(prot_to_real) .code16 /* cold boot */ //sti /* needn't enable interrupt here. comment it out */ movw $0x0472, %di movw %ax, (%di) ljmp $0xFFFF, $0x0000 .code32 /* * grub_halt(int no_apm) * * Halt the system, using APM if possible. If NO_APM is true, don't use * APM even if it is available. */ENTRY(grub_halt) /* get the argument */ movl 4(%esp), %eax /* see if zero */ testl %eax, %eax jnz EXT_C(stop) call EXT_C(prot_to_real) .code16 //sti /* this is not needed here, so comment it out. */ sti #; added 2006-11-30 /* detect APM */ movw $0x5300, %ax xorw %bx, %bx int $0x15 //jc EXT_C(hard_stop) jc hard_stop /* don't check %bx for buggy BIOSes... */ /* disconnect APM first */ movw $0x5304, %ax xorw %bx, %bx int $0x15 /* connect APM */ movw $0x5301, %ax xorw %bx, %bx int $0x15 //jc EXT_C(hard_stop) jc hard_stop /* set APM protocol level - 1.1 or bust. (this covers APM 1.2 also) */ movw $0x530E, %ax xorw %bx, %bx movw $0x0101, %cx int $0x15 //jc EXT_C(hard_stop) jc hard_stop /* set the power state to off */ movw $0x5307, %ax movw $1, %bx movw $3, %cx int $0x15 /* shouldn't reach here */ //jmp EXT_C(hard_stop) jmp hard_stop/* * int check_64bit (void) * * Checks whether 64-bit mode is supported * * Stolen from a patch originaly intended for syslinux * (http://syslinux.zytor.com/archives/2007-January/007832.html) * * Copyright (C) 2007 Byron Stanoszek <gandalf@winds.org> * * Adapted to AT&T syntax by Robert Millan <rmh@aybabtu.com> */ENTRY(check_64bit) .code32 pushl %ebp pushl %ebx pushl %edx /* Check if this CPU supports the CPUID command */ pushfl pushfl popl %eax movl %eax, %ebx xorl $(1 << 21), %eax // CPUID bit pushl %eax popfl pushfl popl %eax popfl // Restore the original flags xorl %ebx, %eax jz is_32bit /* Now check for the 64-bit flag in the CPU features byte ($0000_0001, edx) This is bit 30 for Intel CPUs, and bit 29 for AMD CPUs */ movl $0x00000000, %eax // Find last Intel cpuid # cpuid cmpl $0x00000000, %eax je test_amd movl $0x00000001, %eax // Read Intel CPU flags cpuid btl $30, %edx // 64-bit if bit 30 is set jc is_64bittest_amd: movl $0x80000000, %eax // Find last AMD cpuid # cpuid cmpl $0x80000000, %eax jbe is_32bit movl $0x80000001, %eax // Read AMD CPU flags cpuid btl $29, %edx // 64-bit if bit 29 is set jnc is_32bitis_64bit: movl $1, %eax popl %edx popl %ebx popl %ebp retis_32bit: xorl %eax, %eax popl %edx popl %ebx popl %ebp ret/* Catch CPU exceptions 0 - 7 * 0 Divide * 1 Debug * 2 NMI * 3 Break point * 4 Overflow * 5 Bound * 6 Invalid Instruction * 7 no coprocessor */set_fault_recovery_handler: .code16 pushfw pushw %ds pushw %es pushaw /* backup int 00 - 07 */ xorw %ax, %ax movw %ax, %ds movw %ax, %es xorw %si, %si movw $ABS(int_00_07_vectors), %di movw $16, %cx cld repz movsw /* set to new vector */ xorw %ax, %ax movw %ax, %ds movw %ax, %es xorw %si, %si movw $ABS(int_00_07_vectors), %di pushl %eax xorw %di, %di movl $ABS(fault_recovery_handler), %eax /* 0000:fault_recovery_handler */ movw $8, %cx cld repz stosl popl %eax popaw popw %es popw %ds popfw retunset_fault_recovery_handler: .code16 pushfw pushw %ds pushw %es pushaw /* restore int 00 - 07 */ xorw %ax, %ax movw %ax, %ds movw %ax, %es xorw %di, %di movw $ABS(int_00_07_vectors), %si movw $16, %cx cld repz movsw popaw popw %es popw %ds popfw ret .align 4int_00_07_vectors: .space 32original_registers: .space 48safe_int13: .code16 /* setup our fault recovery handler */ call set_fault_recovery_handler /* backup old registers. Note: CS=0 */ movw %ds, %cs:ABS(original_registers) movw %es, %cs:ABS(original_registers) + 4 movw %ss, %cs:ABS(original_registers) + 8 movl %esp, %cs:ABS(original_registers) + 12 movl %eax, %cs:ABS(original_registers) + 16 movl %ebx, %cs:ABS(original_registers) + 20 movl %ecx, %cs:ABS(original_registers) + 24 movl %edx, %cs:ABS(original_registers) + 28 movl %esi, %cs:ABS(original_registers) + 32 movl %edi, %cs:ABS(original_registers) + 36 movl %ebp, %cs:ABS(original_registers) + 40 pushw %bp pushw %ax movw %sp, %bp movw 4(%bp), %ax movw %ax, %cs:ABS(original_registers) + 44 #; return IP popw %ax popw %bp int $0x13 call unset_fault_recovery_handler retfault_recovery_handler: .code16 /* restore old registers. Note: CS=0 */ movw %cs:ABS(original_registers), %ds movw %cs:ABS(original_registers) + 4, %es movw %cs:ABS(original_registers) + 8, %ss movl %cs:ABS(original_registers) + 12, %esp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -