startup.asm 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. ; TODO finish converting this to a text file that looks like the PDF...
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;
  4. ; ASSUMPTIONS:
  5. ;
  6. ; 1. The bottom 64K of memory is ram, and can be used for
  7. ; scratch space by this module.
  8. ;
  9. ; 2. The system has sufficient free usable ram to copy the
  10. ; initial GDT, IDT, and TSS
  11. ;
  12. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  13. ; configuration data - must match with build definition
  14. CS_BASE EQU 0FFFF0000H
  15. ; CS_BASE is the linear address of the segment STARTUP_CODE
  16. ; - this is specified in the build language file
  17. RAM_START EQU 400H
  18. ; RAM_START is the start of free, usable ram in the linear
  19. ; memory space. The GDT, IDT, and initial TSS will be
  20. ; copied above this space, and a small data segment will be
  21. ; discarded at this linear address. The 32-bit word at
  22. ; RAM_START will contain the linear address of the first
  23. ; free byte above the copied tables - this may be useful if
  24. ; a memory manager is used.
  25. TSS_INDEX EQU 10
  26. ; TSS_INDEX is the index of the TSS of the first task to
  27. ; run after startup
  28. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  29. ; ------------------------- STRUCTURES and EQU ---------------
  30. ; structures for system data
  31. ; TSS structure
  32. TASK_STATE STRUC
  33. link DW ?
  34. link_h DW ?
  35. ESP0 DD ?
  36. SS0 DW ?
  37. SS0_h DW ?
  38. ESP1 DD ?
  39. SS1 DW ?
  40. SS1_h DW ?
  41. ESP2 DD ?
  42. SS2 DW ?
  43. SS2_h DW ?
  44. CR3_reg DD ?
  45. EIP_reg DD ?
  46. EFLAGS_regDD ?
  47. EAX_reg DD ?
  48. ECX_reg DD ?
  49. EDX_reg DD ?
  50. EBX_reg DD ?
  51. ESP_reg DD ?
  52. EBP_reg DD ?
  53. ESI_reg DD ?
  54. EDI_reg DD ?
  55. ES_reg DW ?
  56. ES_h DW ?
  57. CS_reg DW ?
  58. CS_h DW ?
  59. SS_reg DW ?
  60. SS_h DW ?
  61. DS_reg DW ?
  62. DS_h DW ?
  63. FS_reg DW ?
  64. FS_h DW ?
  65. GS_reg DW ?
  66. GS_h DW ?
  67. LDT_reg DW ?
  68. LDT_h DW ?
  69. TRAP_reg DW ?
  70. IO_map_baseDW ?
  71. TASK_STATE ENDS
  72. ; basic structure of a descriptor
  73. DESC STRUC
  74. lim_0_15 DW ?
  75. bas_0_15 DW ?
  76. bas_16_23 DB ?
  77. access DB ?
  78. gran DB ?
  79. bas_24_31 DB ?
  80. DESC ENDS
  81. ; structure for use with LGDT and LIDT instructions
  82. TABLE_REG STRUC
  83. table_lim DW ?
  84. table_linearDD ?
  85. TABLE_REG
  86. ENDS
  87. ; offset of GDT and IDT descriptors in builder generated GDT
  88. GDT_DESC_OFF
  89. EQU 1*SIZE(DESC)
  90. IDT_DESC_OFF
  91. EQU 2*SIZE(DESC)
  92. ; equates for building temporary GDT in RAM
  93. LINEAR_SEL
  94. EQU
  95. 1*SIZE (DESC)
  96. LINEAR_PROTO_LO
  97. EQU
  98. 00000FFFFH ; LINEAR_ALIAS
  99. LINEAR_PROTO_HI
  100. EQU
  101. 000CF9200H
  102. ; Protection Enable Bit in CR0
  103. PE_BIT EQU 1B
  104. ; ------------------------------------------------------------
  105. ; ------------------------- DATA SEGMENT----------------------
  106. ; Initially, this data segment starts at linear 0, according
  107. ; to the processor’s power-up state.
  108. STARTUP_DATA
  109. SEGMENT RW
  110. free_mem_linear_base
  111. LABEL
  112. DWORD
  113. TEMP_GDT
  114. LABEL
  115. BYTE ; must be first in segment
  116. TEMP_GDT_NULL_DESC
  117. DESC
  118. <>
  119. TEMP_GDT_LINEAR_DESC DESC
  120. <>
  121. ; scratch areas for LGDT and
  122. LIDT instructions
  123. TEMP_GDT_SCRATCH TABLE_REG
  124. <>
  125. APP_GDT_RAM
  126. TABLE_REG
  127. <>
  128. APP_IDT_RAM
  129. TABLE_REG
  130. <>
  131. ; align end_data
  132. fill
  133. DW
  134. ?
  135. ; last thing in this segment - should be on a dword boundary
  136. end_data
  137. LABEL
  138. BYTE
  139. STARTUP_DATA
  140. ENDS
  141. ; ------------------------------------------------------------
  142. ; ------------------------- CODE SEGMENT----------------------
  143. STARTUP_CODE SEGMENT ER PUBLIC USE16
  144. ; filled in by builder
  145. PUBLIC GDT_EPROM
  146. GDT_EPROM
  147. TABLE_REG
  148. <>
  149. ; filled in by builder
  150. PUBLIC IDT_EPROM
  151. IDT_EPROM
  152. TABLE_REG
  153. <>
  154. ; entry point into startup code - the bootstrap will vector
  155. ; here with a near JMP generated by the builder.
  156. This
  157. ; label must be in the top 64K of linear memory.
  158. PUBLIC
  159. STARTUP
  160. STARTUP:
  161. ; DS,ES address the bottom 64K of flat linear memory
  162. ASSUME DS:STARTUP_DATA, ES:STARTUP_DATA
  163. ; See Figure 9-4
  164. ; load GDTR with temporary GDT
  165. LEA
  166. EBX,TEMP_GDT ; build the TEMP_GDT in low ram,
  167. MOV
  168. DWORD PTR [EBX],0
  169. ; where we can address
  170. MOV
  171. DWORD PTR [EBX]+4,0
  172. MOV
  173. DWORD PTR [EBX]+8, LINEAR_PROTO_LO
  174. MOV
  175. DWORD PTR [EBX]+12, LINEAR_PROTO_HI
  176. MOV
  177. TEMP_GDT_scratch.table_linear,EBX
  178. MOV
  179. TEMP_GDT_scratch.table_lim,15
  180. DB 66H; execute a 32 bit LGDT
  181. LGDT
  182. TEMP_GDT_scratch
  183. ; enter protected mode
  184. MOV
  185. EBX,CR0
  186. OR
  187. EBX,PE_BIT
  188. MOV
  189. CR0,EBX
  190. ; clear prefetch queue
  191. JMP
  192. CLEAR_LABEL
  193. CLEAR_LABEL:
  194. ; make DS and ES address 4G of linear memory
  195. MOV
  196. CX,LINEAR_SEL
  197. MOV
  198. DS,CX
  199. MOV
  200. ES,CX
  201. ; do board specific initialization
  202. ;
  203. ;
  204. ; ......
  205. ;
  206. ; See Figure 9-5
  207. ; copy EPROM GDT to ram at:
  208. ;
  209. RAM_START + size (STARTUP_DATA)
  210. MOV
  211. EAX,RAM_START
  212. ADD
  213. EAX,OFFSET (end_data)
  214. MOV
  215. EBX,RAM_START
  216. MOV
  217. ECX, CS_BASE
  218. ADD
  219. ECX, OFFSET (GDT_EPROM)
  220. MOV
  221. ESI, [ECX].table_linear
  222. MOV
  223. EDI,EAX
  224. MOVZX
  225. ECX, [ECX].table_lim
  226. MOV
  227. APP_GDT_ram[EBX].table_lim,CX
  228. INC
  229. ECX
  230. MOV
  231. EDX,EAX
  232. MOV
  233. APP_GDT_ram[EBX].table_linear,EAX
  234. ADD
  235. EAX,ECX
  236. REP MOVS
  237. BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
  238. ; fixup
  239. GDT base in descriptor
  240. MOV
  241. ECX,EDX
  242. MOV
  243. [EDX].bas_0_15+GDT_DESC_OFF,CX
  244. ROR
  245. ECX,16
  246. ; PAGE 4 TODO remove later.
  247. MOV
  248. [EDX].bas_16_23+GDT_DESC_OFF,CL
  249. [EDX].bas_24_31+GDT_DESC_OFF,CH
  250. ; copy EPROM IDT to ram at:
  251. ; RAM_START+size(STARTUP_DATA)+SIZE (EPROM GDT)
  252. MOV
  253. ECX, CS_BASE
  254. ADD
  255. ECX, OFFSET (IDT_EPROM)
  256. MOV
  257. ESI, [ECX].table_linear
  258. MOV
  259. EDI,EAX
  260. MOVZX
  261. ECX, [ECX].table_lim
  262. MOV
  263. APP_IDT_ram[EBX].table_lim,CX
  264. INC
  265. ECX
  266. MOV
  267. APP_IDT_ram[EBX].table_linear,EAX
  268. MOV
  269. EBX,EAX
  270. ADD
  271. EAX,ECX
  272. REP MOVS
  273. BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
  274. MOV
  275. ROR
  276. MOV
  277. MOV
  278. MOV
  279. LGDT
  280. LIDT
  281. REPMOV
  282. MOV
  283. MOV
  284. MOV
  285. MOV
  286. MOV
  287. ROL
  288. MOV
  289. MOV
  290. LSL
  291. INC
  292. MOV
  293. ADD
  294. MOVS
  295. MOV
  296. ROL
  297. MOV
  298. MOV
  299. ROL
  300. ;save start
  301. MOV
  302. ; fixup IDT pointer in GDT
  303. [EDX].bas_0_15+IDT_DESC_OFF,BX
  304. EBX,16
  305. [EDX].bas_16_23+IDT_DESC_OFF,BL
  306. [EDX].bas_24_31+IDT_DESC_OFF,BH
  307. ; load GDTR and IDTR
  308. EBX,RAM_START
  309. DB
  310. 66H
  311. ; execute a 32 bit LGDT
  312. APP_GDT_ram[EBX]
  313. DB
  314. 66H
  315. ; execute a 32 bit LIDT
  316. APP_IDT_ram[EBX]
  317. ; move the TSS
  318. EDI,EAX
  319. EBX,TSS_INDEX*SIZE(DESC)
  320. ECX,GDT_DESC_OFF ;build linear address for TSS
  321. GS,CX
  322. DH,GS:[EBX].bas_24_31
  323. DL,GS:[EBX].bas_16_23
  324. EDX,16
  325. DX,GS:[EBX].bas_0_15
  326. ESI,EDX
  327. ECX,EBX
  328. ECX
  329. EDX,EAX
  330. EAX,ECX
  331. BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
  332. ; fixup TSS pointer
  333. GS:[EBX].bas_0_15,DX
  334. EDX,16
  335. GS:[EBX].bas_24_31,DH
  336. GS:[EBX].bas_16_23,DL
  337. EDX,16
  338. of free ram at linear location RAMSTART
  339. free_mem_linear_base+RAM_START,EAX
  340. ;assume no LDT used in the initial task - if necessary,
  341. ;code to move the LDT could be added, and should resemble
  342. ;that used to move the TSS
  343. ; load task register
  344. LTR
  345. BX
  346. ; No task switch, only descriptor loading
  347. ; See Figure 9-6
  348. ; load minimal set of registers necessary to simulate task
  349. ; switch
  350. MOV
  351. AX,[EDX].SS_reg
  352. ; start loading registers
  353. MOV
  354. EDI,[EDX].ESP_reg
  355. MOV
  356. SS,AX
  357. MOV
  358. ESP,EDI
  359. ; stack now valid
  360. PUSH
  361. DWORD PTR [EDX].EFLAGS_reg
  362. PUSH
  363. DWORD PTR [EDX].CS_reg
  364. PUSH
  365. DWORD PTR [EDX].EIP_reg
  366. MOV
  367. AX,[EDX].DS_reg
  368. MOV
  369. BX,[EDX].ES_reg
  370. MOV
  371. DS,AX
  372. ; DS and ES no longer linear memory
  373. MOV
  374. ES,BX
  375. ; simulate far jump to initial task
  376. IRETD
  377. STARTUP_CODE ENDS
  378. END STARTUP, DS:STARTUP_DATA, SS:STARTUP_DATA