Advertisement
MichaelPetch

Untitled

Jun 21st, 2019
456
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.38 KB | None | 0 0
  1. %define BUFFER_OFF 0x8000
  2. %define BUFFER_SEG 0x0000
  3. %define LOAD_SEG 0x0c00
  4. %define LOAD_OFF 0x0000
  5.  
  6. [bits 16]
  7. [org 0x7c00]
  8.  
  9. jmp short start
  10. nop
  11.  
  12. ;DISK DESCRIPTION(BIOS PARAMETER BLOCK)
  13. OEMLabel db "BOOT "
  14. BytesPerSector dw 512
  15. SectorsPerCluster db 1
  16. ReservedForBoot dw 1
  17. NumberOfFats db 2
  18. RootDirEntries dw 224 ; Number of entries in root dir
  19. ; (224 * 32 = 7168 = 14 sectors to read)
  20. LogicalSectors dw 2880
  21. MediumByte db 0F0h
  22. SectorsPerFat dw 9
  23. SectorsPerTrack dw 18 ; Sectors per track (36/cylinder)
  24. Sides dw 2
  25. HiddenSectors dd 0
  26. LargeSectors dd 0
  27. DriveNo dw 0
  28. Signature db 0x29
  29. VolumeID dd 00000000h
  30. VolumeLabel db "myOS "
  31. FileSystem db "FAT12 "
  32.  
  33. ;BOOTLOADER
  34. start:
  35. xor ax, ax
  36. mov ds, ax
  37. cli
  38. mov ss, ax
  39. mov sp, 0x7c00
  40. sti
  41. cld
  42. mov [drive], dl
  43.  
  44. mov si, BUFFER_SEG ; ES=buffer segment. Only has to be set once
  45. mov es, si
  46. mov bx, BUFFER_OFF
  47.  
  48. load_root:
  49. mov ax, 19 ; Root directory starts at LBA 19
  50. call lba_to_hts
  51. mov ax, (2<<8) | 14 ; Root directory for this media fits in 14 sectors
  52. ; Combine 2 moves (AH/AL) into one
  53. ; same as 'mov ah, 2' and 'mov al, 14'
  54. int 13h
  55. jc reset
  56. mov si, load_root_str
  57. call print
  58.  
  59. search_file:
  60. mov di, BUFFER_OFF
  61. mov cx, word [RootDirEntries]
  62. xor ax, ax
  63. .loop_search:
  64. xchg cx, dx
  65. mov si, filename
  66. mov cx, 11
  67. rep cmpsb
  68. je file_found
  69. add ax, 32
  70. mov di, BUFFER_OFF
  71. add di, ax
  72. xchg dx, cx
  73. loop .loop_search
  74. jmp file_not_found
  75.  
  76. file_found:
  77. mov ax, word [di+15] ; Buffer and Bootloader now in same segment DS
  78. ; Don't need ES:
  79. mov [cluster], ax
  80. mov ax, 1
  81. call lba_to_hts
  82. mov bx, BUFFER_OFF
  83. mov ax, (2<<8) | 9 ; Combine 2 moves (AH/AL) into one
  84. ; same as 'mov ah, 2' and 'mov al, 9'
  85.  
  86. load_FAT:
  87. mov si, FAT_str
  88. call print
  89. int 13h
  90. jnc load_file
  91. call reset
  92. jnc load_FAT
  93. jmp disk_error
  94.  
  95. load_file:
  96. mov si, load_file_str
  97. call print
  98. mov ax, LOAD_SEG ; ES=load segment for kernel
  99. mov es, ax
  100.  
  101. load_sector:
  102. mov ax, word [cluster] ; Get cluster number to read
  103. add ax, 33-2 ; Add 31 to cluster since FAT data area
  104. ; starts at Logical Block Address (LBA) 33
  105. ; and we need to subtract 2 since valid
  106. ; cluster numbers start at 2
  107. call lba_to_hts
  108. xor bx, bx ; Always read a kernel sector to offset 0
  109.  
  110. mov ax, (2<<8) | 1 ; AH=2 is read, AL=1 read 1 sector
  111. ; Combine 2 moves (AH/AL) into one
  112. ; same as 'mov ah, 2' and 'mov al, 1'
  113. int 13h
  114. jnc next_cluster
  115. call reset
  116. jmp load_sector
  117.  
  118. next_cluster:
  119. mov bx, [cluster] ; BX = current cluster number
  120. mov ax, bx ; AX = copy of cluster number
  121. shl bx, 1 ; BX = BX * 2
  122. add bx, ax ; BX = BX + AX (BX now contains BX * 3)
  123. shr bx, 1 ; Divide BX by 2
  124. mov ax, [bx+BUFFER_OFF] ; Get cluster entry from FAT table
  125. jnc .even ; If carry not set by SHR then result was even
  126. .odd:
  127. shr ax, 4 ; If cluster entry is odd then cluster number is AX >> 4
  128. jmp short finish_load
  129. .even:
  130. and ah, 0Fh ; If cluster entry is even then cluster number is AX & 0fffh
  131. ; We just need to and AH with 0fh to achieve the same result
  132. finish_load:
  133. mov word [cluster], ax
  134. cmp ax, 0FF8h
  135. jae .jump_to_file
  136. mov ax, es
  137. add ax, 32 ; Increasing segment by 1 advances 16 bytes (paragraph)
  138. ; in memory. Adding 32 is same advancing 512 bytes (32*16)
  139. mov es, ax ; Advance ES to point at next 512 byte block to read into
  140. jmp load_sector ; Go back and load the next sector
  141. .jump_to_file:
  142. mov dl, byte [drive]
  143. jmp 0x0000:(LOAD_SEG<<4)
  144.  
  145. ;SUBROUTINES
  146. file_not_found:
  147. mov si, not_found_str
  148. call print
  149. jmp reboot
  150. print:
  151. pusha
  152. mov ah, 0x0E
  153. .next:
  154. lodsb
  155. cmp al,0
  156. je .done
  157. int 0x10
  158. jmp .next
  159. .done:
  160. popa
  161. ret
  162. lba_to_hts:
  163. div byte [SectorsPerTrack] ; 16-bit by 8-bit DIV : LBA / SPT
  164. mov cl, ah ; CL = S = LBA mod SPT
  165. inc cl ; CL = S = (LBA mod SPT) + 1
  166. xor ah, ah ; Upper 8-bit of 16-bit value set to 0 for DIV
  167. div byte [Sides] ; 16-bit by 8-bit DIV : (LBA / SPT) / HEADS
  168. mov ch, al ; CH = C = (LBA / SPT) / HEADS
  169. mov dh, ah ; DH = H = (LBA / SPT) mod HEADS
  170. mov dl, [drive] ; boot device, not necessary to set but convenient
  171. ret
  172. reset:
  173. mov ah, 0
  174. int 13h ;reset disk
  175. jc disk_error ;if failed jump to search fail
  176. ret
  177. disk_error:
  178. mov si, disk_error_str
  179. call print
  180. reboot:
  181. mov si, reboot_pmpt
  182. call print
  183. mov ax, 0
  184. int 16h
  185. mov ax, 0
  186. int 19h
  187.  
  188. ;DATA
  189. load_root_str db 'Loading Root',13,10,0
  190. disk_error_str db 'Disk Error!',13,10,0
  191. reboot_pmpt db 'PRESS A KEY TO REBOOT',13,10,0
  192. not_found_str db 'KERNEL NOT FOUND',13,10,0
  193. FAT_str db 'Loading FAT',13,10,0
  194. load_file_str db 'Loading KERNEL',13,10,0
  195. drive dw 0
  196. cluster dw 0
  197. filename db 'KERNEL BIN',0
  198. ;PADDING AND SIGNATURE
  199. times (510-($-$$)) db 0x00
  200. dw 0AA55h
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208. org 0xc000
  209. [bits 16] ;16-bit binary format
  210.  
  211. ;KERNEL
  212. os_main:
  213. mov ax, cs ;CS is segment where we were loaded
  214. cli
  215. mov ss, ax
  216. xor sp, sp
  217. sti
  218. cld
  219. mov ds, ax
  220. mov es, ax
  221. mov fs, ax
  222. mov gs, ax
  223. mov si, hello ;print welcome
  224. call print
  225. call A20_line
  226. call load_gdt
  227. call set_mode
  228. ; cli
  229. ; hlt
  230.  
  231. ;SUBROUTINES
  232. A20_line:
  233. in al, 0xee
  234. mov si, A20_enable_str
  235. call print
  236. ret
  237. load_gdt:
  238. cli
  239. lgdt [toc]
  240. sti
  241. mov si, load_gdt_str
  242. call print
  243. ret
  244. set_mode:
  245. mov si, set_mode_str
  246. call print
  247. cli
  248. mov eax, cr0
  249. or al, 1
  250. mov cr0, eax
  251. jmp 08h:ENTER_PROTECTED_MODE
  252.  
  253. print:
  254. mov ah, 0x0e
  255. .next:
  256. lodsb
  257. cmp al,0
  258. je .done
  259. int 0x10
  260. jmp .next
  261. .done:
  262. ret
  263.  
  264. ;DATA
  265. hello db 'Hello',13,10,0
  266. A20_enable_str db 'A20 Line enabled',13,10,0
  267. load_gdt_str db 'Loading GDT',13,10,0
  268. set_mode_str db 'Entering Protected Mode',13,10,0
  269.  
  270. ;GLOBAL DESCRIPTOR TABLE
  271. gdt_data:
  272. dd 0 ;null descriptor
  273. dd 0
  274. dw 0FFFFh ;code descriptor
  275. dw 0
  276. db 0
  277. db 10011010b
  278. db 11001111b
  279. db 0
  280. dw 0FFFFh ;data descriptor
  281. dw 0
  282. db 0
  283. db 10010010b
  284. db 11001111b
  285. db 0
  286. end_of_gdt:
  287. toc:
  288. dw end_of_gdt - gdt_data - 1
  289. dd gdt_data
  290.  
  291.  
  292. ;PROTECTED MODE
  293. [bits 32]
  294. ENTER_PROTECTED_MODE:
  295. VIDMEM equ 0xB8000
  296. mov ax, 0x10
  297. mov es, ax
  298. mov ds, ax
  299. mov fs, ax
  300. mov gs, ax
  301. mov esp, 0x90000
  302. mov eax, 0x0f54
  303. mov [VIDMEM], eax
  304. cli
  305. hlt
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement