2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
21 * Note: These functions defined in this file may be called from C.
22 * Be careful of that you must not modify some registers. Quote
23 * from gcc-2.95.2/gcc/config/i386/i386.h:
25 1 for registers not available across function calls.
26 These must include the FIXED_REGISTERS and also any
27 registers that can be used without being saved.
28 The latter must include the registers where values are returned
29 and the register where structure-value addresses are passed.
30 Aside from that, you can include as many other registers as you like.
32 ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
33 { 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
37 * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
38 * So the first three arguments are passed in %eax, %edx, and %ecx,
39 * respectively, and if a function has a fixed number of arguments
40 * and the number if greater than three, the function must return
41 * with "ret $N" where N is ((the number of arguments) - 3) * 4.
45 * This is the area for all of the special variables.
48 .p2align 2 /* force 4-byte alignment */
51 * void grub_linux_boot_zimage (void)
53 VARIABLE(grub_linux_prot_size)
55 VARIABLE(grub_linux_tmp_addr)
57 VARIABLE(grub_linux_real_addr)
59 VARIABLE(grub_linux_is_bzimage)
62 FUNCTION(grub_linux_boot)
63 /* Must be done before zImage copy. */
64 call EXT_C(grub_dl_unload_all)
66 movl EXT_C(grub_linux_is_bzimage), %ebx
71 movl EXT_C(grub_linux_prot_size), %ecx
74 movl $GRUB_LINUX_BZIMAGE_ADDR, %esi
75 movl $GRUB_LINUX_ZIMAGE_ADDR, %edi
81 movl EXT_C(grub_linux_real_addr), %ebx
83 /* copy the real mode code */
84 movl EXT_C(grub_linux_tmp_addr), %esi
86 movl $GRUB_LINUX_SETUP_MOVE_SIZE, %ecx
91 /* change %ebx to the segment address */
95 movw %ax, linux_setup_seg
97 /* XXX new stack pointer in safe area for calling functions */
99 call EXT_C(grub_stop_floppy)
101 /* final setup for linux boot */
107 movw $GRUB_LINUX_SETUP_STACK, %sp
123 * This starts the multiboot kernel.
126 VARIABLE(grub_multiboot_payload_size)
128 VARIABLE(grub_multiboot_payload_orig)
130 VARIABLE(grub_multiboot_payload_dest)
132 VARIABLE(grub_multiboot_payload_entry_offset)
136 * The relocators below understand the following parameters:
137 * ecx: Size of the block to be copied.
138 * esi: Where to copy from (always lowest address, even if we're relocating
140 * edi: Where to copy to (likewise).
141 * edx: Offset of the entry point (relative to the beginning of the block).
143 VARIABLE(grub_multiboot_forward_relocator)
149 VARIABLE(grub_multiboot_forward_relocator_end)
151 VARIABLE(grub_multiboot_backward_relocator)
155 /* backward movsb is implicitly off-by-one. compensate that. */
159 /* same problem again. */
163 VARIABLE(grub_multiboot_backward_relocator_end)
165 FUNCTION(grub_multiboot_real_boot)
166 /* Push the entry address on the stack. */
168 /* Move the address of the multiboot information structure to ebx. */
171 /* Unload all modules and stop the floppy driver. */
172 call EXT_C(grub_dl_unload_all)
173 call EXT_C(grub_stop_floppy)
175 /* Interrupts should be disabled. */
178 /* Where do we copy what from. */
179 movl EXT_C(grub_multiboot_payload_size), %ecx
180 movl EXT_C(grub_multiboot_payload_orig), %esi
181 movl EXT_C(grub_multiboot_payload_dest), %edi
182 movl EXT_C(grub_multiboot_payload_entry_offset), %edx
184 /* Move the magic value into eax. */
185 movl $MULTIBOOT_MAGIC2, %eax
187 /* Jump to the relocator. */
192 * This starts the multiboot 2 kernel.
195 FUNCTION(grub_multiboot2_real_boot)
196 /* Push the entry address on the stack. */
198 /* Move the address of the multiboot information structure to ebx. */
201 /* Unload all modules and stop the floppy driver. */
202 call EXT_C(grub_dl_unload_all)
203 call EXT_C(grub_stop_floppy)
205 /* Interrupts should be disabled. */
208 /* Move the magic value into eax and jump to the kernel. */
209 movl $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
214 * Use cdecl calling convention for *BSD kernels.
217 FUNCTION(grub_unix_real_boot)
219 call EXT_C(grub_dl_unload_all)
220 call EXT_C(grub_stop_floppy)
222 /* Interrupts should be disabled. */
225 /* Discard `grub_unix_real_boot' return address. */
228 /* Fetch `entry' address ... */
232 * ... and put our return address in its place. The kernel will
233 * ignore it, but it expects %esp to point to it.