startup.S 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009,2011 Free Software Foundation, Inc.
  4. *
  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.
  9. *
  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.
  14. *
  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/>.
  17. */
  18. /*
  19. * Note: These functions defined in this file may be called from C.
  20. * Be careful of that you must not modify some registers. Quote
  21. * from gcc-2.95.2/gcc/config/i386/i386.h:
  22. 1 for registers not available across function calls.
  23. These must include the FIXED_REGISTERS and also any
  24. registers that can be used without being saved.
  25. The latter must include the registers where values are returned
  26. and the register where structure-value addresses are passed.
  27. Aside from that, you can include as many other registers as you like.
  28. ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
  29. { 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
  30. */
  31. /*
  32. * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
  33. * So the first three arguments are passed in %eax, %edx, and %ecx,
  34. * respectively, and if a function has a fixed number of arguments
  35. * and the number is greater than three, the function must return
  36. * with "ret $N" where N is ((the number of arguments) - 3) * 4.
  37. */
  38. #include <config.h>
  39. #include <grub/symbol.h>
  40. #include <multiboot.h>
  41. #ifdef __APPLE__
  42. #include <grub/i386/pc/memory.h>
  43. #endif
  44. .file "startup.S"
  45. .text
  46. .globl start, _start, __start
  47. start:
  48. _start:
  49. __start:
  50. #ifdef __APPLE__
  51. LOCAL(start):
  52. #endif
  53. .code32
  54. movl %ecx, (LOCAL(real_to_prot_addr) - _start) (%esi)
  55. movl %edi, (LOCAL(prot_to_real_addr) - _start) (%esi)
  56. movl %eax, (EXT_C(grub_realidt) - _start) (%esi)
  57. /* copy back the decompressed part (except the modules) */
  58. #ifdef __APPLE__
  59. movl $EXT_C(_edata), %ecx
  60. subl $LOCAL(start), %ecx
  61. #else
  62. movl $(_edata - _start), %ecx
  63. #endif
  64. movl $(_start), %edi
  65. rep
  66. movsb
  67. movl $LOCAL (cont), %esi
  68. jmp *%esi
  69. LOCAL(cont):
  70. #if 0
  71. /* copy modules before cleaning out the bss */
  72. movl EXT_C(grub_total_module_size), %ecx
  73. movl EXT_C(grub_kernel_image_size), %esi
  74. addl %ecx, %esi
  75. addl $_start, %esi
  76. decl %esi
  77. movl $END_SYMBOL, %edi
  78. addl %ecx, %edi
  79. decl %edi
  80. std
  81. rep
  82. movsb
  83. #endif
  84. #ifdef __APPLE__
  85. /* clean out the bss */
  86. movl $EXT_C(_edata), %edi
  87. /* compute the bss length */
  88. movl $GRUB_MEMORY_MACHINE_SCRATCH_ADDR, %ecx
  89. #else
  90. /* clean out the bss */
  91. movl $BSS_START_SYMBOL, %edi
  92. /* compute the bss length */
  93. movl $END_SYMBOL, %ecx
  94. #endif
  95. subl %edi, %ecx
  96. /* clean out */
  97. xorl %eax, %eax
  98. cld
  99. rep
  100. stosb
  101. movl %edx, EXT_C(grub_boot_device)
  102. /*
  103. * Call the start of main body of C code.
  104. */
  105. call EXT_C(grub_main)
  106. LOCAL(real_to_prot_addr):
  107. .long 0
  108. LOCAL(prot_to_real_addr):
  109. .long 0
  110. .macro PROT_TO_REAL
  111. movl LOCAL(prot_to_real_addr), %eax
  112. call *%eax
  113. .endm
  114. .macro REAL_TO_PROT
  115. movl LOCAL(real_to_prot_addr), %eax
  116. calll *%eax
  117. .endm
  118. /*
  119. * grub_exit()
  120. *
  121. * Exit the system.
  122. */
  123. FUNCTION(grub_exit)
  124. PROT_TO_REAL
  125. .code16
  126. /* Tell the BIOS a boot failure. If this does not work, reboot. */
  127. int $0x18
  128. /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */
  129. xorw %ax, %ax
  130. movw $0x0472, %di
  131. movw %ax, (%di)
  132. ljmp $0xf000, $0xfff0
  133. .code32
  134. /*
  135. * int grub_pxe_call (int func, void* data, grub_uint32_t pxe_rm_entry);
  136. */
  137. FUNCTION(grub_pxe_call)
  138. pushl %ebp
  139. movl %esp, %ebp
  140. pushl %esi
  141. pushl %edi
  142. pushl %ebx
  143. movl %ecx, %ebx
  144. movl %eax, %ecx
  145. movl %edx, %eax
  146. andl $0xF, %eax
  147. shrl $4, %edx
  148. shll $16, %edx
  149. addl %eax, %edx
  150. PROT_TO_REAL
  151. .code16
  152. pushl %ebx
  153. pushl %edx
  154. pushw %cx
  155. movw %sp, %bx
  156. lcall *%ss:6(%bx)
  157. cld
  158. addw $10, %sp
  159. movw %ax, %cx
  160. REAL_TO_PROT
  161. .code32
  162. movzwl %cx, %eax
  163. popl %ebx
  164. popl %edi
  165. popl %esi
  166. popl %ebp
  167. ret
  168. #include "../int.S"
  169. VARIABLE(grub_realidt)
  170. .long 0
  171. #ifdef __APPLE__
  172. /* Older versions of objconv assume that there is the same number
  173. of text and data sections. Hence this dummy. */
  174. .section __TEXT, __zz_dummy
  175. .byte 0
  176. .globl EXT_C(_edata)
  177. .globl EXT_C(grub_boot_device)
  178. .zerofill __DATA, __aa_before_bss, EXT_C(_edata), 1, 0
  179. .zerofill __DATA, __bss, EXT_C(grub_boot_device), 4, 2
  180. #else
  181. .bss
  182. VARIABLE(grub_boot_device)
  183. .long 0
  184. #endif