2 * relocate_kernel.S - put the kernel image in place to boot
3 * Copyright (C) 2002-2004 Eric Biederman <ebiederm@xmission.com>
5 * This source code is licensed under the GNU General Public License,
6 * Version 2. See the file COPYING for more details.
9 #include <linux/linkage.h>
12 * Must be relocatable PIC code callable as a C function, that once
13 * it starts can not use the previous processes stack.
15 .globl relocate_new_kernel
17 /* read the arguments and say goodbye to the stack */
18 movl 4(%esp), %ebx /* page_list */
19 movl 8(%esp), %ebp /* reboot_code_buffer */
20 movl 12(%esp), %edx /* start address */
21 movl 16(%esp), %ecx /* cpu_has_pae */
23 /* zero out flags, and disable interrupts */
27 /* set a new stack at the bottom of our page... */
30 /* store the parameters back on the stack */
31 pushl %edx /* store the start address */
33 /* Set cr0 to a known state:
34 * 31 0 == Paging disabled
35 * 18 0 == Alignment check disabled
36 * 16 0 == Write protect disabled
37 * 3 0 == No task switch
38 * 2 0 == Don't do FP software emulation.
39 * 0 1 == Proctected mode enabled
42 andl $~((1<<31)|(1<<18)|(1<<16)|(1<<3)|(1<<2)), %eax
46 /* clear cr4 if applicable */
49 /* Set cr4 to a known state:
50 * Setting everything to zero seems safe.
59 /* Flush the TLB (needed?) */
67 0: /* top, read another word from the indirection page */
71 testl $0x1, %ecx /* is it a destination page */
74 andl $0xfffff000, %edi
77 testl $0x2, %ecx /* is it an indirection page */
80 andl $0xfffff000, %ebx
83 testl $0x4, %ecx /* is it the done indicator */
87 testl $0x8, %ecx /* is it the source indicator */
88 jz 0b /* Ignore it otherwise */
89 movl %ecx, %esi /* For every source page do a copy */
90 andl $0xfffff000, %esi
98 /* To be certain of avoiding problems with self-modifying code
99 * I need to execute a serializing instruction here.
100 * So I flush the TLB, it's handy, and not processor dependent.
105 /* set all of the registers to known values */
106 /* leave %esp alone */
116 relocate_new_kernel_end:
118 .globl relocate_new_kernel_size
119 relocate_new_kernel_size:
120 .long relocate_new_kernel_end - relocate_new_kernel