imgrecv.asm 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. ;*
  2. ;* bios/imgrecv.asm
  3. ;* https://gitlab.com/bztsrc/imgrec
  4. ;*
  5. ;* Copyright (C) 2020 bzt (bztsrc@gitlab)
  6. ;*
  7. ;* Permission is hereby granted, free of charge, to any person
  8. ;* obtaining a copy of this software and associated documentation
  9. ;* files (the "Software"), to deal in the Software without
  10. ;* restriction, including without limitation the rights to use, copy,
  11. ;* modify, merge, publish, distribute, sublicense, and/or sell copies
  12. ;* of the Software, and to permit persons to whom the Software is
  13. ;* furnished to do so, subject to the following conditions:
  14. ;*
  15. ;* The above copyright notice and this permission notice shall be
  16. ;* included in all copies or substantial portions of the Software.
  17. ;*
  18. ;* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19. ;* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20. ;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  21. ;* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  22. ;* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  23. ;* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. ;* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  25. ;* DEALINGS IN THE SOFTWARE.
  26. ;*
  27. LOAD_ADDR equ 1024*1024
  28. if ~defined OPTIONROM
  29. ORG 0600h
  30. USE16
  31. end if
  32. bootboot_record:
  33. if ~defined OPTIONROM
  34. jmp short .skipid
  35. nop
  36. .skipid:
  37. end if
  38. ;relocate our code to offset 0h:600h
  39. cli
  40. cld
  41. xor ax, ax
  42. mov ss, ax
  43. mov sp, 600h
  44. push ax
  45. pop es
  46. push cs
  47. pop ds
  48. ;find our position in memory.
  49. call .getaddr
  50. .getaddr: pop si
  51. sub si, .getaddr-bootboot_record
  52. mov di, sp
  53. ;clear data area 500h-600h
  54. sub di, 100h
  55. mov cx, 80h
  56. repnz stosw
  57. ;and copy ourselves to 600h
  58. mov cx, 100h
  59. repnz movsw
  60. ;have to clear ds, because cs is set to 7c0 when booted from El Torito
  61. push es
  62. pop ds
  63. jmp 0:.start
  64. .start:
  65. ;-----initialize serial port COM1,115200,8N1------
  66. mov ax, 0401h
  67. xor bx, bx
  68. mov cx, 030Bh
  69. xor dx, dx
  70. int 14h
  71. mov dx, 03fdh
  72. in al, dx
  73. cmp al, 0ffh
  74. jne .a20
  75. mov si, errstr
  76. @@: lodsb
  77. or al, al
  78. jz @b
  79. mov ah, byte 0Eh
  80. mov bx, word 11
  81. int 10h
  82. jmp @b
  83. @@: jmp @b
  84. ;-----enable A20-----
  85. .a20: mov ax, 2401h
  86. int 15h
  87. ;---- enable protmode ----
  88. lgdt [GDT_value]
  89. mov eax, cr0
  90. or al, 1
  91. mov cr0, eax
  92. jmp CODE_PROT:protmode_start
  93. USE32
  94. ; IN: al, character to send
  95. uart_send: mov ah, al
  96. mov dx, 3fdh
  97. @@: pause
  98. in al, dx
  99. and al, 20h
  100. jz @b
  101. sub dl, 5
  102. mov al, ah
  103. out dx, al
  104. ret
  105. ; IN: edi pointer to store the received char
  106. uart_getc: mov dx, 03fdh
  107. @@: pause
  108. in al, dx
  109. and al, 1
  110. jz @b
  111. sub dl, 5
  112. in al, dx
  113. stosb
  114. ret
  115. protmode_start:
  116. mov ax, DATA_PROT
  117. mov ds, ax
  118. mov es, ax
  119. mov fs, ax
  120. mov gs, ax
  121. mov ss, ax
  122. mov esp, 600h
  123. ;---- notify raspbootcom / USBImager to send the kernel ----
  124. again: mov al, 3
  125. call uart_send
  126. call uart_send
  127. call uart_send
  128. ;---- read the kernel's size ----
  129. mov edi, size
  130. call uart_getc
  131. call uart_getc
  132. call uart_getc
  133. call uart_getc
  134. mov ecx, dword [size]
  135. mov edi, LOAD_ADDR
  136. ;---- send negative or positive acknowledge ----
  137. cmp ecx, 32
  138. jb .se
  139. cmp ecx, 4*1024*1024
  140. jb .ok
  141. .se: mov al, 'S'
  142. call uart_send
  143. mov al, 'E'
  144. call uart_send
  145. jmp again
  146. .ok: mov ebx, edi
  147. mov al, 'O'
  148. call uart_send
  149. mov al, 'K'
  150. call uart_send
  151. ;---- read in the image ----
  152. @@: call uart_getc
  153. dec ecx
  154. jnz @b
  155. mov al, 0FFh ;disable PIC
  156. out 021h, al
  157. out 0A1h, al
  158. in al, 70h ;disable NMI
  159. or al, 80h
  160. out 70h, al
  161. ;---- get entry point ----
  162. cmp dword [ebx], 06D6F687Fh ; \x7fELF
  163. jne @f
  164. cmp byte [ebx+4], 2
  165. je .long
  166. mov ebx, dword [ebx+24]
  167. @@: jmp ebx
  168. .long: ;PML4
  169. mov edi, 01000h
  170. ;pointer to 2M PDPE (first 4G RAM identity mapped)
  171. mov dword [edi], 02003h
  172. ;2M PDPE
  173. mov edi, 02000h
  174. mov dword [edi], 03003h
  175. ;2M PDE
  176. mov edi, 03000h
  177. xor eax, eax
  178. mov al, 83h
  179. mov ecx, 512* 1;G RAM
  180. @@: stosd
  181. add edi, 4
  182. add eax, 2*1024*1024
  183. dec ecx
  184. jnz @b
  185. mov eax, 01000h
  186. mov cr3, eax
  187. mov ecx, 0C0000080h ;EFER MSR
  188. rdmsr
  189. or eax, 100h ;enable long mode
  190. wrmsr
  191. mov eax, cr0
  192. or eax, 0C0000001h
  193. mov cr0, eax ;enable paging with cache disabled
  194. mov eax, GDT64_table
  195. mov dword [GDT_value+2], eax
  196. lgdt [GDT_value] ;read 80 bit address
  197. jmp @f
  198. nop
  199. @@: jmp CODE_LONG:@f
  200. USE64
  201. @@: xor eax, eax ;load long mode segments
  202. mov ax, DATA_LONG
  203. mov ds, ax
  204. mov es, ax
  205. mov ss, ax
  206. mov rbx, qword [ebx+24]
  207. jmp rbx
  208. size: dd 0
  209. errstr: db "No COM1?", 13, 10, 0
  210. align 16
  211. GDT_table: dd 0, 0 ;null descriptor
  212. DATA_PROT = $-GDT_table
  213. dd 0000FFFFh,008F9200h ;flat ds
  214. CODE_PROT = $-GDT_table
  215. dd 0000FFFFh,00CF9A00h ;32 bit prot mode ring0 cs
  216. GDT_value: dw $-GDT_table
  217. dd GDT_table
  218. GDT64_table:dd 0,0
  219. CODE_LONG = $-GDT_table
  220. dd 0000FFFFh,00809200h
  221. DATA_LONG = $-GDT_table
  222. dd 0000FFFFh,00209800h
  223. if ~defined OPTIONROM
  224. ;padding and magic
  225. db 01FEh-($-$$) dup 0
  226. db 55h,0AAh
  227. end if