Advertisement
MichaelPetch

SO78999226 - stage2.asm

Sep 18th, 2024
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.12 KB | None | 0 0
  1. [BITS 16]
  2. [org 0x8000]
  3.  
  4. TSS_ADDR_HI_BYTE_OFFSET equ 5
  5. TSS_ACCESS_BYTE_OFFSET equ 7
  6.  
  7. jmp a20_enter
  8. ; -------------------------
  9. ; Messages
  10. ; -------------------------
  11. section .data
  12. msg_a20_loading db 'A20 loading... ', 0x0D, 0x0A, 0
  13. msg_a20_error db 'A20 line enable -> failed ', 0x0D, 0x0A, 0
  14. msg_a20_enable db 'A20 line enable -> successfully ', 0x0D, 0x0A, 0
  15.  
  16. msg_gdt_loading db 'GDT loading... ', 0x0D, 0x0A, 0
  17. msg_gdt_success db 'GDT load -> successfully ', 0x0D, 0x0A, 0
  18.  
  19. msg_tss_loading db 'TSS loading... ', 0x0D, 0x0A, 0
  20. msg_tss_success db 'TSS load -> successfully ', 0x0D, 0x0A, 0
  21.  
  22. ; -------------------------
  23. ; BSS Section for TSS
  24. ; -------------------------
  25. section .bss
  26. tss resb 104 ; Reserve 104 bytes for the TSS (Task State Segment)
  27.  
  28. ; -------------------------
  29. ; Initialize the TSS
  30. ; -------------------------
  31. section .text
  32.  
  33. init_tss:
  34. ; Set ESP0 (stack pointer for privilege level 0)
  35. mov eax, 0x9FC00 ; Example stack pointer for ring 0
  36. mov [tss + 4], eax ; Set ESP0 in the TSS
  37.  
  38. ; Set SS0 (stack segment for privilege level 0)
  39. mov ax, 0x10 ; Kernel data segment selector (0x10)
  40. mov [tss + 8], ax ; Set SS0 in the TSS
  41.  
  42. ; Swap the byte with tss address bits 24:31 with the access byte
  43. ; In the TSS descriptor
  44. mov al, [gdt.tss + TSS_ADDR_HI_BYTE_OFFSET]
  45. xchg al, [gdt.tss + TSS_ACCESS_BYTE_OFFSET]
  46. mov [gdt.tss + TSS_ADDR_HI_BYTE_OFFSET], al
  47.  
  48. ret ; Return to the main flow
  49.  
  50. ; -------------------------
  51. ; Print Message: A20 Loading
  52. ; -------------------------
  53. a20_enter:
  54. mov ax, 0x0000 ; Set data segment to 0 for memory access
  55. mov ds, ax
  56. mov ah, 0x0E ; BIOS teletype function (interrupt 0x10, AH=0x0E) for printing characters
  57. mov bh, 0x00 ; Display page number
  58.  
  59. mov si, msg_a20_loading ; Load pointer to "A20 loading..." message into SI
  60.  
  61. a20_print_loading:
  62. lodsb ; Load next byte from [SI] into AL
  63. cmp al, 0 ; Check if null terminator (end of string)
  64. je a20_status_check ; Jump to A20 status check if end of message
  65. int 0x10 ; BIOS interrupt to print character in AL
  66. jmp a20_print_loading ; Repeat for next character
  67.  
  68. ; -------------------------
  69. ; A20 Status Check
  70. ; -------------------------
  71. a20_status_check:
  72. pushf ; Save flags
  73. push ds ; Save data segment
  74. push es ; Save extra segment
  75. push di ; Save destination index
  76. push si ; Save source index
  77.  
  78. cli ; Disable interrupts during A20 check
  79. xor ax, ax ; Set AX to 0
  80. mov es, ax ; Set extra segment (ES) to 0
  81. mov di, 0x0500 ; Set DI to test memory location 0x0500 in low memory
  82.  
  83. not ax ; Set AX to 0xFFFF (inverted 0)
  84. mov ds, ax ; Set data segment (DS) to 0xFFFF
  85. mov si, 0x0510 ; Set SI to memory location 0x0510 (also in low memory)
  86.  
  87. ; Save original values from memory locations
  88. mov al, byte [es:di] ; Load byte at ES:DI into AL
  89. push ax ; Save value from ES:DI
  90. mov al, byte [ds:si] ; Load byte at DS:SI into AL
  91. push ax ; Save value from DS:SI
  92.  
  93. ; Modify memory locations for the test
  94. mov byte [es:di], 0x00 ; Set ES:DI to 0x00
  95. mov byte [ds:si], 0xFF ; Set DS:SI to 0xFF
  96.  
  97. ; Check if memory write is visible at ES:DI
  98. cmp byte [es:di], 0xFF ; Compare ES:DI with 0xFF
  99.  
  100. ; Restore original memory values
  101. pop ax ; Restore value from stack to AX
  102. mov byte [ds:si], al ; Restore original byte at DS:SI
  103. pop ax ; Restore value from stack to AX
  104. mov byte [es:di], al ; Restore original byte at ES:DI
  105.  
  106. ; Determine A20 status based on comparison result
  107. mov ax, 0 ; Assume A20 is off
  108. je status_a20_off ; Jump if A20 is off
  109. mov ax, 1 ; A20 is on
  110. jmp status_a20_on ; Jump to A20 enabled handling
  111.  
  112. ; -------------------------
  113. ; A20 Enable via BIOS Interrupt 15h
  114. ; -------------------------
  115. status_a20_off:
  116. mov ax, 0x2401 ; Request to enable A20 via BIOS (INT 15h)
  117. int 0x15 ; BIOS interrupt call
  118.  
  119. jc a20_error ; If carry flag is set (error), jump to error handler
  120. jmp a20_status_check ; Otherwise, recheck A20 status after enabling
  121.  
  122. ; -------------------------
  123. ; A20 Enable Failure Handling
  124. ; -------------------------
  125. a20_error:
  126. mov ax, 0x0000 ; Reset segment register for message output
  127. mov ds, ax
  128. mov ah, 0x0E ; Set up for character output
  129. mov bh, 0x00 ; Display page number
  130.  
  131. mov si, msg_a20_error ; Load error message into SI
  132.  
  133. print_error_loop:
  134. lodsb ; Load next byte from message
  135. cmp al, 0 ; Check for null terminator
  136. je end_error_msg_a20 ; If end of string, stop printing
  137. int 0x10 ; Print character in AL
  138. jmp print_error_loop ; Loop to print the next character
  139.  
  140. end_error_msg_a20:
  141. cli ; Disable interrupts
  142. hlt ; Halt the system
  143.  
  144. ; -------------------------
  145. ; A20 Enable Success Handling
  146. ; -------------------------
  147. status_a20_on:
  148. mov ax, 0x0000 ; Reset data segment for message output
  149. mov ds, ax
  150. mov ah, 0x0E ; Set up for character output
  151. mov bh, 0x00 ; Display page number
  152.  
  153. mov si, msg_a20_enable ; Load success message into SI
  154.  
  155. print_enable_loop:
  156. lodsb ; Load next byte from message
  157. cmp al, 0 ; Check for null terminator
  158. je restore_registers_a20 ; If end of string, restore registers
  159. int 0x10 ; Print character in AL
  160. jmp print_enable_loop ; Loop to print the next character
  161.  
  162. ; -------------------------
  163. ; Restore Registers and Continue
  164. ; -------------------------
  165. restore_registers_a20:
  166. pop si ; Restore source index
  167. pop di ; Restore destination index
  168. pop es ; Restore extra segment
  169. pop ds ; Restore data segment
  170. popf ; Restore flags
  171.  
  172. sti ; Re-enable interrupts
  173.  
  174. ; -------------------------
  175. ; GDT And TSS Loading Message
  176. ; -------------------------
  177. mov ax, 0x0000 ; Reset data segment for message output
  178. mov ds, ax
  179. mov ah, 0x0E ; Set up for character output
  180. mov bh, 0x00 ; Display page number
  181.  
  182. mov si, msg_gdt_loading ; Load GDT loading message into SI
  183.  
  184. gdt_print_loading:
  185. lodsb ; Load next byte from message
  186. cmp al, 0 ; Check for null terminator
  187. je tss_loading_msg ; If end of string, jump to GDT setup
  188. int 0x10 ; Print character in AL
  189. jmp gdt_print_loading ; Loop to print the next character
  190.  
  191. tss_loading_msg:
  192. mov ax, 0x0000 ;
  193. mov ds, ax
  194. mov ah, 0x0E ;
  195. mov bh, 0x00 ;
  196.  
  197. mov si, msg_tss_loading ;
  198.  
  199. tss_print_loading:
  200. lodsb ;
  201. cmp al, 0 ;
  202. je gdt_setup ;
  203. int 0x10 ;
  204. jmp tss_print_loading ;
  205.  
  206. ; -------------------------
  207. ; GDT and TSS Setup and Loading
  208. ; -------------------------
  209. gdt_setup:
  210. cli ; Disable interrupts during GDT setup
  211. lgdt [gdt_descriptor] ; Load GDT descriptor into GDTR
  212.  
  213. push ds
  214. push es
  215.  
  216. call init_tss ; Initialize the TSS
  217.  
  218. pop es
  219. pop ds
  220.  
  221. ; Display success message after loading GDT
  222. mov ax, 0x0000 ; Reset data segment for message output
  223. mov ds, ax
  224. mov ah, 0x0E ; Set up for character output
  225. mov bh, 0x00 ; Display page number
  226.  
  227. mov si, msg_gdt_success ; Load GDT success message into SIs
  228.  
  229. gdt_print_success:
  230. lodsb ; Load next byte from message
  231. cmp al, 0 ; Check for null terminator
  232. je tss_succsess_msg ; If end of string, proceed to protected mode
  233. int 0x10 ; Print character in AL
  234. jmp gdt_print_success ; Loop to print the next character
  235.  
  236. tss_succsess_msg: ;
  237. mov ax, 0x0000 ;
  238. mov ds, ax
  239. mov ah, 0x0E ;
  240. mov bh, 0x00 ;
  241.  
  242. mov si, msg_tss_success ;
  243.  
  244. tss_print_success:
  245. lodsb ;
  246. cmp al, 0 ;
  247. je enter_protected_mode ;
  248. int 0x10 ;
  249. jmp tss_print_success ;
  250.  
  251. ; -------------------------
  252. ; Enter Protected Mode
  253. ; -------------------------
  254. enter_protected_mode:
  255. cli ; Disable interrupts before entering protected mode
  256. mov eax, cr0
  257. or eax, 1 ; Set protected mode bit in CR0
  258. mov cr0, eax
  259.  
  260. ; Far jump to update CS with GDT code segment (0x08)
  261. jmp 0x08:update_segments
  262.  
  263. [BITS 32]
  264. update_segments:
  265. ; Set up segment registers for protected mode
  266. mov ax, 0x10 ; Load GDT data segment selector (0x10)
  267. mov ds, ax
  268. mov es, ax
  269. mov fs, ax
  270. mov gs, ax
  271. mov ss, ax
  272.  
  273. mov ax, 0x28 ; Load task register with our TSS descriptor
  274. ltr ax
  275.  
  276. jmp kernel ; Jump to kernel code
  277.  
  278. ; -------------------------
  279. ; Kernel Code (currently halting)
  280. ; -------------------------
  281. kernel:
  282. hlt ; Halt the CPU (placeholder for actual kernel code)
  283.  
  284. ; -------------------------
  285. ; GDT Descriptor and TSS
  286. ; -------------------------
  287. section .data
  288. gdt_start:
  289. gdt:
  290. ; Null Descriptor
  291. dd 0x0
  292. dd 0x0
  293.  
  294. ; Kernel Code Segment (DPL = 0)
  295. dw 0xFFFF ; Limit
  296. dw 0x0000 ; Base (lower 16 bits)
  297. db 0x00 ; Base (next 8 bits)
  298. db 10011010b ; Access byte
  299. db 11001111b ; Flags and limit (upper 4 bits)
  300. db 0x00 ; Base (upper 8 bits)
  301.  
  302. ; Kernel Data Segment (DPL = 0)
  303. dw 0xFFFF ; Limit
  304. dw 0x0000 ; Base (lower 16 bits)
  305. db 0x00 ; Base (next 8 bits)
  306. db 10010010b ; Access byte
  307. db 11001111b ; Flags and limit (upper 4 bits)
  308. db 0x00 ; Base (upper 8 bits)
  309.  
  310. ; User Code Segment (DPL = 3)
  311. dw 0xFFFF ; Limit
  312. dw 0x0000 ; Base (lower 16 bits)
  313. db 0x00 ; Base (next 8 bits)
  314. db 11111010b ; Access byte (DPL = 3)
  315. db 11001111b ; Flags and limit (upper 4 bits)
  316. db 0x00 ; Base (upper 8 bits)
  317.  
  318. ; User Data Segment (DPL = 3)
  319. dw 0xFFFF ; Limit
  320. dw 0x0000 ; Base (lower 16 bits)
  321. db 0x00 ; Base (next 8 bits)
  322. db 11110010b ; Access byte (DPL = 3)
  323. db 11001111b ; Flags and limit (upper 4 bits)
  324. db 0x00 ; Base (upper 8 bits)
  325.  
  326. ; TSS Descriptor
  327. .tss:
  328. dw 0x0067 ; Limit
  329. dd tss ; Base
  330. db 00000000b ; Flags and limit (upper 4 bits)
  331. db 10001001b ; Access byte
  332.  
  333. gdt_end:
  334.  
  335. ; GDT Descriptor (contains size and location of GDT)
  336. gdt_descriptor:
  337. dw gdt_end - gdt_start - 1 ; Size of the GDT (in bytes, minus 1)
  338. dd gdt_start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement