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.2KB

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