head.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/boot/head.S
  3.  *
  4.  *  Copyright (C) 1991, 1992, 1993  Linus Torvalds
  5.  */
  6. /*
  7.  *  head.S contains the 32-bit startup code.
  8.  *
  9.  * NOTE!!! Startup happens at absolute address 0x00001000, which is also where
  10.  * the page directory will exist. The startup code will be overwritten by
  11.  * the page directory. [According to comments etc elsewhere on a compressed
  12.  * kernel it will end up at 0x1000 + 1Mb I hope so as I assume this. - AC]
  13.  *
  14.  * Page 0 is deliberately kept safe, since System Management Mode code in 
  15.  * laptops may need to access the BIOS data stored there.  This is also
  16.  * useful for future device drivers that either access the BIOS via VM86 
  17.  * mode.
  18.  */
  19. /*
  20.  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  21.  */
  22. .text
  23. #include <linux/linkage.h>
  24. #include <asm/segment.h>
  25. .globl startup_32
  26. startup_32:
  27. cld
  28. cli
  29. movl $(__KERNEL_DS),%eax
  30. movl %eax,%ds
  31. movl %eax,%es
  32. movl %eax,%fs
  33. movl %eax,%gs
  34. lss SYMBOL_NAME(stack_start),%esp
  35. xorl %eax,%eax
  36. 1: incl %eax # check that A20 really IS enabled
  37. movl %eax,0x000000 # loop forever if it isn't
  38. cmpl %eax,0x100000
  39. je 1b
  40. /*
  41.  * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
  42.  * confuse the debugger if this code is traced.
  43.  * XXX - best to initialize before switching to protected mode.
  44.  */
  45. pushl $0
  46. popfl
  47. /*
  48.  * Clear BSS
  49.  */
  50. xorl %eax,%eax
  51. movl $ SYMBOL_NAME(_edata),%edi
  52. movl $ SYMBOL_NAME(_end),%ecx
  53. subl %edi,%ecx
  54. cld
  55. rep
  56. stosb
  57. /*
  58.  * Do the decompression, and jump to the new kernel..
  59.  */
  60. subl $16,%esp # place for structure on the stack
  61. movl %esp,%eax
  62. pushl %esi # real mode pointer as second arg
  63. pushl %eax # address of structure as first arg
  64. call SYMBOL_NAME(decompress_kernel)
  65. orl  %eax,%eax 
  66. jnz  3f
  67. popl %esi # discard address
  68. popl %esi # real mode pointer
  69. xorl %ebx,%ebx
  70. ljmp $(__KERNEL_CS), $0x100000
  71. /*
  72.  * We come here, if we were loaded high.
  73.  * We need to move the move-in-place routine down to 0x1000
  74.  * and then start it with the buffer addresses in registers,
  75.  * which we got from the stack.
  76.  */
  77. 3:
  78. movl $move_routine_start,%esi
  79. movl $0x1000,%edi
  80. movl $move_routine_end,%ecx
  81. subl %esi,%ecx
  82. addl $3,%ecx
  83. shrl $2,%ecx
  84. cld
  85. rep
  86. movsl
  87. popl %esi # discard the address
  88. popl %ebx # real mode pointer
  89. popl %esi # low_buffer_start
  90. popl %ecx # lcount
  91. popl %edx # high_buffer_start
  92. popl %eax # hcount
  93. movl $0x100000,%edi
  94. cli # make sure we don't get interrupted
  95. ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine
  96. /*
  97.  * Routine (template) for moving the decompressed kernel in place,
  98.  * if we were high loaded. This _must_ PIC-code !
  99.  */
  100. move_routine_start:
  101. movl %ecx,%ebp
  102. shrl $2,%ecx
  103. rep
  104. movsl
  105. movl %ebp,%ecx
  106. andl $3,%ecx
  107. rep
  108. movsb
  109. movl %edx,%esi
  110. movl %eax,%ecx # NOTE: rep movsb won't move if %ecx == 0
  111. addl $3,%ecx
  112. shrl $2,%ecx
  113. rep
  114. movsl
  115. movl %ebx,%esi # Restore setup pointer
  116. xorl %ebx,%ebx
  117. ljmp $(__KERNEL_CS), $0x100000
  118. move_routine_end: