Advertisement
MichaelPetch

SO78992609 - second_stage.asm

Sep 17th, 2024 (edited)
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.24 KB | None | 0 0
  1. ; Second stage bootloader
  2. [BITS 16]
  3. [ORG 0x7E00]
  4.  
  5. ; in first_stage.asm ensure this appears just before far hmp
  6. ; to this location.
  7. ; mov dl, [bootDrive] ; Drive number
  8.  
  9. KERNEL_OFFSET_HIGH equ 0xFFFF_FFFF_8000_0000
  10. KERNEL_OFFSET_LOW equ 0x8400
  11.  
  12. start:
  13. ; Set up segments
  14. xor ax, ax
  15. mov ds, ax
  16. mov es, ax
  17. mov ss, ax
  18. mov sp, 0x7C00 ; Set stack just below the bootloader
  19.  
  20. ; Print initial success message
  21. mov si, stage2Msg
  22. call print_string_16
  23.  
  24. ; Load the rest of Stage 2 and the kernel
  25. call load_kernel
  26.  
  27. ; Enable A20 line
  28. call enable_A20
  29.  
  30. ; Load GDT and switch to protected mode
  31. call enable_protected_mode
  32.  
  33. load_kernel:
  34. ; Load the rest of Stage 2 and the kernel from disk
  35. mov ah, 0x02 ; BIOS read sector function
  36. mov al, 60 ; Number of sectors to read (adjust as needed)
  37. mov ch, 0 ; Cylinder number
  38. mov cl, 5 ; Start from sector 5
  39. mov dh, 0 ; Head number
  40. mov bx, KERNEL_OFFSET_LOW
  41. ; Load starting at KERNEL_OFFSET_LOW
  42.  
  43. int 0x13 ; BIOS interrupt to read disk
  44. jc disk_error ; Jump if error
  45.  
  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. cli ; Disable interrupts
  56. lgdt [gdt_descriptor]
  57.  
  58. ; Enable protected mode
  59. mov eax, cr0
  60. or eax, 1 ; Set PE (Protection Enable) bit
  61. mov cr0, eax
  62.  
  63. ; Far jump to flush prefetch and enter protected mode
  64. jmp 0x08:protected_mode_entry
  65.  
  66. [BITS 32]
  67. protected_mode_entry:
  68. ; Set up 32-bit data segments
  69. mov ax, 0x10 ; Data 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 for protected mode
  77. mov esp, 0x90000
  78.  
  79. ; Print protected mode message
  80. mov esi, protected_mode_msg
  81. call print_string_pm
  82.  
  83. ; Set up paging for long mode
  84. call setup_paging
  85.  
  86. ; Load 64-bit GDT
  87. lgdt [gdt64_descriptor]
  88.  
  89. ; Enable long mode
  90. call enable_long_mode
  91.  
  92. ; Jump to long mode entry
  93. jmp 0x08:long_mode_entry
  94.  
  95. setup_paging:
  96. ; Identity map first 2MB
  97. mov edi, 0x1000 ; Page directory base address
  98. xor eax, eax ; Clear EAX (for zero-fill)
  99. mov ecx, (5*4096)/4 ; Number of 4KB entries
  100. rep stosd ; Zero the page directory and tables
  101.  
  102. ; Identity map first 2MiB
  103. ; Map 0x0000000000000000-0x00000000001fffff to physical 0x00000000-0x001fffff
  104. mov dword [0x1000], 0x00002003 ; PML4[0] = 0x2000 | PRESENT | READWRITE
  105. mov dword [0x2000], 0x00003003 ; PDP[0] = 0x3000 | PRESENT | READWRITE
  106. mov dword [0x3000], 0x00000083 ; PD[0] = 0x0000 | PRESENT | READWRITE | 2MIB_PAGE
  107.  
  108. ; Map 0xFFFFFFFF80000000-0xffffffff801fffff to physical 0x00000000-0x001fffff
  109. mov dword [0x1000+8*((KERNEL_OFFSET_HIGH>>39) & 0x1ff)], 0x00004003
  110. ; PML4[511] = 0x4000 | PRESENT | READWRITE
  111. mov dword [0x4000+8*((KERNEL_OFFSET_HIGH>>30) & 0x1ff)], 0x00005003
  112. ; PDP[510] = 0x5000 | PRESENT | READWRITE
  113. mov dword [0x5000+8*((KERNEL_OFFSET_HIGH>>21) & 0x1ff)], 0x00000083
  114. ; PD[0] = 0x0000 | PRESENT | READWRITE | 2MIB_PAGE
  115.  
  116. mov edi, 0x1000
  117. mov cr3, edi ; Load the page directory base into CR3 (set PDBR)
  118.  
  119. ret
  120.  
  121. enable_long_mode:
  122. ; Enable long mode in IA32_EFER MSR
  123. mov ecx, 0xC0000080
  124. rdmsr
  125. or eax, 1 << 8 ; Set Long Mode Enable (LME) bit
  126. wrmsr
  127.  
  128. mov eax, 10100000b ; Enable PAE and PGE bits and everything else off.
  129. mov cr4, eax
  130.  
  131. ; Enable paging and long mode by setting the PG and PE bits in CR0
  132. mov eax, cr0
  133. or eax, 1 << 31 ; Enable paging (PG bit)
  134. mov cr0, eax
  135.  
  136. ret
  137. [BITS 64]
  138. long_mode_entry:
  139. ; Set up segment registers for long mode
  140. mov ax, 0x10 ; Data segment selector
  141. mov ds, ax
  142. mov es, ax
  143. mov fs, ax
  144. mov gs, ax
  145. mov ss, ax
  146.  
  147. ; Set up stack in higher half
  148. mov rsp, 0x90000 + KERNEL_OFFSET_HIGH
  149.  
  150. ; Print long mode message
  151. mov rsi, long_mode_msg
  152. call print_string_lm
  153.  
  154. ; Jump to kernel entry point (higher-half address)
  155. mov rax, KERNEL_OFFSET_HIGH+KERNEL_OFFSET_LOW
  156. ; Kernel address in higher-half memory
  157. jmp rax
  158.  
  159. [BITS 16]
  160. print_string_16:
  161. lodsb
  162. or al, al
  163. jz .done
  164. mov ah, 0x0E ; BIOS teletype function
  165. int 0x10
  166. jmp print_string_16
  167. .done:
  168. ret
  169.  
  170. [BITS 32]
  171. print_string_pm:
  172. push eax
  173. push ebx
  174. mov ebx, 0xB8000 ; VGA video memory address
  175. .loop:
  176. lodsb
  177. or al, al
  178. jz .done
  179. mov ah, 0x0F ; Text attribute for character
  180. mov [ebx], ax ; Write character to VGA memory
  181. add ebx, 2 ; Move to next character
  182. jmp .loop
  183. .done:
  184. pop ebx
  185. pop eax
  186. ret
  187.  
  188. [BITS 64]
  189. print_string_lm:
  190. push rax
  191. push rbx
  192. mov rbx, 0xB8000 ; VGA video memory address
  193. .loop:
  194. lodsb
  195. or al, al
  196. jz .done
  197. mov ah, 0x0F ; Text attribute for character
  198. mov [rbx], ax ; Write character to VGA memory
  199. add rbx, 2 ; Move to next character
  200. jmp .loop
  201. .done:
  202. pop rbx
  203. pop rax
  204. ret
  205.  
  206. disk_error:
  207. ; Display error and halt
  208. mov si, diskErrorMsg
  209. call print_string_16
  210. cli
  211. hlt
  212.  
  213. ; Data
  214. stage3Msg db 'Entered Stage 2', 13, 10, 0
  215. stage2Msg db 'Entered Stage 2', 13, 10, 0
  216. protected_mode_msg db 'Entered Protected Mode', 0
  217. long_mode_msg db 'Entered Long Mode', 0
  218. diskErrorMsg db 'Disk Error in Stage 2!', 13, 10, 0
  219.  
  220. ; GDT for Protected Mode
  221. gdt_start:
  222. dq 0x0000000000000000 ; Null descriptor
  223. dq 0x00CF9A000000FFFF ; 32-bit code descriptor
  224. dq 0x00CF92000000FFFF ; 32-bit data descriptor
  225. gdt_end:
  226.  
  227. gdt_descriptor:
  228. dw gdt_end - gdt_start - 1
  229. dd gdt_start
  230.  
  231. ; GDT for Long Mode
  232. gdt64_start:
  233. dq 0x0000000000000000 ; Null descriptor
  234. dq 0x00AF9A000000FFFF ; 64-bit code descriptor
  235. dq 0x00AF92000000FFFF ; 64-bit data descriptor
  236. gdt64_end:
  237.  
  238. gdt64_descriptor:
  239. dw gdt64_end - gdt64_start - 1
  240. dq gdt64_start
  241.  
  242. times 512*3 - ($ - $$) db 0 ; Pad to 3 sectors
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement