歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux0.11內核--啟動引導代碼分析bootsect.s

Linux0.11內核--啟動引導代碼分析bootsect.s

日期:2017/3/1 10:24:04   编辑:Linux編程

Linux內核中的系統啟動引導代碼位於/boot目錄下

但是,由於。Linus當時是在MINIX系統上開發Linux的,最初MINIX系統上還沒有移植gas程序,因此Linus就使用了MINIX系統上的as86。

bootsect需要是16位的實模式程序。目前gas匯編器也支持16位的編譯。所以現在也可以直接用as編譯器直接編譯。

下面是用at&t格式改寫的bootsect.s代碼

  1. .code16
  2. # rewrite with AT&T syntax by falcon <[email protected]> at 081012
  3. #
  4. # SYS_SIZE is the number of clicks (16 bytes) to be loaded.
  5. # 0x3000 is 0x30000 bytes = 196kB, more than enough for current
  6. # versions of linux
  7. #
  8. .equ SYSSIZE, 0x3000
  9. #
  10. # bootsect.s (C) 1991 Linus Torvalds
  11. #
  12. # bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
  13. # iself out of the way to address 0x90000, and jumps there.
  14. #
  15. # It then loads 'setup' directly after itself (0x90200), and the system
  16. # at 0x10000, using BIOS interrupts.
  17. #
  18. # NOTE! currently system is at most 8*65536 bytes long. This should be no
  19. # problem, even in the future. I want to keep it simple. This 512 kB
  20. # kernel size should be enough, especially as this doesn't contain the
  21. # buffer cache as in minix
  22. #
  23. # The loader has been made as simple as possible, and continuos
  24. # read errors will result in a unbreakable loop. Reboot by hand. It
  25. # loads pretty fast by getting whole sectors at a time whenever possible.
  26. .global _start, begtext, begdata, begbss, endtext, enddata, endbss
  27. .text
  28. begtext:
  29. .data
  30. begdata:
  31. .bss
  32. begbss:
  33. .text
  34. .equ SETUPLEN, 4 # nr of setup-sectors
  35. .equ BOOTSEG, 0x07c0 # original address of boot-sector
  36. .equ INITSEG, 0x9000 # we move boot here - out of the way
  37. .equ SETUPSEG, 0x9020 # setup starts here
  38. .equ SYSSEG, 0x1000 # system loaded at 0x10000 (65536).
  39. .equ ENDSEG, SYSSEG + SYSSIZE # where to stop loading
  40. # ROOT_DEV: 0x000 - same type of floppy as boot.
  41. # 0x301 - first partition on first drive etc
  42. .equ ROOT_DEV, 0x301
  43. ljmp $BOOTSEG, $_start
  44. _start:
  45. mov $BOOTSEG, %ax
  46. mov %ax, %ds
  47. mov $INITSEG, %ax
  48. mov %ax, %es
  49. mov $256, %cx
  50. sub %si, %si
  51. sub %di, %di
  52. rep
  53. movsw
  54. ljmp $INITSEG, $go
  55. go: mov %cs, %ax
  56. mov %ax, %ds
  57. mov %ax, %es
  58. # put stack at 0x9ff00.
  59. mov %ax, %ss
  60. mov $0xFF00, %sp # arbitrary value >>512
  61. # load the setup-sectors directly after the bootblock.
  62. # Note that 'es' is already set up.
  63. load_setup:
  64. mov $0x0000, %dx # drive 0, head 0
  65. mov $0x0002, %cx # sector 2, track 0
  66. mov $0x0200, %bx # address = 512, in INITSEG
  67. .equ AX, 0x0200+SETUPLEN
  68. mov $AX, %ax # service 2, nr of sectors
  69. int $0x13 # read it
  70. jnc ok_load_setup # ok - continue
  71. mov $0x0000, %dx
  72. mov $0x0000, %ax # reset the diskette
  73. int $0x13
  74. jmp load_setup
  75. ok_load_setup:
  76. # Get disk drive parameters, specifically nr of sectors/track
  77. mov $0x00, %dl
  78. mov $0x0800, %ax # AH=8 is get drive parameters
  79. int $0x13
  80. mov $0x00, %ch
  81. #seg cs
  82. mov %cx, %cs:sectors+0 # %cs means sectors is in %cs
  83. mov $INITSEG, %ax
  84. mov %ax, %es
  85. # Print some inane message
  86. mov $0x03, %ah # read cursor pos
  87. xor %bh, %bh
  88. int $0x10
  89. mov $38, %cx
  90. mov $0x0007, %bx # page 0, attribute 7 (normal)
  91. #lea msg1, %bp
  92. mov $msg1, %bp
  93. mov $0x1301, %ax # write string, move cursor
  94. int $0x10
  95. # ok, we've written the message, now
  96. # we want to load the system (at 0x10000)
  97. mov $SYSSEG, %ax
  98. mov %ax, %es # segment of 0x010000
  99. call read_it
  100. call kill_motor
  101. # After that we check which root-device to use. If the device is
  102. # defined (#= 0), nothing is done and the given device is used.
  103. # Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending
  104. # on the number of sectors that the BIOS reports currently.
  105. #seg cs
  106. mov %cs:root_dev+0, %ax
  107. cmp $0, %ax
  108. jne root_defined
  109. #seg cs
  110. mov %cs:sectors+0, %bx
  111. mov $0x0208, %ax # /dev/ps0 - 1.2Mb
  112. cmp $15, %bx
  113. je root_defined
  114. mov $0x021c, %ax # /dev/PS0 - 1.44Mb
  115. cmp $18, %bx
  116. je root_defined
  117. undef_root:
  118. jmp undef_root
  119. root_defined:
  120. #seg cs
  121. mov %ax, %cs:root_dev+0
  122. # after that (everyting loaded), we jump to
  123. # the setup-routine loaded directly after
  124. # the bootblock:
  125. ljmp $SETUPSEG, $0 #jump to 0x9020:0000(setup.s 程序的開始處)
  126. # This routine loads the system at address 0x10000, making sure
  127. # no 64kB boundaries are crossed. We try to load it as fast as
  128. # possible, loading whole tracks whenever we can.
  129. #
  130. # in: es - starting address segment (normally 0x1000)
  131. #
  132. sread: .word 1+ SETUPLEN # sectors read of current track
  133. head: .word 0 # current head
  134. track: .word 0 # current track
  135. read_it:
  136. mov %es, %ax
  137. test $0x0fff, %ax
  138. die: jne die # es must be at 64kB boundary
  139. xor %bx, %bx # bx is starting address within segment
  140. rp_read:
  141. mov %es, %ax
  142. cmp $ENDSEG, %ax # have we loaded all yet?
  143. jb ok1_read
  144. ret
  145. ok1_read:
  146. #seg cs
  147. mov %cs:sectors+0, %ax
  148. sub sread, %ax
  149. mov %ax, %cx
  150. shl $9, %cx
  151. add %bx, %cx
  152. jnc ok2_read
  153. je ok2_read
  154. xor %ax, %ax
  155. sub %bx, %ax
  156. shr $9, %ax
  157. ok2_read:
  158. call read_track
  159. mov %ax, %cx
  160. add sread, %ax
  161. #seg cs
  162. cmp %cs:sectors+0, %ax
  163. jne ok3_read
  164. mov $1, %ax
  165. sub head, %ax
  166. jne ok4_read
  167. incw track
  168. ok4_read:
  169. mov %ax, head
  170. xor %ax, %ax
  171. ok3_read:
  172. mov %ax, sread
  173. shl $9, %cx
  174. add %cx, %bx
  175. jnc rp_read
  176. mov %es, %ax
  177. add $0x1000, %ax
  178. mov %ax, %es
  179. xor %bx, %bx
  180. jmp rp_read
  181. read_track:
  182. push %ax
  183. push %bx
  184. push %cx
  185. push %dx
  186. mov track, %dx
  187. mov sread, %cx
  188. inc %cx
  189. mov %dl, %ch
  190. mov head, %dx
  191. mov %dl, %dh
  192. mov $0, %dl
  193. and $0x0100, %dx
  194. mov $2, %ah
  195. int $0x13
  196. jc bad_rt
  197. pop %dx
  198. pop %cx
  199. pop %bx
  200. pop %ax
  201. ret
  202. bad_rt: mov $0, %ax
  203. mov $0, %dx
  204. int $0x13
  205. pop %dx
  206. pop %cx
  207. pop %bx
  208. pop %ax
  209. jmp read_track
  210. #/*
  211. # * This procedure turns off the floppy drive motor, so
  212. # * that we enter the kernel in a known state, and
  213. # * don't have to worry about it later.
  214. # */
  215. kill_motor:
  216. push %dx
  217. mov $0x3f2, %dx
  218. mov $0, %al
  219. outsb
  220. pop %dx
  221. ret
  222. sectors:
  223. .word 0
  224. msg1:
  225. .byte 13,10
  226. .ascii "Loading system ... compiled by yan!"
  227. .byte 13,10,13,10
  228. .org 508
  229. root_dev:
  230. .word ROOT_DEV
  231. boot_flag:
  232. .word 0xAA55
  233. .text
  234. endtext:
  235. .data
  236. enddata:
  237. .bss
  238. endbss:
Copyright © Linux教程網 All Rights Reserved