You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bootpart.S 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
  2. #define BOOT_SEG 0x07c0
  3. #define EXEC_SEG 0x0100
  4. #define STACK_SEG 0x0200
  5. #define STACK_SIZE 0x2000
  6. .text
  7. .arch i386
  8. .section ".prefix", "awx", @progbits
  9. .code16
  10. /*
  11. * Find active partition
  12. *
  13. * Parameters:
  14. * %dl : BIOS drive number
  15. * %bp : Active partition handler routine
  16. */
  17. find_active_partition:
  18. /* Set up stack at STACK_SEG:STACK_SIZE */
  19. movw $STACK_SEG, %ax
  20. movw %ax, %ss
  21. movw $STACK_SIZE, %sp
  22. /* Relocate self to EXEC_SEG */
  23. pushw $BOOT_SEG
  24. popw %ds
  25. pushw $EXEC_SEG
  26. popw %es
  27. xorw %si, %si
  28. xorw %di, %di
  29. movw $0x200, %cx
  30. rep movsb
  31. ljmp $EXEC_SEG, $1f
  32. 1: pushw %ds
  33. popw %es
  34. pushw %cs
  35. popw %ds
  36. /* Check for LBA extensions */
  37. movb $0x41, %ah
  38. movw $0x55aa, %bx
  39. stc
  40. int $0x13
  41. jc 1f
  42. cmpw $0xaa55, %bx
  43. jne 1f
  44. movw $read_lba, read_sectors
  45. 1:
  46. /* Read and process root partition table */
  47. xorb %dh, %dh
  48. movw $0x0001, %cx
  49. xorl %esi, %esi
  50. xorl %edi, %edi
  51. call process_table
  52. /* Print failure message */
  53. movw $10f, %si
  54. jmp boot_error
  55. 10: .asciz "Could not locate active partition\r\n"
  56. /*
  57. * Print failure message and boot next device
  58. *
  59. * Parameters:
  60. * %si : Failure string
  61. */
  62. boot_error:
  63. cld
  64. movw $0x0007, %bx
  65. movb $0x0e, %ah
  66. 1: lodsb
  67. testb %al, %al
  68. je 99f
  69. int $0x10
  70. jmp 1b
  71. 99: /* Boot next device */
  72. int $0x18
  73. /*
  74. * Process partition table
  75. *
  76. * Parameters:
  77. * %dl : BIOS drive number
  78. * %dh : Head
  79. * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
  80. * %ch : Low eight bits of cylinder
  81. * %esi:%edi : LBA address
  82. * %bp : Active partition handler routine
  83. *
  84. * Returns:
  85. * CF set on error
  86. */
  87. process_table:
  88. pushal
  89. call read_boot_sector
  90. jc 99f
  91. movw $446, %bx
  92. 1: call process_partition
  93. addw $16, %bx
  94. cmpw $510, %bx
  95. jne 1b
  96. 99: popal
  97. ret
  98. /*
  99. * Process partition
  100. *
  101. * Parameters:
  102. * %dl : BIOS drive number
  103. * %dh : Head
  104. * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
  105. * %ch : Low eight bits of cylinder
  106. * %esi:%edi : LBA address
  107. * %bx : Offset within partition table
  108. * %bp : Active partition handler routine
  109. */
  110. process_partition:
  111. pushal
  112. /* Load C/H/S values from partition entry */
  113. movb %es:1(%bx), %dh
  114. movw %es:2(%bx), %cx
  115. /* Update LBA address from partition entry */
  116. addl %es:8(%bx), %edi
  117. adcl $0, %esi
  118. /* Check active flag */
  119. testb $0x80, %es:(%bx)
  120. jz 1f
  121. call read_boot_sector
  122. jc 99f
  123. jmp *%bp
  124. 1: /* Check for extended partition */
  125. movb %es:4(%bx), %al
  126. cmpb $0x05, %al
  127. je 2f
  128. cmpb $0x0f, %al
  129. je 2f
  130. cmpb $0x85, %al
  131. jne 99f
  132. 2: call process_table
  133. 99: popal
  134. /* Reload original partition table */
  135. call read_boot_sector
  136. ret
  137. /*
  138. * Read single sector to %es:0000 and verify 0x55aa signature
  139. *
  140. * Parameters:
  141. * %dl : BIOS drive number
  142. * %dh : Head
  143. * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
  144. * %ch : Low eight bits of cylinder
  145. * %esi:%edi : LBA address
  146. *
  147. * Returns:
  148. * CF set on error
  149. */
  150. read_boot_sector:
  151. pushw %ax
  152. movw $1, %ax
  153. call *read_sectors
  154. jc 99f
  155. cmpw $0xaa55, %es:(510)
  156. je 99f
  157. stc
  158. 99: popw %ax
  159. ret
  160. /*
  161. * Read sectors to %es:0000
  162. *
  163. * Parameters:
  164. * %dl : BIOS drive number
  165. * %dh : Head
  166. * %cl : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
  167. * %ch : Low eight bits of cylinder
  168. * %esi:%edi : LBA address
  169. * %ax : Number of sectors (max 127)
  170. *
  171. * Returns:
  172. * CF set on error
  173. */
  174. read_sectors: .word read_chs
  175. read_chs:
  176. /* Read sectors using C/H/S address */
  177. pushal
  178. xorw %bx, %bx
  179. movb $0x02, %ah
  180. stc
  181. int $0x13
  182. sti
  183. popal
  184. ret
  185. read_lba:
  186. /* Read sectors using LBA address */
  187. pushal
  188. movw %ax, (lba_desc + 2)
  189. pushw %es
  190. popw (lba_desc + 6)
  191. movl %edi, (lba_desc + 8)
  192. movl %esi, (lba_desc + 12)
  193. movw $lba_desc, %si
  194. movb $0x42, %ah
  195. int $0x13
  196. popal
  197. ret
  198. lba_desc:
  199. .byte 0x10
  200. .byte 0
  201. .word 1
  202. .word 0x0000
  203. .word 0x0000
  204. .long 0, 0