Advertisement
MichaelPetch

rmode.asm

Jun 2nd, 2020
275
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.35 KB | None | 0 0
  1. [bits 32]
  2.  
  3. global int32, _int32
  4.  
  5. struc regs16_t
  6. .di resw 1
  7. .si resw 1
  8. .bp resw 1
  9. .sp resw 1
  10. .bx resw 1
  11. .dx resw 1
  12. .cx resw 1
  13. .ax resw 1
  14. .gs resw 1
  15. .fs resw 1
  16. .es resw 1
  17. .ds resw 1
  18. .ef resw 1
  19. endstruc
  20.  
  21. %define INT32_BASE 0x7C00
  22. %define REBASE(x) (((x) - reloc) + INT32_BASE)
  23. %define GDTENTRY(x) ((x) << 3)
  24. %define CODE32 GDTENTRY(1) ; 0x08
  25. %define DATA32 GDTENTRY(2) ; 0x10
  26. %define CODE16 GDTENTRY(3) ; 0x18
  27. %define DATA16 GDTENTRY(4) ; 0x20
  28. %define STACK16 (INT32_BASE - regs16_t_size)
  29.  
  30. section .text
  31. int32: use32 ; by Napalm
  32. _int32:
  33. pushf ; Save flags (including interrupt flag)
  34. cli ; disable interrupts
  35. pusha ; save register state to 32bit stack
  36. mov esi, reloc ; set source to code below
  37. mov edi, INT32_BASE ; set destination to new base address
  38. mov ecx, (int32_end - reloc) ; set copy size to our codes size
  39. cld ; clear direction flag (so we copy forward)
  40. rep movsb ; do the actual copy (relocate code to low 16bit space)
  41. jmp INT32_BASE ; jump to new code location
  42. reloc: use32 ; by Napalm
  43. mov [REBASE(stack32_ptr)], esp ; save 32bit stack pointer
  44. sidt [REBASE(idt32_ptr)] ; save 32bit idt pointer
  45. sgdt [REBASE(gdt32_ptr)] ; save 32bit gdt pointer
  46. lgdt [REBASE(gdt16_ptr)] ; load 16bit gdt pointer
  47. lea esi, [esp+0x24] ; set position of intnum on 32bit stack
  48. lodsd ; read intnum into eax
  49. mov [REBASE(ib)], al ; set intrrupt immediate byte from our arguments
  50. mov esi, [esi] ; read regs pointer in esi as source
  51. mov edi, STACK16 ; set destination to 16bit stack
  52. mov ecx, regs16_t_size ; set copy size to our struct size
  53. mov esp, edi ; save destination to as 16bit stack offset
  54. rep movsb ; do the actual copy (32bit stack to 16bit stack)
  55. jmp word CODE16:REBASE(p_mode16) ; switch to 16bit selector (16bit protected mode)
  56. p_mode16: use16
  57. mov ax, DATA16 ; get our 16bit data selector
  58. mov ds, ax ; set ds to 16bit selector
  59. mov es, ax ; set es to 16bit selector
  60. mov fs, ax ; set fs to 16bit selector
  61. mov gs, ax ; set gs to 16bit selector
  62. mov ss, ax ; set ss to 16bit selector
  63. mov eax, cr0 ; get cr0 so we can modify it
  64. and al, ~0x01 ; mask off PE bit to turn off protected mode
  65. mov cr0, eax ; set cr0 to result
  66. jmp word 0x0000:REBASE(r_mode16) ; finally set cs:ip to enter real-mode
  67. r_mode16: use16
  68. xor ax, ax ; set ax to zero
  69. mov ds, ax ; set ds so we can access idt16
  70. mov ss, ax ; set ss so they the stack is valid
  71. lidt [REBASE(idt16_ptr)] ; load 16bit idt
  72. mov bx, 0x0870 ; master 8 and slave 112
  73. call resetpic ; set pic's the to real-mode settings
  74. popa ; load general purpose registers from 16bit stack
  75. pop gs ; load gs from 16bit stack
  76. pop fs ; load fs from 16bit stack
  77. pop es ; load es from 16bit stack
  78. pop ds ; load ds from 16bit stack
  79. ; enable interrupts
  80. db 0xCD ; opcode of INT instruction with immediate byte
  81. ib: db 0x00
  82. cli ; disable interrupts
  83. xor sp, sp ; zero sp so we can reuse it
  84. mov ss, sp ; set ss so the stack is valid
  85. mov sp, INT32_BASE ; set correct stack position so we can copy back
  86. pushf ; save eflags to 16bit stack
  87. push ds ; save ds to 16bit stack
  88. push es ; save es to 16bit stack
  89. push fs ; save fs to 16bit stack
  90. push gs ; save gs to 16bit stack
  91. pusha ; save general purpose registers to 16bit stack
  92. mov bx, 0x2028 ; master 32 and slave 40
  93. call resetpic ; restore the pic's to protected mode settings
  94. mov eax, cr0 ; get cr0 so we can modify it
  95. inc eax ; set PE bit to turn on protected mode
  96. mov cr0, eax ; set cr0 to result
  97. jmp dword CODE32:REBASE(p_mode32) ; switch to 32bit selector (32bit protected mode)
  98. p_mode32: use32
  99. mov ax, DATA32 ; get our 32bit data selector
  100. mov ds, ax ; reset ds selector
  101. mov es, ax ; reset es selector
  102. mov fs, ax ; reset fs selector
  103. mov gs, ax ; reset gs selector
  104. mov ss, ax ; reset ss selector
  105. lgdt [REBASE(gdt32_ptr)] ; restore 32bit gdt pointer
  106. lidt [REBASE(idt32_ptr)] ; restore 32bit idt pointer
  107. mov esp, [REBASE(stack32_ptr)] ; restore 32bit stack pointer
  108. mov esi, STACK16 ; set copy source to 16bit stack
  109. lea edi, [esp+0x28] ; set position of regs pointer on 32bit stack
  110. mov edi, [edi] ; use regs pointer in edi as copy destination
  111. mov ecx, regs16_t_size ; set copy size to our struct size
  112. cld ; clear direction flag (so we copy forward)
  113. rep movsb ; do the actual copy (16bit stack to 32bit stack)
  114. popa ; restore registers
  115. popf ; Restore interrupts
  116. ret ; return to caller
  117.  
  118. resetpic: ; reset's 8259 master and slave pic vectors
  119. push ax ; expects bh = master vector, bl = slave vector
  120. mov al, 0x11 ; 0x11 = ICW1_INIT | ICW1_ICW4
  121. out 0x20, al ; send ICW1 to master pic
  122. out 0xA0, al ; send ICW1 to slave pic
  123. mov al, bh ; get master pic vector param
  124. out 0x21, al ; send ICW2 aka vector to master pic
  125. mov al, bl ; get slave pic vector param
  126. out 0xA1, al ; send ICW2 aka vector to slave pic
  127. mov al, 0x04 ; 0x04 = set slave to IRQ2
  128. out 0x21, al ; send ICW3 to master pic
  129. shr al, 1 ; 0x02 = tell slave its on IRQ2 of master
  130. out 0xA1, al ; send ICW3 to slave pic
  131. shr al, 1 ; 0x01 = ICW4_8086
  132. out 0x21, al ; send ICW4 to master pic
  133. out 0xA1, al ; send ICW4 to slave pic
  134. pop ax ; restore ax from stack
  135. ret ; return to caller
  136.  
  137. stack32_ptr: ; address in 32bit stack after we
  138. dd 0x00000000 ; save all general purpose registers
  139.  
  140. idt32_ptr: ; IDT table pointer for 32bit access
  141. dw 0x0000 ; table limit (size)
  142. dd 0x00000000 ; table base address
  143.  
  144. gdt32_ptr: ; GDT table pointer for 32bit access
  145. dw 0x0000 ; table limit (size)
  146. dd 0x00000000 ; table base address
  147.  
  148. idt16_ptr: ; IDT table pointer for 16bit access
  149. dw 0x03FF ; table limit (size)
  150. dd 0x00000000 ; table base address
  151.  
  152. gdt16_base: ; GDT descriptor table
  153. .null: ; 0x00 - null segment descriptor
  154. dd 0x00000000 ; must be left zero'd
  155. dd 0x00000000 ; must be left zero'd
  156.  
  157. .code32: ; 0x01 - 32bit code segment descriptor 0xFFFFFFFF
  158. dw 0xFFFF ; limit 0:15
  159. dw 0x0000 ; base 0:15
  160. db 0x00 ; base 16:23
  161. db 0x9A ; present, iopl/0, code, execute/read
  162. db 0xCF ; 4Kbyte granularity, 32bit selector; limit 16:19
  163. db 0x00 ; base 24:31
  164.  
  165. .data32: ; 0x02 - 32bit data segment descriptor 0xFFFFFFFF
  166. dw 0xFFFF ; limit 0:15
  167. dw 0x0000 ; base 0:15
  168. db 0x00 ; base 16:23
  169. db 0x92 ; present, iopl/0, data, read/write
  170. db 0xCF ; 4Kbyte granularity, 32bit selector; limit 16:19
  171. db 0x00 ; base 24:31
  172.  
  173. .code16: ; 0x03 - 16bit code segment descriptor 0x000FFFFF
  174. dw 0xFFFF ; limit 0:15
  175. dw 0x0000 ; base 0:15
  176. db 0x00 ; base 16:23
  177. db 0x9A ; present, iopl/0, code, execute/read
  178. db 0x0F ; 1Byte granularity, 16bit selector; limit 16:19
  179. db 0x00 ; base 24:31
  180.  
  181. .data16: ; 0x04 - 16bit data segment descriptor 0x000FFFFF
  182. dw 0xFFFF ; limit 0:15
  183. dw 0x0000 ; base 0:15
  184. db 0x00 ; base 16:23
  185. db 0x92 ; present, iopl/0, data, read/write
  186. db 0x0F ; 1Byte granularity, 16bit selector; limit 16:19
  187. db 0x00 ; base 24:31
  188.  
  189. gdt16_ptr: ; GDT table pointer for 16bit access
  190. dw gdt16_ptr - gdt16_base - 1 ; table limit (size)
  191. dd gdt16_base ; table base address
  192.  
  193. int32_end: ; end marker (so we can copy the code)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement