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.

337 lines
8.3 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. ORG 0x7C00
  2. BITS 16
  3. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4. ; SLRboot
  5. ; Bootloader for SingOS
  6. ; version 0.2.0.3-exp
  7. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8. cli
  9. jmp long 0x0000:start
  10. start:
  11. mov ax, 0x1000
  12. mov ss, ax
  13. mov sp, 0xb000
  14. mov ax, 0
  15. mov ds, ax
  16. mov es, ax
  17. mov [disk_identifier], dl
  18. sti
  19. mov si, 0x7c00
  20. mov di, 0x600
  21. mov cx, 0x100
  22. rep movsw
  23. mov bx, relocated
  24. sub bx, 0x7600 ; Calculate the offset.
  25. push bx
  26. ret ; Return far
  27. ;jmp long 0:bx
  28. relocated:
  29. mov si, message ; Put address of the null-terminated string to output into 'si'
  30. call print ; Call our string-printing routine
  31. ; Check for more than one active partition that we can start from.
  32. xor bx, bx
  33. xor cx, cx
  34. mov ax, [partition_1.active_partition]
  35. call dumpax
  36. cli
  37. hlt
  38. cmp ax, 0x80
  39. jne check_p_2
  40. mov bx, 0x01 ; Partion 1 active
  41. inc cx
  42. check_p_2:
  43. mov ax, [partition_2.active_partition]
  44. cmp ax, 0x80
  45. jne check_p_3
  46. inc cx
  47. mov bx, 0x02 ; Partion 2 active
  48. check_p_3:
  49. mov ax, [partition_3.active_partition]
  50. cmp ax, 0x80
  51. jne check_p_4
  52. inc cx
  53. mov bx, 0x03 ; Partion 3 active
  54. check_p_4:
  55. mov ax, [partition_4.active_partition]
  56. cmp ax, 0x80
  57. jne eval_active_partion_number
  58. inc cx
  59. mov bx, 0x04 ; Partion 4 active
  60. eval_active_partion_number:
  61. cmp cx, 1
  62. je boot_partition:
  63. ; here goes wait call, for the user to enter debug mode.
  64. ; Wating for 2 seconds:
  65. mov ah, 0x86 ; code for waiting interupt call
  66. mov cx, 0x001e ; high count of microseconds
  67. mov dx, 0x8480 ; low count
  68. int 0x15
  69. .busy_wait_for_key:
  70. xor ax, ax
  71. mov ah, 0x01 ; BIOS call to wait for key
  72. int 0x16
  73. mov bx, 1
  74. boot_partition:
  75. ; IMPORTANT bx, has to hold the value 1-4 for the partiotion that wanted to be booted.
  76. mov ax, partition_1
  77. .loop:
  78. cmp bx, 1
  79. je break
  80. add ax, 0x10
  81. dec bx
  82. jmp .loop
  83. break:
  84. add ax, 7 ; This is the offset to fetch the LBA start adress of the partition record
  85. mov bx, [ax] ; first part of LBA
  86. mov WORD [DAPACK.lba_addr_dw_low], bx
  87. inc ax ; next part
  88. mov bx, [ax]
  89. mov WORD [DAPACK.lba_addr_dw_low + 1], bx
  90. inc ax ; next part
  91. mov bx, [ax]
  92. mov WORD [DAPACK.lba_addr_dw_low + 2], bx
  93. inc ax ; next part
  94. mov bx, [ax]
  95. mov WORD [DAPACK.lba_addr_dw_low + 3], bx
  96. mov WORD [DAPACK.blkcnt], 0x01
  97. mov WORD [DAPACK.db_addr_segment], 0x0000
  98. mov WORD [DAPACK.db_addr_offset], 0x7c00
  99. mov si, DAPACK ; address of "disk address packet"
  100. xor ax, ax
  101. mov ah, 0x42 ; READ
  102. mov dl, [disk_identifier]
  103. int 0x13
  104. jmp long 0x0:0x7c00
  105. cli
  106. hlt
  107. %IF 0
  108. cli
  109. jmp long 0x0000:start
  110. start:
  111. xor ax, ax
  112. mov ds, ax
  113. mov es, ax
  114. mov ss, ax
  115. mov [disk_identifier], dl
  116. ; initialize stack
  117. ; Set up 4K stack after this bootloader
  118. ; [Remember: Effective Address = Segment*16 + Offset]
  119. mov ax, 0x7C0 ; Set 'ax' equal to the location of this bootloader divided by 16
  120. add ax, 0x20 ; Skip over the size of the bootloader divided by 16
  121. mov ss, ax ; Set 'ss' to this location (the beginning of our stack region)
  122. mov sp, 8192 ; Set 'ss:sp' to the top of our 8K stack
  123. sti
  124. mov si, message ; Put address of the null-terminated string to output into 'si'
  125. call print ; Call our string-printing routine
  126. mov si, enter_debug_mode
  127. call print
  128. call printCRLF
  129. ;%IF 0
  130. ; here goes wait call, for the user to enter debug mode.
  131. ; Wating for 2 seconds:
  132. mov ah, 0x86 ; code for waiting interupt call
  133. mov cx, 0x001e ; high count of microseconds
  134. mov dx, 0x8480 ; low count
  135. int 0x15
  136. .busy_wait_for_key:
  137. xor ax, ax
  138. mov ah, 0x01 ; BIOS call to wait for key
  139. int 0x16
  140. jnz debug_mode
  141. ; entering system check:
  142. mov si, enter_system_check
  143. mov si, sys_check_ok ; Put address of the null-terminated string to output into 'si'
  144. call print ; Call our string-printing routine
  145. mov si, boot_system ; Put address of the null-terminated string to output into 'si'
  146. call print ; Call our string-printing routine
  147. ;This goes first as to now overwrite %ah and %al.
  148. ;mov ax, 0x0050
  149. ;mov es, ax ;Section to write into
  150. ;mov ah, 0x2 ;Read sectors from drive
  151. ;mov al, 0x08 ;Number of sectors to read (31 * 512 = 15872 bytes)
  152. ;mov ch, 0x0 ;Low 8 bits of cylinder
  153. ;mov cl, 0x11 ;First sector to read (bits 0-5), upper bits of cylinder (bits 6-7)
  154. ;mov dh, 0x0 ;Head number
  155. ;mov dl, [disk_identifier] ;Drive number
  156. ;mov bx, 0x0000 ;Offset into section
  157. ;int 0x13 ;Low level disk services
  158. ;jnc notcarry
  159. ;mov si, error_str
  160. ;call print
  161. ;jmp endcarrycheck
  162. notcarry:
  163. ;mov si, success_str
  164. ;call print
  165. ;call printCRLF
  166. mov ax, 0x0
  167. mov ds, ax
  168. mov ax, 89 ; lba adress
  169. jmp 0x50:0x0000 ; Jump to the kernel
  170. endcarrycheck:
  171. cli ; Clear the Interrupt Flag (disable external interrupts)
  172. hlt ; Halt the CPU (until the next external interrupt)
  173. debug_mode:
  174. mov si, .welcome_debug
  175. call print
  176. cli ; Clear the Interrupt Flag (disable external interrupts)
  177. hlt
  178. .welcome_debug db 'This is debug mode', 0
  179. printCRLF:
  180. mov ah, 0xE
  181. mov al, 13
  182. int 0x10
  183. mov al, 10
  184. int 0x10
  185. ret
  186. %ENDIF
  187. ;Routine for printing a 'ax' as hex
  188. dumpax:
  189. pusha ; save registers
  190. mov bx, ax
  191. mov ah, 0xE ; Teletype output
  192. mov cx, 4 ; 4 nipples in a 16 bit word
  193. .loop:
  194. rol bx, 4 ; rotate to next nipple
  195. mov al, bl ; we copy to al because we need to mask only the low 4 bits
  196. and al, 1111b ; Do the masking
  197. add al, '0' ; convert to ASCII
  198. cmp al, '9' ; If we are greater than 9 ascii, we add 7 to make digit 10 be represented as 'A'
  199. jbe .skip ; -|-
  200. add al, 7 ; -|-
  201. .skip: ; -|-
  202. int 0x10 ; BIOS call 'output'
  203. loop .loop
  204. popa ; restore registers
  205. ret
  206. ; Routine for outputting string in 'si' register to screen
  207. print:
  208. mov ah, 0xE ; Specify 'int 0x10' 'teletype output' function
  209. ; [AL = Character, BH = Page Number, BL = Colour (in graphics mode)]
  210. .printchar:
  211. lodsb ; Load byte at address SI into AL, and increment SI
  212. cmp al, 0
  213. je .done ; If the character is zero (NUL), stop writing the string
  214. int 0x10 ; Otherwise, print the character via 'int 0x10'
  215. jmp .printchar ; Repeat for the next character
  216. .done:
  217. ret
  218. data:
  219. message db 'SLRboot for SingOS! v0.2.0.3-exp',13,10,0
  220. ;enter_debug_mode db 'Press d to enter bootloader debug mode',13,10,0
  221. ;enter_system_check db 'Performing system check:',13,10,0
  222. ;sys_check_ok db 'System check ok', 13, 10, 0
  223. ;boot_system db 'Read SingOS from disk', 13, 10, 0
  224. ;error_str db 'Error', 0
  225. ;success_str db 'Success', 0
  226. boot_this_partition: dw 0
  227. disk_identifier db 0
  228. DAPACK:
  229. .dap_Size: db 0x10 ; This is always 16 bytes (0x10)
  230. .rev_byte: db 0x0 ; reserved byte, should always be zero
  231. .blkcnt: dw 0x0 ; int 13 resets this to # of blocks actually read/written
  232. .db_addr_offset: dw 0x0 ; memory buffer destination address (0:7c00)
  233. .db_addr_segment: dw 0x0 ; in memory page zero
  234. .lba_addr_dw_low: dd 0x0 ; put the lba to read in this spot
  235. .lba_addr_dw_high: dd 0x0 ; more storage bytes only for big lba's ( > 4 bytes )
  236. ; Pad to 510 bytes (boot sector size minus 2) with 0s, and finish with the two-byte standard boot signature
  237. times 446-($-$$) db 0 ; First partion entry
  238. partition_1:
  239. .active_partition db 0x80
  240. .start_CHS db 0x00, 0x00, 0x11;0x20, 0x21, 0x00
  241. .disk_type db 0x83
  242. .end_CHS db 0x8C, 0x3D, 0x0F
  243. .start_LBA db 0x10, 0x00, 0x00, 0x00
  244. .size db 0x00, 0xC8, 0x03, 0x00
  245. partition_2:
  246. .active_partition db 0x80
  247. .start_CHS db 0x8C, 0x3E, 0x0F
  248. .disk_type db 0x83
  249. .end_CHS db 0xFF, 0xFF, 0xFF
  250. .start_LBA db 0x00, 0xD0, 0x03, 0x00
  251. .size db 0x00, 0x28, 0x1C, 0x03
  252. partition_3:
  253. .active_partition db 0x00
  254. .start_CHS db 0x00, 0x00, 0x00
  255. .disk_type db 0x00
  256. .end_CHS db 0x00, 0x00, 0x00
  257. .start_LBA db 0x00, 0x00, 0x00, 0x00
  258. .size db 0x00, 0x00, 0x00, 0x00
  259. partition_4:
  260. .active_partition db 0x00
  261. .start_CHS db 0x00, 0x00, 0x00
  262. .disk_type db 0x00
  263. .end_CHS db 0x00, 0x00, 0x00
  264. .start_LBA db 0x00, 0x00, 0x00, 0x00
  265. .size db 0x00, 0x00, 0x00, 0x00
  266. times 510-($-$$) db 0
  267. dw 0xAA55 ; => 0x55 0xAA (little endian byte order)
  268. ; bootloder debug_mode goes here
  269. times 8192-($-$$) db 0
  270. ; mov si, 0x7be
  271. ; cmp byte [si], al
  272. ; jne 0x33
  273. ; add si, 0x10
  274. ; cmp si, 0x7fe
  275. ; jne 0x24
  276. ; jmp 0x49
  277. ; mov ah, 2
  278. ; mov al, 1
  279. ; mov bx, 0x7c00
  280. ; mov dl, 0x80
  281. ; mov dh, byte [si + 1]
  282. ; mov cx, word [si + 2]
  283. ; int 0x13
  284. ; jmp long 0:0x7c00
  285. ; jmp 0x49