diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:29:51 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:29:51 +0000 |
commit | 6e7a315eb67cb6c113cf37e1d66c4f11a51a2b3e (patch) | |
tree | 32451fa3cdd9321fb2591fada9891b2cb70a9cd1 /grub-core/kern/i386/pc/startup.S | |
parent | Initial commit. (diff) | |
download | grub2-upstream.tar.xz grub2-upstream.zip |
Adding upstream version 2.06.upstream/2.06upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | grub-core/kern/i386/pc/startup.S | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S new file mode 100644 index 0000000..b8a9b33 --- /dev/null +++ b/grub-core/kern/i386/pc/startup.S @@ -0,0 +1,217 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009,2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. + */ + + +/* + * Note: These functions defined in this file may be called from C. + * Be careful of that you must not modify some registers. Quote + * from gcc-2.95.2/gcc/config/i386/i386.h: + + 1 for registers not available across function calls. + These must include the FIXED_REGISTERS and also any + registers that can be used without being saved. + The latter must include the registers where values are returned + and the register where structure-value addresses are passed. + Aside from that, you can include as many other registers as you like. + + ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg +{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } + */ + +/* + * Note: GRUB is compiled with the options -mrtd and -mregparm=3. + * So the first three arguments are passed in %eax, %edx, and %ecx, + * respectively, and if a function has a fixed number of arguments + * and the number is greater than three, the function must return + * with "ret $N" where N is ((the number of arguments) - 3) * 4. + */ + +#include <config.h> +#include <grub/symbol.h> +#include <multiboot.h> +#ifdef __APPLE__ +#include <grub/i386/pc/memory.h> +#endif + + .file "startup.S" + + .text + + .globl start, _start, __start +start: +_start: +__start: +#ifdef __APPLE__ +LOCAL(start): +#endif + .code32 + + movl %ecx, (LOCAL(real_to_prot_addr) - _start) (%esi) + movl %edi, (LOCAL(prot_to_real_addr) - _start) (%esi) + movl %eax, (EXT_C(grub_realidt) - _start) (%esi) + + /* copy back the decompressed part (except the modules) */ +#ifdef __APPLE__ + movl $EXT_C(_edata), %ecx + subl $LOCAL(start), %ecx +#else + movl $(_edata - _start), %ecx +#endif + movl $(_start), %edi + rep + movsb + + movl $LOCAL (cont), %esi + jmp *%esi +LOCAL(cont): + +#if 0 + /* copy modules before cleaning out the bss */ + movl EXT_C(grub_total_module_size), %ecx + movl EXT_C(grub_kernel_image_size), %esi + addl %ecx, %esi + addl $_start, %esi + decl %esi + movl $END_SYMBOL, %edi + addl %ecx, %edi + decl %edi + std + rep + movsb +#endif + +#ifdef __APPLE__ + /* clean out the bss */ + movl $EXT_C(_edata), %edi + + /* compute the bss length */ + movl $GRUB_MEMORY_MACHINE_SCRATCH_ADDR, %ecx +#else + /* clean out the bss */ + movl $BSS_START_SYMBOL, %edi + + /* compute the bss length */ + movl $END_SYMBOL, %ecx +#endif + subl %edi, %ecx + + /* clean out */ + xorl %eax, %eax + cld + rep + stosb + + movl %edx, EXT_C(grub_boot_device) + + /* + * Call the start of main body of C code. + */ + call EXT_C(grub_main) + +LOCAL(real_to_prot_addr): + .long 0 +LOCAL(prot_to_real_addr): + .long 0 + + .macro PROT_TO_REAL + movl LOCAL(prot_to_real_addr), %eax + call *%eax + .endm + + .macro REAL_TO_PROT + movl LOCAL(real_to_prot_addr), %eax + calll *%eax + .endm + +/* + * grub_exit() + * + * Exit the system. + */ +FUNCTION(grub_exit) + PROT_TO_REAL + .code16 + /* Tell the BIOS a boot failure. If this does not work, reboot. */ + int $0x18 + /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */ + xorw %ax, %ax + movw $0x0472, %di + movw %ax, (%di) + ljmp $0xf000, $0xfff0 + .code32 + +/* + * int grub_pxe_call (int func, void* data, grub_uint32_t pxe_rm_entry); + */ +FUNCTION(grub_pxe_call) + pushl %ebp + movl %esp, %ebp + pushl %esi + pushl %edi + pushl %ebx + + movl %ecx, %ebx + movl %eax, %ecx + movl %edx, %eax + andl $0xF, %eax + shrl $4, %edx + shll $16, %edx + addl %eax, %edx + + PROT_TO_REAL + .code16 + + pushl %ebx + pushl %edx + pushw %cx + movw %sp, %bx + lcall *%ss:6(%bx) + cld + addw $10, %sp + movw %ax, %cx + + REAL_TO_PROT + .code32 + + movzwl %cx, %eax + + popl %ebx + popl %edi + popl %esi + popl %ebp + ret + +#include "../int.S" + +VARIABLE(grub_realidt) + .long 0 + +#ifdef __APPLE__ + /* Older versions of objconv assume that there is the same number + of text and data sections. Hence this dummy. */ + .section __TEXT, __zz_dummy + .byte 0 + .globl EXT_C(_edata) + .globl EXT_C(grub_boot_device) + .zerofill __DATA, __aa_before_bss, EXT_C(_edata), 1, 0 + .zerofill __DATA, __bss, EXT_C(grub_boot_device), 4, 2 +#else + .bss +VARIABLE(grub_boot_device) + .long 0 +#endif |