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

📄 relocate_kernel_32.s

📁 linux 内核源代码
💻 S
字号:
/* * relocate_kernel.S - put the kernel image in place to boot * Copyright (C) 2002-2004 Eric Biederman  <ebiederm@xmission.com> * * This source code is licensed under the GNU General Public License, * Version 2.  See the file COPYING for more details. */#include <linux/linkage.h>#include <asm/page.h>#include <asm/kexec.h>/* * Must be relocatable PIC code callable as a C function */#define PTR(x) (x << 2)#define PAGE_ALIGNED (1 << PAGE_SHIFT)#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */#define PAE_PGD_ATTR 0x01 /* _PAGE_PRESENT */	.text	.align PAGE_ALIGNED	.globl relocate_kernelrelocate_kernel:	movl	8(%esp), %ebp /* list of pages */#ifdef CONFIG_X86_PAE	/* map the control page at its virtual address */	movl	PTR(VA_PGD)(%ebp), %edi	movl	PTR(VA_CONTROL_PAGE)(%ebp), %eax	andl	$0xc0000000, %eax	shrl	$27, %eax	addl	%edi, %eax	movl	PTR(PA_PMD_0)(%ebp), %edx	orl	$PAE_PGD_ATTR, %edx	movl	%edx, (%eax)	movl	PTR(VA_PMD_0)(%ebp), %edi	movl	PTR(VA_CONTROL_PAGE)(%ebp), %eax	andl	$0x3fe00000, %eax	shrl	$18, %eax	addl	%edi, %eax	movl	PTR(PA_PTE_0)(%ebp), %edx	orl	$PAGE_ATTR, %edx	movl	%edx, (%eax)	movl	PTR(VA_PTE_0)(%ebp), %edi	movl	PTR(VA_CONTROL_PAGE)(%ebp), %eax	andl	$0x001ff000, %eax	shrl	$9, %eax	addl	%edi, %eax	movl	PTR(PA_CONTROL_PAGE)(%ebp), %edx	orl	$PAGE_ATTR, %edx	movl	%edx, (%eax)	/* identity map the control page at its physical address */	movl	PTR(VA_PGD)(%ebp), %edi	movl	PTR(PA_CONTROL_PAGE)(%ebp), %eax	andl	$0xc0000000, %eax	shrl	$27, %eax	addl	%edi, %eax	movl	PTR(PA_PMD_1)(%ebp), %edx	orl	$PAE_PGD_ATTR, %edx	movl	%edx, (%eax)	movl	PTR(VA_PMD_1)(%ebp), %edi	movl	PTR(PA_CONTROL_PAGE)(%ebp), %eax	andl	$0x3fe00000, %eax	shrl	$18, %eax	addl	%edi, %eax	movl	PTR(PA_PTE_1)(%ebp), %edx	orl	$PAGE_ATTR, %edx	movl	%edx, (%eax)	movl	PTR(VA_PTE_1)(%ebp), %edi	movl	PTR(PA_CONTROL_PAGE)(%ebp), %eax	andl	$0x001ff000, %eax	shrl	$9, %eax	addl	%edi, %eax	movl	PTR(PA_CONTROL_PAGE)(%ebp), %edx	orl	$PAGE_ATTR, %edx	movl	%edx, (%eax)#else	/* map the control page at its virtual address */	movl	PTR(VA_PGD)(%ebp), %edi	movl	PTR(VA_CONTROL_PAGE)(%ebp), %eax	andl	$0xffc00000, %eax	shrl	$20, %eax	addl	%edi, %eax	movl	PTR(PA_PTE_0)(%ebp), %edx	orl	$PAGE_ATTR, %edx	movl	%edx, (%eax)	movl	PTR(VA_PTE_0)(%ebp), %edi	movl	PTR(VA_CONTROL_PAGE)(%ebp), %eax	andl	$0x003ff000, %eax	shrl	$10, %eax	addl	%edi, %eax	movl	PTR(PA_CONTROL_PAGE)(%ebp), %edx	orl	$PAGE_ATTR, %edx	movl	%edx, (%eax)	/* identity map the control page at its physical address */	movl	PTR(VA_PGD)(%ebp), %edi	movl	PTR(PA_CONTROL_PAGE)(%ebp), %eax	andl	$0xffc00000, %eax	shrl	$20, %eax	addl	%edi, %eax	movl	PTR(PA_PTE_1)(%ebp), %edx	orl	$PAGE_ATTR, %edx	movl	%edx, (%eax)	movl	PTR(VA_PTE_1)(%ebp), %edi	movl	PTR(PA_CONTROL_PAGE)(%ebp), %eax	andl	$0x003ff000, %eax	shrl	$10, %eax	addl	%edi, %eax	movl	PTR(PA_CONTROL_PAGE)(%ebp), %edx	orl	$PAGE_ATTR, %edx	movl	%edx, (%eax)#endifrelocate_new_kernel:	/* read the arguments and say goodbye to the stack */	movl  4(%esp), %ebx /* page_list */	movl  8(%esp), %ebp /* list of pages */	movl  12(%esp), %edx /* start address */	movl  16(%esp), %ecx /* cpu_has_pae */	/* zero out flags, and disable interrupts */	pushl $0	popfl	/* get physical address of control page now */	/* this is impossible after page table switch */	movl	PTR(PA_CONTROL_PAGE)(%ebp), %edi	/* switch to new set of page tables */	movl	PTR(PA_PGD)(%ebp), %eax	movl	%eax, %cr3	/* setup a new stack at the end of the physical control page */	lea	4096(%edi), %esp	/* jump to identity mapped page */	movl    %edi, %eax	addl    $(identity_mapped - relocate_kernel), %eax	pushl   %eax	retidentity_mapped:	/* store the start address on the stack */	pushl   %edx	/* Set cr0 to a known state:	 * 31 0 == Paging disabled	 * 18 0 == Alignment check disabled	 * 16 0 == Write protect disabled	 * 3  0 == No task switch	 * 2  0 == Don't do FP software emulation.	 * 0  1 == Proctected mode enabled	 */	movl	%cr0, %eax	andl	$~((1<<31)|(1<<18)|(1<<16)|(1<<3)|(1<<2)), %eax	orl	$(1<<0), %eax	movl	%eax, %cr0	/* clear cr4 if applicable */	testl	%ecx, %ecx	jz	1f	/* Set cr4 to a known state:	 * Setting everything to zero seems safe.	 */	movl	%cr4, %eax	andl	$0, %eax	movl	%eax, %cr4	jmp 1f1:	/* Flush the TLB (needed?) */	xorl	%eax, %eax	movl	%eax, %cr3	/* Do the copies */	movl	%ebx, %ecx	jmp	1f0:	/* top, read another word from the indirection page */	movl	(%ebx), %ecx	addl	$4, %ebx1:	testl	$0x1,   %ecx  /* is it a destination page */	jz	2f	movl	%ecx,	%edi	andl	$0xfffff000, %edi	jmp     0b2:	testl	$0x2,	%ecx  /* is it an indirection page */	jz	2f	movl	%ecx,	%ebx	andl	$0xfffff000, %ebx	jmp     0b2:	testl   $0x4,   %ecx /* is it the done indicator */	jz      2f	jmp     3f2:	testl   $0x8,   %ecx /* is it the source indicator */	jz      0b	     /* Ignore it otherwise */	movl    %ecx,   %esi /* For every source page do a copy */	andl    $0xfffff000, %esi	movl    $1024, %ecx	rep ; movsl	jmp     0b3:	/* To be certain of avoiding problems with self-modifying code	 * I need to execute a serializing instruction here.	 * So I flush the TLB, it's handy, and not processor dependent.	 */	xorl	%eax, %eax	movl	%eax, %cr3	/* set all of the registers to known values */	/* leave %esp alone */	xorl	%eax, %eax	xorl	%ebx, %ebx	xorl    %ecx, %ecx	xorl    %edx, %edx	xorl    %esi, %esi	xorl    %edi, %edi	xorl    %ebp, %ebp	ret

⌨️ 快捷键说明

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