Advertisement
MichaelPetch

SO78992609 - Danson stage2.asm

Sep 21st, 2024 (edited)
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.15 KB | None | 0 0
  1. %ifndef KERNEL_SECTORS
  2. %define KERNEL_SECTORS 1
  3. %endif
  4.  
  5. [BITS 16]
  6. [org 0x8000]
  7.  
  8. ; -------------------------
  9. ; A20 Status Check
  10. ; -------------------------
  11. a20_status_check:
  12. pushf ; Save flags
  13. push ds ; Save data segment
  14. push es ; Save extra segment
  15. push di ; Save destination index
  16. push si ; Save source index
  17.  
  18. cli ; Disable interrupts during A20 check
  19. xor ax, ax ; Set AX to 0
  20. mov es, ax ; Set extra segment (ES) to 0
  21. mov di, 0x0500 ; Set DI to test memory location 0x0500 in low memory
  22.  
  23. not ax ; Set AX to 0xFFFF (inverted 0)
  24. mov ds, ax ; Set data segment (DS) to 0xFFFF
  25. mov si, 0x0510 ; Set SI to memory location 0x0510 (also in low memory)
  26.  
  27. ; Save original values from memory locations
  28. mov al, byte [es:di] ; Load byte at ES:DI into AL
  29. push ax ; Save value from ES:DI
  30. mov al, byte [ds:si] ; Load byte at DS:SI into AL
  31. push ax ; Save value from DS:SI
  32.  
  33. ; Modify memory locations for the test
  34. mov byte [es:di], 0x00 ; Set ES:DI to 0x00
  35. mov byte [ds:si], 0xFF ; Set DS:SI to 0xFF
  36.  
  37. ; Check if memory write is visible at ES:DI
  38. cmp byte [es:di], 0xFF ; Compare ES:DI with 0xFF
  39.  
  40. ; Restore original memory values
  41. pop ax ; Restore value from stack to AX
  42. mov byte [ds:si], al ; Restore original byte at DS:SI
  43. pop ax ; Restore value from stack to AX
  44. mov byte [es:di], al ; Restore original byte at ES:DI
  45.  
  46. ; Determine A20 status based on comparison result
  47. mov ax, 0 ; Assume A20 is off
  48. je status_a20_off ; Jump if A20 is off
  49.  
  50. mov ax, 1 ; A20 is on
  51. jmp status_a20_on ; Jump to A20 enabled handling
  52.  
  53. ; -------------------------
  54. ; A20 Enable via BIOS Interrupt 15h
  55. ; -------------------------
  56. status_a20_off:
  57. mov ax, 0x2401 ; Request to enable A20 via BIOS (INT 15h)
  58. int 0x15 ; BIOS interrupt call
  59.  
  60. jc a20_error ; If carry flag is set (error), jump to error handler
  61. jmp a20_status_check ; Otherwise, recheck A20 status after enabling
  62.  
  63. ; -------------------------
  64. ; A20 Enable Failure Handling
  65. ; -------------------------
  66. a20_error:
  67. xor ax, ax
  68. mov ds, ax
  69. mov ah, 0x0E ; Set up for character output
  70. mov bh, 0x00 ; Display page number
  71.  
  72. mov si, msg_a20_error ; Load error message into SI
  73.  
  74. print_error_loop:
  75. lodsb ; Load next byte from message
  76. cmp al, 0 ; Check for null terminator
  77. je end_error_msg_a20 ; If end of string, stop printing
  78. int 0x10 ; Print character in AL
  79. jmp print_error_loop ; Loop to print the next character
  80.  
  81. end_error_msg_a20:
  82. hlt ; Halt the system
  83.  
  84. ; -------------------------
  85. ; A20 Enable Success Handling
  86. ; -------------------------
  87. status_a20_on:
  88. xor ax, ax
  89. mov ds, ax
  90. mov ah, 0x0E ; Set up for character output
  91. mov bh, 0x00 ; Display page number
  92.  
  93. mov si, msg_a20_enable ; Load success message into SI
  94.  
  95. print_enable_loop:
  96. lodsb ; Load next byte from message
  97. cmp al, 0 ; Check for null terminator
  98. je restore_registers_a20 ; If end of string, restore registers
  99. int 0x10 ; Print character in AL
  100. jmp print_enable_loop ; Loop to print the next character
  101.  
  102. ; -------------------------
  103. ; Restore Registers and Continue
  104. ; -------------------------
  105. restore_registers_a20:
  106. pop si ; Restore source index
  107. pop di ; Restore destination index
  108. pop es ; Restore extra segment
  109. pop ds ; Restore data segment
  110. popf ; Restore flags
  111.  
  112. sti ; Re-enable interrupts
  113.  
  114. ; Now proceed to set up GDT and TSS
  115. jmp gdt_setup
  116.  
  117. ; -------------------------
  118. ; GDT Setup and TSS Setup
  119. ; -------------------------
  120. gdt_setup:
  121. cli ; Disable interrupts during GDT setup
  122. lgdt [gdt_descriptor] ; Load GDT descriptor into GDTR
  123.  
  124. ; -------------------------
  125. ; GDT & TSS Success Message
  126. ; -------------------------
  127. xor ax, ax
  128. mov ds, ax
  129. mov ah, 0x0E ; Set up for character output
  130. mov bh, 0x00 ; Display page number
  131.  
  132. mov si, msg_gdtss_success ; Load GDT success message into SI
  133.  
  134. gdtss_print_success:
  135. lodsb ; Load next byte from message
  136. cmp al, 0 ; Check for null terminator
  137. je enter_protected_mode ; If end of string, proceed to protected mode
  138. int 0x10 ; Print character in AL
  139. jmp gdtss_print_success ; Loop to print the next character
  140.  
  141. ; -------------------------
  142. ; Enter Protected Mode
  143. ; -------------------------
  144. enter_protected_mode:
  145. cli ; Disable interrupts before entering protected mode
  146.  
  147. mov ah, 0x0E
  148. mov al, 'B' ; Print 'B' for before protected mode
  149. int 0x10
  150.  
  151. mov ah, 0x02 ; BIOS function to read sectors
  152. mov al, KERNEL_SECTORS ; Number of sectors to read
  153. mov ch, 0x00 ; Cylinder number (0)
  154. mov cl, 0x03 ; Sector number (starts at sector 3)
  155. mov dh, 0x00 ; Head number (0)
  156. mov dl, 0x80 ; Drive number (0x80 = primary hard disk)
  157. push load_segment
  158. pop es ; Load segment
  159. mov bx, load_offset ; Destination address (ES:BX = 0x1000:0x0000 = Destination 0x10000)
  160. int 0x13 ; Call BIOS interrupt
  161. jc load_error ; Jump if error
  162.  
  163. mov eax, cr0
  164. or eax, 1 ; Set protected mode bit
  165. mov cr0, eax
  166.  
  167. jmp 0x08:pm_start ; Far jump to 32-bit code
  168. load_error:
  169. mov ah, 0x0E ; BIOS function to print character
  170. mov al, 'E' ; Print 'E' for error
  171. int 0x10 ; Call BIOS interrupt to print
  172. hlt
  173.  
  174. ; -------------------------
  175. ; Protected Mode Code Segment
  176. ; -------------------------
  177. [BITS 32]
  178. pm_start:
  179.  
  180. ; Set up segment registers for protected mode
  181. mov ax, 0x10 ; Load GDT data segment selector (0x10)
  182. mov ds, ax
  183. mov es, ax
  184. mov fs, ax
  185. mov gs, ax
  186. mov ss, ax
  187.  
  188. mov esp, 0x9FC00 ; Set ESP to a safe location within the segment
  189.  
  190. ; Load TSS
  191. call setup_tss
  192. mov ax, 0x28 ; TSS selector
  193. ltr ax ; Load Task Register with TSS selector
  194.  
  195. call run_offset
  196. jmp $
  197.  
  198. global setup_tss
  199. setup_tss:
  200. ; Get the base address of the TSS at runtime
  201. lea eax, [tss_start] ; Load the effective address of TSS into EAX
  202.  
  203. ; Set ESP0 (kernel stack pointer) and SS0 (kernel stack selector)
  204. mov dword [tss_start + 4], esp0 ; Set the kernel stack pointer (ESP0)
  205. mov dword [tss_start + 8], ss0 ; Set the kernel stack segment selector (SS0)
  206.  
  207. ; Fill the TSS base address into GDT descriptor at runtime
  208. mov [gdt_tss_base + 2], ax ; Set the lower 16 bits (Base Low)
  209. shr eax, 16 ; Get the upper 16 bits of the TSS base address
  210. mov [gdt_tss_base + 4], al ; Set the middle 8 bits (Base Middle)
  211. mov [gdt_tss_base + 7], ah ; Set the upper 8 bits (Base High)
  212.  
  213. ret
  214.  
  215. ; -------------------------
  216. ; TSS Memory Allocation
  217. ; -------------------------
  218. section .bss
  219. tss_start: resb 104 ; Reserve 104 bytes for the TSS
  220. tss_end:
  221.  
  222. esp0 EQU 0x9D000 ; Define the kernel stack pointer
  223. ; (0x9D000 is an example, should not be same as kernel stack)
  224. ss0 EQU 0x10 ; Define the kernel data segment selector (0x10, corresponding to your GDT)
  225.  
  226. section .text
  227. ; -------------------------
  228. ; GDT Definition
  229. ; -------------------------
  230. gdt_start:
  231.  
  232. ; Null Descriptor (Selector 0x00)
  233. dd 0x0
  234. dd 0x0
  235.  
  236. ; Kernel Code Segment Descriptor (Selector 0x08)
  237. dw 0xFFFF ; Limit Low
  238. dw 0x0000 ; Base Low
  239. db 0x00 ; Base Middle
  240. db 10011010b ; Access Byte
  241. db 11001111b ; Flags and Limit High
  242. db 0x00 ; Base High
  243.  
  244. ; Kernel Data Segment Descriptor (Selector 0x10)
  245. dw 0xFFFF ; Limit Low
  246. dw 0x0000 ; Base Low
  247. db 0x00 ; Base Middle
  248. db 10010010b ; Access Byte
  249. db 11001111b ; Flags and Limit High
  250. db 0x00 ; Base High
  251.  
  252. ; User Code Segment Descriptor (Selector 0x18)
  253. dw 0xFFFF ; Limit Low
  254. dw 0x0000 ; Base Low
  255. db 0x00 ; Base Middle
  256. db 11111010b ; Access Byte
  257. db 11001111b ; Flags and Limit High
  258. db 0x00 ; Base High
  259.  
  260. ; User Data Segment Descriptor (Selector 0x20)
  261. dw 0xFFFF ; Limit Low
  262. dw 0x0000 ; Base Low
  263. db 0x00 ; Base Middle
  264. db 11110010b ; Access Byte
  265. db 11001111b ; Flags and Limit High
  266. db 0x00 ; Base High
  267.  
  268. ; TSS Descriptor (Selector 0x28)
  269. gdt_tss_base:
  270. dw tss_end - tss_start - 1 ; Limit (Size of TSS)
  271. dw 0x0000 ; Base Low (to be filled at runtime)
  272. db 0x00 ; Base Middle (to be filled at runtime)
  273. db 0x89 ; Access Byte (TSS descriptor, 32-bit available)
  274. db 0x00 ; Flags and Limit High
  275. db 0x00 ; Base High (to be filled at runtime)
  276.  
  277. gdt_end:
  278.  
  279. ; -------------------------
  280. ; GDT Descriptor
  281. ; -------------------------
  282. gdt_descriptor:
  283. dw gdt_end - gdt_start - 1 ; Size of the GDT (in bytes, minus 1)
  284. dd gdt_start ; Linear address of the GDT
  285.  
  286. ; -------------------------
  287. ; Messages
  288. ; -------------------------
  289. msg_a20_error db 'A20 line enable -> failed ', 0x0D, 0x0A, 0
  290. msg_a20_enable db 'A20 line enable -> successfully ', 0x0D, 0x0A, 0
  291.  
  292. msg_gdtss_success db 'GDT and TSS is configured -> successfully ', 0x0D, 0x0A, 0
  293. load_segment equ 0x1000
  294. load_offset equ 0x0000
  295. run_offset equ ((load_segment << 4) + load_offset)
  296.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement