Advertisement
Guest User

Untitled

a guest
Mar 26th, 2013
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.13 KB | None | 0 0
  1. SYSSIZE=0x8000
  2. |
  3. | boot.s
  4. |
  5. | boot.s is loaded at 0x7c00 by the bios-startup routines, and moves itself
  6. | out of the way to address 0x90000, and jumps there.
  7. |
  8. | It then loads the system at 0x10000, using BIOS interrupts. Thereafter
  9. | it disables all interrupts, moves the system down to 0x0000, changes
  10. | to protected mode, and calls the start of system. System then must
  11. | RE-initialize the protected mode in it's own tables, and enable
  12. | interrupts as needed.
  13. |
  14. | NOTE! currently system is at most 8*65536 bytes long. This should be no
  15. | problem, even in the future. I want to keep it simple. This 512 kB
  16. | kernel size should be enough - in fact more would mean we'd have to move
  17. | not just these start-up routines, but also do something about the cache-
  18. | memory (block IO devices). The area left over in the lower 640 kB is meant
  19. | for these. No other memory is assumed to be "physical", i.e. all memory
  20. | over 1Mb is demand-paging. All addresses under 1Mb are guaranteed to match
  21. | their physical addresses.
  22. |
  23. | NOTE1 above is no longer valid in it's entirety. cache-memory is allocated
  24. | above the 1Mb mark as well as below. Otherwise it is mainly correct.
  25. |
  26. | NOTE 2! The boot disk type must be set at compile-time, by setting
  27. | the following equ. Having the boot-up procedure hunt for the right
  28. | disk type is severe brain-damage.
  29. | The loader has been made as simple as possible (had to, to get it
  30. | in 512 bytes with the code to move to protected mode), and continuous
  31. | read errors will result in a unbreakable loop. Reboot by hand. It
  32. | loads pretty fast by getting whole sectors at a time whenever possible.
  33.  
  34. | 1.44Mb disks:
  35. sectors = 18
  36. | 1.2Mb disks:
  37. | sectors = 15
  38. | 720kB disks:
  39. | sectors = 9
  40.  
  41. .globl begtext, begdata, begbss, endtext, enddata, endbss
  42. .text
  43. begtext:
  44. .data
  45. begdata:
  46. .bss
  47. begbss:
  48. .text
  49.  
  50. BOOTSEG = 0x07c0
  51. INITSEG = 0x9000
  52. SYSSEG = 0x1000 | system loaded at 0x10000 (65536).
  53. ENDSEG = SYSSEG + SYSSIZE
  54.  
  55. entry start
  56. start:
  57. mov ax,#BOOTSEG
  58. mov ds,ax
  59. mov ax,#INITSEG
  60. mov es,ax
  61. mov cx,#256
  62. sub si,si
  63. sub di,di
  64. rep
  65. movw
  66. jmpi go,INITSEG
  67. go: mov ax,cs
  68. mov ds,ax
  69. mov es,ax
  70. mov ss,ax
  71. mov sp,#0x400 | arbitrary value >>512
  72.  
  73. mov ah,#0x03 | read cursor pos
  74. xor bh,bh
  75. int 0x10
  76.  
  77. mov cx,#24
  78. mov bx,#0x0007 | page 0, attribute 7 (normal)
  79. mov bp,#msg1
  80. mov ax,#0x1301 | write string, move cursor
  81. int 0x10
  82.  
  83. | ok, we've written the message, now
  84. | we want to load the system (at 0x10000)
  85.  
  86. mov ax,#SYSSEG
  87. mov es,ax | segment of 0x010000
  88. call read_it
  89. call kill_motor
  90.  
  91. | if the read went well we get current cursor position ans save it for
  92. | posterity.
  93.  
  94. mov ah,#0x03 | read cursor pos
  95. xor bh,bh
  96. int 0x10 | save it in known place, con_init fetches
  97. mov [510],dx | it from 0x90510.
  98.  
  99. | now we want to move to protected mode ...
  100.  
  101. cli | no interrupts allowed !
  102.  
  103. | first we move the system to it's rightful place
  104.  
  105. mov ax,#0x0000
  106. cld | 'direction'=0, movs moves forward
  107. do_move:
  108. mov es,ax | destination segment
  109. add ax,#0x1000
  110. cmp ax,#0x9000
  111. jz end_move
  112. mov ds,ax | source segment
  113. sub di,di
  114. sub si,si
  115. mov cx,#0x8000
  116. rep
  117. movsw
  118. j do_move
  119.  
  120. | then we load the segment descriptors
  121.  
  122. end_move:
  123.  
  124. mov ax,cs | right, forgot this at first. didn't work :-)
  125. mov ds,ax
  126. lidt idt_48 | load idt with 0,0
  127. lgdt gdt_48 | load gdt with whatever appropriate
  128.  
  129. | that was painless, now we enable A20
  130.  
  131. call empty_8042
  132. mov al,#0xD1 | command write
  133. out #0x64,al
  134. call empty_8042
  135. mov al,#0xDF | A20 on
  136. out #0x60,al
  137. call empty_8042
  138.  
  139. | well, that went ok, I hope. Now we have to reprogram the interrupts :-(
  140. | we put them right after the intel-reserved hardware interrupts, at
  141. | int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
  142. | messed this up with the original PC, and they haven't been able to
  143. | rectify it afterwards. Thus the BIOS puts interrupts at 0x08-0x0f,
  144. | which is used for the internal hardware interrupts as well. We just
  145. | have to reprogram the 8259's, and it isn't fun.
  146.  
  147. mov al,#0x11 | initialization sequence
  148. out #0x20,al | send it to 8259A-1
  149. .word 0x00eb,0x00eb | jmp $+2, jmp $+2
  150. out #0xA0,al | and to 8259A-2
  151. .word 0x00eb,0x00eb
  152. mov al,#0x20 | start of hardware int's (0x20)
  153. out #0x21,al
  154. .word 0x00eb,0x00eb
  155. mov al,#0x28 | start of hardware int's 2 (0x28)
  156. out #0xA1,al
  157. .word 0x00eb,0x00eb
  158. mov al,#0x04 | 8259-1 is master
  159. out #0x21,al
  160. .word 0x00eb,0x00eb
  161. mov al,#0x02 | 8259-2 is slave
  162. out #0xA1,al
  163. .word 0x00eb,0x00eb
  164. mov al,#0x01 | 8086 mode for both
  165. out #0x21,al
  166. .word 0x00eb,0x00eb
  167. out #0xA1,al
  168. .word 0x00eb,0x00eb
  169. mov al,#0xFF | mask off all interrupts for now
  170. out #0x21,al
  171. .word 0x00eb,0x00eb
  172. out #0xA1,al
  173.  
  174. | well, that certainly wasn't fun :-(. Hopefully it works, and we don't
  175. | need no steenking BIOS anyway (except for the initial loading :-).
  176. | The BIOS-routine wants lots of unnecessary data, and it's less
  177. | "interesting" anyway. This is how REAL programmers do it.
  178. |
  179. | Well, now's the time to actually move into protected mode. To make
  180. | things as simple as possible, we do no register set-up or anything,
  181. | we let the gnu-compiled 32-bit programs do that. We just jump to
  182. | absolute address 0x00000, in 32-bit protected mode.
  183.  
  184. mov ax,#0x0001 | protected mode (PE) bit
  185. lmsw ax | This is it!
  186. jmpi 0,8 | jmp offset 0 of segment 8 (cs)
  187.  
  188. | This routine checks that the keyboard command queue is empty
  189. | No timeout is used - if this hangs there is something wrong with
  190. | the machine, and we probably couldn't proceed anyway.
  191. empty_8042:
  192. .word 0x00eb,0x00eb
  193. in al,#0x64 | 8042 status port
  194. test al,#2 | is input buffer full?
  195. jnz empty_8042 | yes - loop
  196. ret
  197.  
  198. | This routine loads the system at address 0x10000, making sure
  199. | no 64kB boundaries are crossed. We try to load it as fast as
  200. | possible, loading whole tracks whenever we can.
  201. |
  202. | in: es - starting address segment (normally 0x1000)
  203. |
  204. | This routine has to be recompiled to fit another drive type,
  205. | just change the "sectors" variable at the start of the file
  206. | (originally 18, for a 1.44Mb drive)
  207. |
  208. sread: .word 1 | sectors read of current track
  209. head: .word 0 | current head
  210. track: .word 0 | current track
  211. read_it:
  212. mov ax,es
  213. test ax,#0x0fff
  214. die: jne die | es must be at 64kB boundary
  215. xor bx,bx | bx is starting address within segment
  216. rp_read:
  217. mov ax,es
  218. cmp ax,#ENDSEG | have we loaded all yet?
  219. jb ok1_read
  220. ret
  221. ok1_read:
  222. mov ax,#sectors
  223. sub ax,sread
  224. mov cx,ax
  225. shl cx,#9
  226. add cx,bx
  227. jnc ok2_read
  228. je ok2_read
  229. xor ax,ax
  230. sub ax,bx
  231. shr ax,#9
  232. ok2_read:
  233. call read_track
  234. mov cx,ax
  235. add ax,sread
  236. cmp ax,#sectors
  237. jne ok3_read
  238. mov ax,#1
  239. sub ax,head
  240. jne ok4_read
  241. inc track
  242. ok4_read:
  243. mov head,ax
  244. xor ax,ax
  245. ok3_read:
  246. mov sread,ax
  247. shl cx,#9
  248. add bx,cx
  249. jnc rp_read
  250. mov ax,es
  251. add ax,#0x1000
  252. mov es,ax
  253. xor bx,bx
  254. jmp rp_read
  255.  
  256. read_track:
  257. push ax
  258. push bx
  259. push cx
  260. push dx
  261. mov dx,track
  262. mov cx,sread
  263. inc cx
  264. mov ch,dl
  265. mov dx,head
  266. mov dh,dl
  267. mov dl,#0
  268. and dx,#0x0100
  269. mov ah,#2
  270. int 0x13
  271. jc bad_rt
  272. pop dx
  273. pop cx
  274. pop bx
  275. pop ax
  276. ret
  277. bad_rt: mov ax,#0
  278. mov dx,#0
  279. int 0x13
  280. pop dx
  281. pop cx
  282. pop bx
  283. pop ax
  284. jmp read_track
  285.  
  286. /*
  287. * This procedure turns off the floppy drive motor, so
  288. * that we enter the kernel in a known state, and
  289. * don't have to worry about it later.
  290. */
  291. kill_motor:
  292. push dx
  293. mov dx,#0x3f2
  294. mov al,#0
  295. outb
  296. pop dx
  297. ret
  298.  
  299. gdt:
  300. .word 0,0,0,0 | dummy
  301.  
  302. .word 0x07FF | 8Mb - limit=2047 (2048*4096=8Mb)
  303. .word 0x0000 | base address=0
  304. .word 0x9A00 | code read/exec
  305. .word 0x00C0 | granularity=4096, 386
  306.  
  307. .word 0x07FF | 8Mb - limit=2047 (2048*4096=8Mb)
  308. .word 0x0000 | base address=0
  309. .word 0x9200 | data read/write
  310. .word 0x00C0 | granularity=4096, 386
  311.  
  312. idt_48:
  313. .word 0 | idt limit=0
  314. .word 0,0 | idt base=0L
  315.  
  316. gdt_48:
  317. .word 0x800 | gdt limit=2048, 256 GDT entries
  318. .word gdt,0x9 | gdt base = 0X9xxxx
  319.  
  320. msg1:
  321. .byte 13,10
  322. .ascii "Loading system ..."
  323. .byte 13,10,13,10
  324.  
  325. .text
  326. endtext:
  327. .data
  328. enddata:
  329. .bss
  330. endbss:
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement