⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 start32.s

📁 linux下从网卡远程启动
💻 S
📖 第 1 页 / 共 2 页
字号:
	andq	$0xffffffff, %rdx		/* Get the argument pointer */	movl	24(%rbx), %ebx	andq	$0xffffffff, %rbx	/* Jump to the 64bit code */	call	*%rdx	/* Preserve the result */	movl	%eax, %edx	/* Fixup %eflags */	cli	cld	/* Switch to 32bit compatibility mode */	ljmp	*end_lm_addr(%rip)	.code32end_lm:	/* Disable paging */	movl	%cr0, %eax	andl	$~CR0_PG, %eax	movl	%eax, %cr0	/* Disable long mode */	movl	$MSR_K6_EFER, %ecx	rdmsr	andl	$~EFER_LME, %eax	wrmsr	/* Disable PAE */	movl	%cr4, %eax	andl	$~X86_CR4_PAE, %eax	movl	%eax, %cr4		/* Compute virt_offset */	popl	%ebp	/* Compute the original stack pointer + 16 */	popl	%ebx	movl	%ebx, %esp	/* Enable the virtual addresses */	leal	_phys_to_virt(%ebp), %eax	call	*%eax	/* Restore the callee save registers */	popl	%ebx	popl	%esi	popl	%edi	popl	%ebp	/* Get the C return value */	movl	%edx, %eax	/* Return */	ret	.arch i386#endif /* CONFIG_X86_64 *//**************************************************************************SETJMP - Save stack context for non-local goto**************************************************************************/	.globl	setjmpsetjmp:	movl	4(%esp),%ecx		/* jmpbuf */	movl	0(%esp),%edx		/* return address */	movl	%edx,0(%ecx)	movl	%ebx,4(%ecx)	movl	%esp,8(%ecx)	movl	%ebp,12(%ecx)	movl	%esi,16(%ecx)	movl	%edi,20(%ecx)	movl	$0,%eax	ret/**************************************************************************LONGJMP - Non-local jump to a saved stack context**************************************************************************/	.globl	longjmplongjmp:	movl	4(%esp),%edx		/* jumpbuf */	movl	8(%esp),%eax		/* result */	movl	0(%edx),%ecx	movl	4(%edx),%ebx	movl	8(%edx),%esp	movl	12(%edx),%ebp	movl	16(%edx),%esi	movl	20(%edx),%edi	cmpl	$0,%eax	jne	1f	movl	$1,%eax1:	movl	%ecx,0(%esp)	ret/**************************************************************************_VIRT_TO_PHYS - Transition from virtual to physical addresses**************************************************************************/	.globl _virt_to_phys_virt_to_phys:	movl	virt_offset, %ebp	/* Load virt_offset */	addl	%ebp, 0(%esp)		/* Adjust the return address */	/* reload the code segment */	pushl	$FLAT_CODE_SEG	leal	1f(%ebp), %eax	pushl	%eax	lret1:	/* reload other segment registers */	movl	$FLAT_DATA_SEG, %eax	movl	%eax, %ds	movl	%eax, %es		movl	%eax, %ss		movl	%eax, %fs		movl	%eax, %gs	/* Adjust the stack pointer, after we have reloaded the stack segment */	addl	%ebp, %esp			ret/**************************************************************************_PHYS_TO_VIRT - Transition from using physical to virtual addresses**************************************************************************/	.globl _phys_to_virt_phys_to_virt:	/* virt_offset is in %ebp */	subl	%ebp, 0(%esp)	/* Adjust the return address */	subl	%ebp, %esp	/* Adjust the stack pointer */	ljmp	$KERN_CODE_SEG, $1f1:	/* reload other segment regsters */	movl	$KERN_DATA_SEG, %eax	movl	%eax, %ds	movl	%eax, %es		movl	%eax, %ss		movl	%eax, %fs		movl	%eax, %gs		ret	/**************************************************************************SET_SEG_BASE - Set the base address of a segment register**************************************************************************/	.globl set_seg_baseset_seg_base:	/* Low half of the gdt base */	movl	4(%esp), %eax	shll	$16, %eax	/* High half of the gdt base */		movl	4(%esp), %ecx	shrl	$16, %ecx	andl	$0xff, %ecx	movl	4(%esp), %edx	andl	$0xff000000, %edx	orl	%edx, %ecx	movl	8(%esp), %edx	/* Fixup the code segment */	andl	$0x0000ffff,  0(%edx)	orl	%eax       ,  0(%edx)	andl	$0x00ffff00,  4(%edx)	orl	%ecx       ,  4(%edx)	/* Fixup the data segment */	andl	$0x0000ffff,  8(%edx)	orl	%eax       ,  8(%edx)	andl	$0x00ffff00, 12(%edx)	orl	%ecx       , 12(%edx)	ret#ifdef CODE16/**************************************************************************_REAL_CALL - Run some code in real mode.**************************************************************************/	/* MAX_REAL_MODE_STACK is carefully tuned to work	 * with the stack bottom at 0x7c00 while not chancing	 * overwriting data below 0x500.	 */#define MAX_REAL_MODE_STACK 29696#define RADDR(sym)	(((sym) - _end16) + MAX_REAL_MODE_STACK)	.balign 4	.globl real_mode_stackreal_mode_stack:	.long 0x7c00  /* Put the stack just below the dos load address */real_stack_top:	.long 0_save_esp:	.long 0	.globl _real_call_real_call:	/* Save the original %esp value */	movl	%esp, _save_esp		/* Save the temporary registers I use */	pushl	$0	pushl	%ebx	pushl	%ecx	pushl	%edx	pushl	%esi	pushl	%edi	pushl	%ebp		/* Load up the registers */	movl	32(%esp), %ecx		/* The 16bit code len */	movl	36(%esp), %esi		/* The 16bit code start */	movl	virt_offset, %ebp	/* The virtual offset */		/* stack top = phys_to_virt(real_mode_stack - MAX_REAL_MODE_STACK) */	movl	real_mode_stack, %ebx	/* The stack top */	subl	$MAX_REAL_MODE_STACK, %ebx	movl	%ebx, real_stack_top	subl	%ebp, %ebx	/* Save the real mode stack top */	movl	%ebx, 24(%esp)	/* Compute where the copied code goes */	leal	RADDR(__real_call)(%ebx), %edi	subl	%ecx, %edi	andl	$0xfffffffc, %edi	/* 4 byte aligned */	/* Remember where the code is executed */	movl	%edi, %eax	subl	%ebx, %eax	movw	%ax, real_ip	/* Copy the user code onto the real mode stack */	rep	movsb		/* Copy the trampoline onto the stack */	movl	$__real_call, %esi	movl	$_end16 - __real_call, %ecx	leal	RADDR(__real_call)(%ebx), %edi	rep	movsb	/* Fixup real_gdtarg */	leal	_gdt(%ebp), %eax	movl	%eax, RADDR(real_gdtarg +2)(%ebx)		/* Fixup the gdt */	pushl	$_rmcs	leal	0(%ebx, %ebp), %eax	pushl	%eax	call	set_seg_base	addl	$8, %esp	/* Restore the saved registers */	popl	%ebp	popl	%edi	popl	%esi	popl	%edx	popl	%ecx	popl	%ebx	/* And switch stacks */	popl	%esp	movzwl	RADDR(real_ip)(%esp), %eax	addl	%eax, %esp	/* Setup for jump to real mode */	movl	real_stack_top, %eax	shrl	$4, %eax	pushw	%ax	pushw	$RADDR(real16)	/* Switch stack from %esp 32bit virtual to %sp 16bit physical */	addl	virt_offset, %esp	subl	real_stack_top, %esp	/* Jump to 16bit code */	ljmp	$REAL_CODE_SEG, $RADDR(code16) 	/* jump to a 16 bit segment */_real_call_ret:	/* reload  segment registers */	movl	$KERN_DATA_SEG,%eax	movl	%eax,%ds	movl	%eax,%es	movl	%eax,%ss	movl	%eax,%fs	movl	%eax,%gs	/* Restore the stack */	movl	_save_esp, %esp	/* Restore the direction flag */	cld	/* Get the real mode stack pointer */	movl	real_stack_top, %eax	subl	virt_offset, %eax	pushl	%eax	movzwl	RADDR(real_sp)(%eax), %eax	addl	0(%esp), %eax	addl	$4, %esp		/* Return to my caller */	ret	$8		.balign 16__real_call:real_sp:	.word 0real_ip:	.word 0real_gdtarg:	.word	_gdt_end - _gdt - 1	/* limit */	.long	_gdt			/* addr */	.code16code16:	/* Load 16bit segment descriptors to force 16bit segment limit */	movw	$REAL_DATA_SEG, %ax	movw	%ax,%ds	movw	%ax,%es	movw	%ax,%ss	movw	%ax,%fs	movw	%ax,%gs	/* clear the PE bit of CR0 */	movl	%cr0,%eax	andb	$0!CR0_PE,%al	movl	%eax,%cr0	/* make intersegment jmp to flush the processor pipeline	 * and reload %cs:%eip (to clear upper 16 bits of %eip).	 */	lretreal16:		/* we are in real mode now	 * set up the real mode segment registers : %ds, $ss, %es	 */	movw	%cs, %ax	movw	%ax, %ds	movw	%ax, %es	movw	%ax, %ss	movw	%ax, %fs	movw	%ax, %gs	/* Enable interrupts */	sti	/* Call the user supplied code */	call	*RADDR(real_ip)	/* Disable interrupts */	cli	/* Reload %ds */		movw	%cs, %ax	movw	%ax, %ds	/* Save the stack pointer */	movw	%sp, RADDR(real_sp)		/* Switch back to protected mode */	DATA32 lgdt RADDR(real_gdtarg)	movl	%cr0, %eax	orb	$CR0_PE, %al	movl	%eax, %cr0	/* turn on protected mode */	/* flush prefetch queue, and reload %cs:%eip */	DATA32 ljmp	$KERN_CODE_SEG, $_real_call_ret	.code32__end16:	.balign 16_end16:	.code32#endif /* CODE16 *//**************************************************************************GLOBAL DESCRIPTOR TABLE**************************************************************************/	.data	.align	4_gdt:gdtarg:	.word	_gdt_end - _gdt - 1	/* limit */	.long	_gdt			/* addr */	.word	0_pmcs:	/* 32 bit protected mode code segment */	.word	0xffff,0	.byte	0,0x9f,0xcf,0_pmds:	/* 32 bit protected mode data segment */	.word	0xffff,0	.byte	0,0x93,0xcf,0_rmcs:	/* 16 bit real mode code segment */	.word	0xffff,(0&0xffff)	.byte	(0>>16),0x9b,0x00,(0>>24)_rmds:	/* 16 bit real mode data segment */	.word	0xffff,(0&0xffff)	.byte	(0>>16),0x93,0x00,(0>>24)_pmcs2:	/* 32 bit protected mode code segment, base 0 */	.word	0xffff,0	.byte	0,0x9f,0xcf,0_pmds2:	/* 32 bit protected mode data segment, base 0 */	.word	0xffff,0	.byte	0,0x93,0xcf,0#ifdef CONFIG_X86_64_lmcs:	/* 64bit long mode code segment, base 0 */	.word	0xffff, 0	.byte	0x00, 0x9f, 0xaf , 0x00_lmds:	/* 64bit long mode data segment, base 0 */	.word	0xffff, 0	.byte	0x00, 0x93, 0xcf, 0x00#endif_gdt_end:	/* The initial register contents */	.balign 4	.globl initial_regsinitial_regs:	.fill 8, 4, 0	/* The virtual address offset  */		.globl virt_offsetvirt_offset:	.long  	0	.section ".stack"	.p2align 3	/* allocate a 4K stack in the stack segment */_stack:	.space 4096_estack:#ifdef CONFIG_X86_64	.section ".bss"	.p2align 12	/* Include a dummy space in case we are loaded badly aligned */	.space 4096	/* Reserve enough space for a page table convering 4GB with 2MB pages */pgt_level4:		.space 4096pgt_level3:		.space 4096pgt_level2:		.space 16384start_lm_addr:	.space	8end_lm_addr:	.space	8#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -