/orange/chapter6/c/kernel/kernel.asm

https://github.com/lingod01/lingod · Assembly · 359 lines · 233 code · 64 blank · 62 comment · 0 complexity · 4f8d0847ca05414880e7803a03815971 MD5 · raw file

  1. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. ; kernel.asm
  3. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4. ; Forrest Yu, 2005
  5. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6. %include "sconst.inc"
  7. ; 导入函数
  8. extern cstart
  9. extern kernel_main
  10. extern exception_handler
  11. extern spurious_irq
  12. extern disp_str
  13. extern delay
  14. ; 导入全局变量
  15. extern gdt_ptr
  16. extern idt_ptr
  17. extern p_proc_ready
  18. extern tss
  19. extern disp_pos
  20. extern k_reenter
  21. bits 32
  22. [SECTION .data]
  23. clock_int_msg db "^", 0
  24. [SECTION .bss]
  25. StackSpace resb 2 * 1024
  26. StackTop: ; 栈顶
  27. [section .text] ; 代码在此
  28. global _start ; 导出 _start
  29. global restart
  30. global divide_error
  31. global single_step_exception
  32. global nmi
  33. global breakpoint_exception
  34. global overflow
  35. global bounds_check
  36. global inval_opcode
  37. global copr_not_available
  38. global double_fault
  39. global copr_seg_overrun
  40. global inval_tss
  41. global segment_not_present
  42. global stack_exception
  43. global general_protection
  44. global page_fault
  45. global copr_error
  46. global hwint00
  47. global hwint01
  48. global hwint02
  49. global hwint03
  50. global hwint04
  51. global hwint05
  52. global hwint06
  53. global hwint07
  54. global hwint08
  55. global hwint09
  56. global hwint10
  57. global hwint11
  58. global hwint12
  59. global hwint13
  60. global hwint14
  61. global hwint15
  62. _start:
  63. ; 此时内存看上去是这样的更详细的内存情况在 LOADER.ASM 中有说明
  64. ;
  65. ; ...
  66. ;
  67. ; Page Tables
  68. ; (大小由LOADER决定) PageTblBase
  69. ; 00101000h
  70. ; Page Directory Table PageDirBase = 1M
  71. ; 00100000h
  72. ; Hardware Reserved B8000h gs
  73. ; 9FC00h
  74. ; LOADER.BIN somewhere in LOADER esp
  75. ; 90000h
  76. ; KERNEL.BIN
  77. ; 80000h
  78. ; KERNEL 30400h KERNEL 入口 (KernelEntryPointPhyAddr)
  79. ; 30000h
  80. ; ...
  81. ;
  82. ; 0h cs, ds, es, fs, ss
  83. ;
  84. ;
  85. ; GDT 以及相应的描述符是这样的
  86. ;
  87. ; Descriptors Selectors
  88. ;
  89. ; Dummy Descriptor
  90. ;
  91. ; DESC_FLAT_C (04G) 8h = cs
  92. ;
  93. ; DESC_FLAT_RW (04G) 10h = ds, es, fs, ss
  94. ;
  95. ; DESC_VIDEO 1Bh = gs
  96. ;
  97. ;
  98. ; 注意! 在使用 C 代码的时候一定要保证 ds, es, ss 这几个段寄存器的值是一样的
  99. ; 因为编译器有可能编译出使用它们的代码, 而编译器默认它们是一样的. 比如串拷贝操作会用到 ds es.
  100. ;
  101. ;
  102. ; esp LOADER 挪到 KERNEL
  103. mov esp, StackTop ; 堆栈在 bss 段中
  104. mov dword [disp_pos], 0
  105. sgdt [gdt_ptr] ; cstart() 中将会用到 gdt_ptr
  106. call cstart ; 在此函数中改变了gdt_ptr让它指向新的GDT
  107. lgdt [gdt_ptr] ; 使用新的GDT
  108. lidt [idt_ptr]
  109. jmp SELECTOR_KERNEL_CS:csinit
  110. csinit: ; 这个跳转指令强制使用刚刚初始化的结构<<OS:D&I 2nd>> P90.
  111. ;jmp 0x40:0
  112. ;ud2
  113. xor eax, eax
  114. mov ax, SELECTOR_TSS
  115. ltr ax
  116. ;sti
  117. jmp kernel_main
  118. ;hlt
  119. ; 中断和异常 -- 硬件中断
  120. ; ---------------------------------
  121. %macro hwint_master 1
  122. push %1
  123. call spurious_irq
  124. add esp, 4
  125. hlt
  126. %endmacro
  127. ALIGN 16
  128. hwint00: ; Interrupt routine for irq 0 (the clock).
  129. sub esp, 4
  130. pushad ; `.
  131. push ds ; |
  132. push es ; | 保存原寄存器值
  133. push fs ; |
  134. push gs ; /
  135. mov dx, ss
  136. mov ds, dx
  137. mov es, dx
  138. inc byte [gs:0] ; 改变屏幕第 0 行, 第 0 列的字符
  139. mov al, EOI ; `. reenable
  140. out INT_M_CTL, al ; / master 8259
  141. inc dword [k_reenter]
  142. cmp dword [k_reenter], 0
  143. jne .re_enter
  144. mov esp, StackTop ; 切到内核栈
  145. sti
  146. push clock_int_msg
  147. call disp_str
  148. add esp, 4
  149. ;;; push 1
  150. ;;; call delay
  151. ;;; add esp, 4
  152. cli
  153. mov esp, [p_proc_ready] ; 离开内核栈
  154. lea eax, [esp + P_STACKTOP]
  155. mov dword [tss + TSS3_S_SP0], eax
  156. .re_enter: ; 如果(k_reenter != 0)会跳转到这里
  157. dec dword [k_reenter]
  158. pop gs ; `.
  159. pop fs ; |
  160. pop es ; | 恢复原寄存器值
  161. pop ds ; |
  162. popad ; /
  163. add esp, 4
  164. iretd
  165. ALIGN 16
  166. hwint01: ; Interrupt routine for irq 1 (keyboard)
  167. hwint_master 1
  168. ALIGN 16
  169. hwint02: ; Interrupt routine for irq 2 (cascade!)
  170. hwint_master 2
  171. ALIGN 16
  172. hwint03: ; Interrupt routine for irq 3 (second serial)
  173. hwint_master 3
  174. ALIGN 16
  175. hwint04: ; Interrupt routine for irq 4 (first serial)
  176. hwint_master 4
  177. ALIGN 16
  178. hwint05: ; Interrupt routine for irq 5 (XT winchester)
  179. hwint_master 5
  180. ALIGN 16
  181. hwint06: ; Interrupt routine for irq 6 (floppy)
  182. hwint_master 6
  183. ALIGN 16
  184. hwint07: ; Interrupt routine for irq 7 (printer)
  185. hwint_master 7
  186. ; ---------------------------------
  187. %macro hwint_slave 1
  188. push %1
  189. call spurious_irq
  190. add esp, 4
  191. hlt
  192. %endmacro
  193. ; ---------------------------------
  194. ALIGN 16
  195. hwint08: ; Interrupt routine for irq 8 (realtime clock).
  196. hwint_slave 8
  197. ALIGN 16
  198. hwint09: ; Interrupt routine for irq 9 (irq 2 redirected)
  199. hwint_slave 9
  200. ALIGN 16
  201. hwint10: ; Interrupt routine for irq 10
  202. hwint_slave 10
  203. ALIGN 16
  204. hwint11: ; Interrupt routine for irq 11
  205. hwint_slave 11
  206. ALIGN 16
  207. hwint12: ; Interrupt routine for irq 12
  208. hwint_slave 12
  209. ALIGN 16
  210. hwint13: ; Interrupt routine for irq 13 (FPU exception)
  211. hwint_slave 13
  212. ALIGN 16
  213. hwint14: ; Interrupt routine for irq 14 (AT winchester)
  214. hwint_slave 14
  215. ALIGN 16
  216. hwint15: ; Interrupt routine for irq 15
  217. hwint_slave 15
  218. ; 中断和异常 -- 异常
  219. divide_error:
  220. push 0xFFFFFFFF ; no err code
  221. push 0 ; vector_no = 0
  222. jmp exception
  223. single_step_exception:
  224. push 0xFFFFFFFF ; no err code
  225. push 1 ; vector_no = 1
  226. jmp exception
  227. nmi:
  228. push 0xFFFFFFFF ; no err code
  229. push 2 ; vector_no = 2
  230. jmp exception
  231. breakpoint_exception:
  232. push 0xFFFFFFFF ; no err code
  233. push 3 ; vector_no = 3
  234. jmp exception
  235. overflow:
  236. push 0xFFFFFFFF ; no err code
  237. push 4 ; vector_no = 4
  238. jmp exception
  239. bounds_check:
  240. push 0xFFFFFFFF ; no err code
  241. push 5 ; vector_no = 5
  242. jmp exception
  243. inval_opcode:
  244. push 0xFFFFFFFF ; no err code
  245. push 6 ; vector_no = 6
  246. jmp exception
  247. copr_not_available:
  248. push 0xFFFFFFFF ; no err code
  249. push 7 ; vector_no = 7
  250. jmp exception
  251. double_fault:
  252. push 8 ; vector_no = 8
  253. jmp exception
  254. copr_seg_overrun:
  255. push 0xFFFFFFFF ; no err code
  256. push 9 ; vector_no = 9
  257. jmp exception
  258. inval_tss:
  259. push 10 ; vector_no = A
  260. jmp exception
  261. segment_not_present:
  262. push 11 ; vector_no = B
  263. jmp exception
  264. stack_exception:
  265. push 12 ; vector_no = C
  266. jmp exception
  267. general_protection:
  268. push 13 ; vector_no = D
  269. jmp exception
  270. page_fault:
  271. push 14 ; vector_no = E
  272. jmp exception
  273. copr_error:
  274. push 0xFFFFFFFF ; no err code
  275. push 16 ; vector_no = 10h
  276. jmp exception
  277. exception:
  278. call exception_handler
  279. add esp, 4*2 ; 让栈顶指向 EIP,堆栈中从顶向下依次是:EIP、CS、EFLAGS
  280. hlt
  281. ; ====================================================================================
  282. ; restart
  283. ; ====================================================================================
  284. restart:
  285. mov esp, [p_proc_ready]
  286. lldt [esp + P_LDT_SEL]
  287. lea eax, [esp + P_STACKTOP]
  288. mov dword [tss + TSS3_S_SP0], eax
  289. pop gs
  290. pop fs
  291. pop es
  292. pop ds
  293. popad
  294. add esp, 4
  295. iretd