Advertisement
MichaelPetch

SO79013023 - second_stage.asm

Sep 23rd, 2024
31
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.79 KB | None | 0 0
  1. ;
  2. ; By alpluspluss 09/22/2024 AD
  3. ;
  4. ; second stage bootloader
  5. ; for x86_64
  6.  
  7. [BITS 16]
  8. [ORG 0x7E00]
  9.  
  10. KERNEL_OFFSET_HIGH equ 0xFFFF_FFFF_8000_0000
  11. KERNEL_LOAD_SEGMENT equ 0x1000
  12. KERNEL_LOAD_OFFSET equ 0x0000
  13. KERNEL_OFFSET_LOW equ (KERNEL_LOAD_SEGMENT<<4)+KERNEL_LOAD_OFFSET
  14.  
  15. start:
  16. ; Just before getting here DL=bootdrive
  17. ; set up segments & stack at 0x9000
  18. xor ax, ax
  19. mov ds, ax
  20. mov es, ax
  21. mov ss, ax
  22. mov sp, 0x9000
  23.  
  24. ; print 'Jumped to stage 2'
  25. mov si, stage2Message
  26. call print_16bit
  27.  
  28. call enable_A20 ; enable A20 for mem access beyond 1 MB
  29. call load_kernel ; load the rest of stage 2 and kernel
  30. call enable_protected_mode ; load GDT and switch to protected mode
  31.  
  32. ; @NOTE: this part is basically 'load_loop' from stage 1
  33. ; but has some extras & some stuff removed
  34. load_kernel:
  35. mov ah, 0x02 ; BIOS read sector function
  36. mov al, 9 ; read 6 sectors / time
  37. mov ch, 0 ; cylinder number
  38. mov cl, 5 ; start from sector 5
  39. mov dh, 0 ; Head number
  40. push KERNEL_LOAD_SEGMENT
  41. pop es
  42. mov bx, KERNEL_LOAD_OFFSET
  43. ; ES:BX is location where sectors will be loaded
  44. int 0x13 ; read disk op
  45. jc disk_error ; jump if disk error
  46. ret
  47.  
  48. enable_A20:
  49. in al, 0x92
  50. or al, 2
  51. out 0x92, al
  52. ret
  53.  
  54. enable_protected_mode:
  55. xchg bx, bx
  56. cli ; disable interrupt
  57. lgdt [gdt_descriptor] ; load GDT descriptor
  58.  
  59. ; init protected mode
  60. mov eax, cr0
  61. or eax, 1 ; set PE bit
  62. mov cr0, eax
  63.  
  64. jmp 0x08:protected_mode_entry ; jump to segment 0x08
  65.  
  66. [BITS 32]
  67. protected_mode_entry:
  68. ; setup segments
  69. mov ax, 0x10 ; segment selector
  70. mov ds, ax
  71. mov es, ax
  72. mov fs, ax
  73. mov gs, ax
  74. mov ss, ax
  75.  
  76. ; set up stack at 0x200000
  77. mov esp, 0x200000
  78.  
  79. ; say 'Entered protected mode'
  80. mov esi, protectedModeMessage
  81. call print_protected_mode
  82.  
  83. ; setup paging for long mode
  84. call setup_paging
  85.  
  86. lgdt [gdt64_descriptor] ; load GDT descriptor in 64-bit
  87.  
  88. call enable_long_mode
  89. jmp 0x08:long_mode_entry ; jump to segment 0x08 at offset long_mode_entry
  90.  
  91. setup_paging:
  92. mov edi, 0x1000 ; assuming they are 4KB aligned
  93. xor eax, eax
  94. mov ecx, 5 * 4096 / 4 ; number of 4 KB entries
  95. rep stosd ; zero page dir and tables
  96.  
  97. ; *IMPORTANT*
  98. ; @NOTE: page fault can happen here
  99. ; Identity map first 2MB
  100. ; Map 0x0000000000000000-0x00000000001fffff
  101. ; to physical 0x00000000-0x001fffff
  102. mov dword [0x1000], 0x00002003 ; PML4[0] = 0x2000 | PRESENT | READWRITE
  103. mov dword [0x2000], 0x00003003 ; PDP[0] = 0x3000 | PRESENT | READWRITE
  104. mov dword [0x3000], 0x00000083 ; PD[0] = 0x0000 | PRESENT | READWRITE | 2MB_PAGE
  105.  
  106. ; Map 0xFFFFFFFF80000000-0xffffffff801fffff
  107. ; to physical 0x00000000-0x001fffff
  108. mov dword [0x1000 + 8 * ((KERNEL_OFFSET_HIGH >> 39) & 0x1ff)], 0x00004003 ; PML4[511] = 0x4000 | PRESENT | READWRITE
  109. mov dword [0x4000 + 8 * ((KERNEL_OFFSET_HIGH >> 30) & 0x1ff)], 0x00005003 ; PDP[510] = 0x5000 | PRESENT | READWRITE
  110. mov dword [0x5000 + 8 * ((KERNEL_OFFSET_HIGH >> 21) & 0x1ff)], 0x00000083 ; PD[0] = 0x0000 | PRESENT | READWRITE | 2MB_PAGE
  111.  
  112. mov edi, 0x1000
  113. mov cr3, edi ; load page dir base into cr3 to set PDBR
  114. ret
  115.  
  116. enable_long_mode:
  117. mov ecx, 0xC0000080
  118. rdmsr
  119. or eax, 1 << 8
  120. wrmsr
  121.  
  122. ; enable PAE and PGE bits in CR0
  123. mov eax, 10100000b
  124. mov cr4, eax
  125.  
  126. mov eax, cr0
  127. or eax, 1 << 31 ; enable paging
  128. mov cr0, eax
  129. ret
  130.  
  131. [BITS 64]
  132. long_mode_entry:
  133. mov ax, 0x10
  134. mov ds, ax
  135. mov es, ax
  136. mov fs, ax
  137. mov gs, ax
  138. mov ss, ax
  139.  
  140. ; setup stack for kernel higher half
  141. mov rsp, 0x90000 + KERNEL_OFFSET_HIGH
  142.  
  143. ; print 'Reached long mode'
  144. mov rsi, longModeMessage
  145. call print_long_mode
  146.  
  147. mov rax, KERNEL_OFFSET_HIGH + KERNEL_OFFSET_LOW
  148. jmp rax
  149.  
  150. [BITS 16]
  151. print_16bit:
  152. lodsb
  153. or al, al
  154. jz .done
  155. mov ah, 0x0E
  156. int 0x10
  157. jmp print_16bit
  158. .done:
  159. ret
  160.  
  161. [BITS 32]
  162. print_protected_mode:
  163. push eax
  164. push ebx
  165. mov ebx, 0xB8000 ; VGA mem address
  166. .loop:
  167. lodsb
  168. or al, al
  169. jz .done
  170. mov ah, 0x0F
  171. mov [ebx], ax
  172. add ebx, 2
  173. jmp .loop
  174. .done:
  175. pop ebx
  176. pop eax
  177. ret
  178.  
  179. [BITS 64]
  180. print_long_mode:
  181. push rax
  182. push rbx
  183. mov rbx, 0xB8000 ; VGA mem address
  184. .loop:
  185. lodsb
  186. or al, al
  187. jz .done
  188. mov ah, 0x0F
  189. mov [rbx], ax
  190. add rbx, 2
  191. jmp .loop
  192. .done:
  193. pop rbx
  194. pop rax
  195. ret
  196.  
  197. [BITS 16]
  198. disk_error:
  199. mov si, diskErrorMessage
  200. call print_16bit
  201. cli
  202. hlt
  203.  
  204. stage2Message db 'Jumped to stage 2', 13, 10, 0
  205. diskErrorMessage db 'Disk error in stage 2', 13, 10, 0
  206. longModeMessage db 'Entered long mode', 0
  207. protectedModeMessage db 'Entered protected mode', 0
  208.  
  209. align 16
  210. gdt_start:
  211. dq 0x0000000000000000 ; null descriptor
  212. dq 0x00CF9A000000FFFF ; 32-bit code descriptor
  213. dq 0x00CF92000000FFFF ; 32-bit data descriptor
  214. gdt_end:
  215.  
  216. gdt_descriptor:
  217. dw gdt_end - gdt_start - 1
  218. dd gdt_start
  219.  
  220. gdt64_start:
  221. dq 0x0000000000000000 ; null descriptor
  222. dq 0x00AF9A000000FFFF ; 64-bit code descriptor
  223. dq 0x00AF92000000FFFF ; 64-bit data descriptor
  224. gdt64_end:
  225.  
  226. gdt64_descriptor:
  227. dw gdt64_end - gdt64_start - 1
  228. dq gdt64_start
  229.  
  230. section .bss
  231. align 16
  232. stack_bottom:
  233. resb 16384
  234. stack_top:
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement