Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

setup.S 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /****************************************************************************
  2. * This file provides the setup() and setup16() functions. The
  3. * purpose of these functions is to set up the internal environment so
  4. * that C code can execute. This includes setting up the internal
  5. * stack and (where applicable) setting up a GDT for virtual
  6. * addressing.
  7. *
  8. * These functions are designed to be called by the prefix.
  9. *
  10. * The same basic assembly code is used to compile both setup()
  11. * and setup16().
  12. ****************************************************************************
  13. */
  14. .text
  15. .arch i386
  16. #ifdef CODE16
  17. /****************************************************************************
  18. * setup16 (real-mode far call)
  19. *
  20. * This function can be called by a 16-bit prefix in order to set up
  21. * the internal (either 16-bit or 32-bit) environment.
  22. *
  23. * Parameters: none
  24. *
  25. * %cs:0000, %ds:0000 and %es:0000 must point to the start of the
  26. * (decompressed) runtime image.
  27. *
  28. * If KEEP_IT_REAL is defined, then %ds:0000 may instead point to the
  29. * start of the (decompressed) data segment portion of the runtime
  30. * image. If %ds==%cs, then it will be assumed that the data segment
  31. * follows immediately after the code segment.
  32. ****************************************************************************
  33. */
  34. #ifdef KEEP_IT_REAL
  35. #define ENTER_FROM_EXTERNAL call ext_to_kir
  36. #define RETURN_TO_EXTERNAL call kir_to_ext
  37. #define ENTRY_POINT kir_call
  38. #else /* KEEP_IT_REAL */
  39. #define ENTER_FROM_EXTERNAL \
  40. pushw %cs ; \
  41. call real_to_prot ; \
  42. .code32
  43. #define RETURN_TO_EXTERNAL \
  44. call prot_to_real ; \
  45. .code16
  46. #define ENTRY_POINT _prot_call /* _prot_call = OFFSET ( prot_call ) in librm */
  47. #endif /* KEEP_IT_REAL */
  48. #define ENTRY_POINT_REGISTER di
  49. .section ".text16"
  50. .code16
  51. .globl setup16
  52. setup16:
  53. #else /* CODE16 */
  54. /****************************************************************************
  55. * setup (32-bit protected-mode near call)
  56. *
  57. * This function can be called by a 32-bit prefix in order to set up
  58. * the internal 32-bit environment.
  59. *
  60. * Parameters: none
  61. ****************************************************************************
  62. */
  63. #define ENTER_FROM_EXTERNAL call ext_to_int
  64. #define RETURN_TO_EXTERNAL call int_to_ext
  65. #define ENTRY_POINT int_call
  66. #define ENTRY_POINT_REGISTER edi
  67. .section ".text"
  68. .code32
  69. .globl setup
  70. setup:
  71. #endif /* CODE16 */
  72. /* Preserve flags (including interrupt status) and registers */
  73. pushfl
  74. pushl %ebp
  75. /* Switch to (uninitialised) internal environment. This will
  76. * preserve the external environment for when we call
  77. * RETURN_TO_EXTERNAL.
  78. */
  79. ENTER_FROM_EXTERNAL
  80. /* NOTE: We may have only four bytes of stack at this point */
  81. #if defined(CODE16) && defined(KEEP_IT_REAL)
  82. /* If %ds == %cs, then the data segment is located immediately
  83. * after the code segment.
  84. */
  85. pushw %ax
  86. movw %cs, %ax
  87. movw %ds, %bp
  88. cmpw %ax, %bp
  89. jne 1f
  90. addw $_text_load_size_pgh, %ax
  91. movw %ax, %ds
  92. 1: popw %ax
  93. /* Switch to internal stack */
  94. pushw %ds
  95. popw %ss
  96. movl $_estack, %esp
  97. #else /* CODE16 && KEEP_IT_REAL */
  98. /* Work out where we're running and switch to internal pmode
  99. * stack
  100. */
  101. call 1f
  102. 1: popl %ebp
  103. leal (_estack-1b)(%ebp), %esp
  104. /* Set up GDT for virtual addressing */
  105. call run_here
  106. #endif /* CODE16 && KEEP_IT_REAL */
  107. /* Switch back to external environment. This will preserve
  108. * the internal environment ready for the next call.
  109. */
  110. RETURN_TO_EXTERNAL
  111. /* Set %es:[e]di to point to entry-point function.
  112. */
  113. push %cs
  114. pop %es
  115. mov $ENTRY_POINT, %ENTRY_POINT_REGISTER
  116. /* Far call to arch_initialise via the entry-point function.
  117. * arch_initialise() (or the entry-point function itself) may
  118. * update %es:[e]di to point to a new entry-point function for
  119. * subsequent calls. librm will use this facility, since
  120. * arch_initialise() causes librm to be relocated.
  121. */
  122. pushl $arch_initialise
  123. push %cs /* lcall %es:[x]di == %cs:[x]di */
  124. call *%ENTRY_POINT_REGISTER
  125. popl %ebp /* discard */
  126. /* Restore flags (including interrupt status) and return */
  127. popl %ebp
  128. popfl
  129. lret
  130. /****************************************************************************
  131. * Internal stack
  132. ****************************************************************************
  133. */
  134. .section ".stack"
  135. .align 8
  136. _stack:
  137. .space 4096
  138. _estack: