boot.asm 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. ;*
  2. ;* x86_64-bios/boot.asm
  3. ;*
  4. ;* Copyright (C) 2017 - 2021 bzt (bztsrc@gitlab)
  5. ;*
  6. ;* Permission is hereby granted, free of charge, to any person
  7. ;* obtaining a copy of this software and associated documentation
  8. ;* files (the "Software"), to deal in the Software without
  9. ;* restriction, including without limitation the rights to use, copy,
  10. ;* modify, merge, publish, distribute, sublicense, and/or sell copies
  11. ;* of the Software, and to permit persons to whom the Software is
  12. ;* furnished to do so, subject to the following conditions:
  13. ;*
  14. ;* The above copyright notice and this permission notice shall be
  15. ;* included in all copies or substantial portions of the Software.
  16. ;*
  17. ;* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. ;* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. ;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. ;* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  21. ;* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  22. ;* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. ;* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  24. ;* DEALINGS IN THE SOFTWARE.
  25. ;*
  26. ;* This file is part of the BOOTBOOT Protocol package.
  27. ;* @brief Stage1 loader, compatible with BIOS boot specification and
  28. ;* El Torito CD-ROM boot in "no emulation" mode
  29. ;*
  30. ;*********************************************************************
  31. ;* Macros *
  32. ;*********************************************************************
  33. ;LBA packet fields
  34. lba_packet equ 07E00h
  35. virtual at lba_packet
  36. lbapacket.size: dw ?
  37. lbapacket.count:dw ?
  38. lbapacket.addr0:dw ?
  39. lbapacket.addr1:dw ?
  40. lbapacket.sect0:dw ?
  41. lbapacket.sect1:dw ?
  42. lbapacket.sect2:dw ?
  43. lbapacket.sect3:dw ?
  44. end virtual
  45. ;memory locations
  46. ldr.header equ 800h ;position of 2nd stage loader
  47. ldr.executor equ 804h ;ptr to init code
  48. ;Writes a message on screen.
  49. macro print msg
  50. {
  51. if ~ msg eq si
  52. push si
  53. mov si, msg
  54. end if
  55. call printfunc
  56. if ~ msg eq si
  57. pop si
  58. end if
  59. }
  60. ;*********************************************************************
  61. ;* code *
  62. ;*********************************************************************
  63. ;-----------------ENTRY POINT called by BIOS--------------------
  64. ORG 0600h
  65. USE16
  66. bootboot_record:
  67. jmp short .skipid
  68. nop
  69. ;skip BPB area so that we can use this
  70. ;boot code on a FAT / exFAT volume if needed
  71. db 120-($-$$) dup 0
  72. .skipid: ;relocate our code to offset 0h:600h
  73. cli
  74. cld
  75. xor ax, ax
  76. mov ss, ax
  77. mov sp, 600h
  78. push ax
  79. pop es
  80. push cs
  81. pop ds
  82. ;find our position in memory.
  83. call .getaddr
  84. .getaddr: pop si
  85. sub si, .getaddr-bootboot_record
  86. mov di, sp
  87. ;clear data area 500h-600h
  88. sub di, 100h
  89. mov cx, 80h
  90. repnz stosw
  91. ;and copy ourselves to 600h
  92. mov cx, 100h
  93. repnz movsw
  94. ;have to clear ds, because cs is set to 7c0 when booted from El Torito
  95. push es
  96. pop ds
  97. jmp 0:.start
  98. .start: ;save boot drive code
  99. mov byte [drive], dl
  100. ;check for lba presistance - floppy not supported any more
  101. ;we use USB sticks as removable media for a long time
  102. cmp dl, byte 80h
  103. jl .nolba
  104. .notfloppy: mov ah, byte 41h
  105. mov bx, word 55AAh
  106. int 13h
  107. jc .nolba
  108. cmp bx, word 0AA55h
  109. jne .nolba
  110. test cl, byte 1
  111. jnz .lbaok
  112. .nolba: mov si, lbanotf
  113. jmp diefunc
  114. .lbaok: ;get CDROM drive code
  115. mov ax, word 4B01h
  116. mov si, lba_packet
  117. mov byte [si + 2], 0E0h
  118. push si
  119. int 13h
  120. pop si
  121. jc .read2stg
  122. mov al, byte [si + 2]
  123. mov byte [cdrom], al
  124. ;try to load stage2 - it's a continous area on disk
  125. ;started at given sector with maximum size of 7000h bytes
  126. .read2stg: mov di, lba_packet
  127. mov si, stage2_addr
  128. ;set up for hard-drive
  129. xor ah, ah
  130. mov al, 16 ; size
  131. stosw
  132. mov al, 56 ; count
  133. stosw
  134. xor al, al
  135. mov ah, 8 ; addr0 to address 800h
  136. stosw
  137. xor ax, ax ; addr1
  138. stosw
  139. movsw ; sect0
  140. movsw ; sect1
  141. xor ax, ax
  142. stosw ; sect2
  143. stosw ; sect3
  144. mov dl, byte [drive]
  145. ;if it's a CDROM with 2048 byte sectors
  146. cmp dl, byte [cdrom]
  147. jl @f
  148. sub di, 8
  149. ;lba=lba/4
  150. clc
  151. rcr word [di+2], 1
  152. rcr word [di], 1
  153. clc
  154. rcr word [di+2], 1
  155. rcr word [di], 1
  156. ;count=count/4
  157. shr word [lbapacket.count], 2
  158. ;load sectors
  159. @@: mov ah, byte 42h
  160. mov si, lba_packet
  161. int 13h
  162. ;do we have a 2nd stage loader?
  163. .chk: cmp word [ldr.header], 0AA55h
  164. jne .nostage2
  165. cmp byte [ldr.header+3], 0E9h
  166. jne .nostage2
  167. mov dl, byte [drive]
  168. ;invoke stage2 real mode code
  169. mov ax, [ldr.executor]
  170. add ax, ldr.executor+2
  171. jmp ax
  172. .nostage2: ;try to load stage2 from a RAID mirror
  173. mov al, byte [drive]
  174. inc al
  175. cmp al, 87h
  176. jle @f
  177. mov al, 80h
  178. @@: mov byte [drive], al
  179. inc byte [cnt]
  180. cmp byte [cnt], 8
  181. jl .read2stg
  182. .nostage2err:
  183. mov si, stage2notf
  184. ;fall into the diefunc code
  185. ;*********************************************************************
  186. ;* functions *
  187. ;*********************************************************************
  188. ;writes the reason, waits for a key and reboots.
  189. diefunc:
  190. print panic
  191. call printfunc
  192. sti
  193. xor ax, ax
  194. int 16h
  195. mov al, 0FEh
  196. out 64h, al
  197. jmp far 0FFFFh:0 ;invoke BIOS POST routine
  198. ;ds:si zero terminated string to write
  199. printfunc:
  200. lodsb
  201. or al, al
  202. jz .end
  203. mov ah, byte 0Eh
  204. mov bx, word 11
  205. int 10h
  206. jmp printfunc
  207. .end: ret
  208. ;*********************************************************************
  209. ;* data area *
  210. ;*********************************************************************
  211. panic: db "BOOTBOOT-PANIC: no ",0
  212. lbanotf: db "LBA support",0
  213. stage2notf: db "FS0:\BOOTBOOT.BIN",0
  214. db 01B0h-($-$$) dup 0
  215. ;right before the partition table some data
  216. stage2_addr:dd 0FFFFFFFFh ;1B0h 2nd stage loader address
  217. ;this should be set by mkfs
  218. cnt: db 0
  219. drive: db 0
  220. cdrom: db 0
  221. db 0
  222. diskid: dd 0 ;1B8h WinNT expects it here
  223. dw 0
  224. ;1BEh first partition entry
  225. ;padding and magic
  226. db 01FEh-($-$$) dup 0
  227. db 55h,0AAh
  228. bootboot_record_end: