Guest User

boot

a guest
Feb 8th, 2019
171
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; The Bootloader
  2. ; recommended reading: Ralf Brown's interrupt list, OSDev wiki
  3.  
  4. cpu 686
  5. org 7c00h   ; set all labels relative to 7c00h
  6.             ; great advantage when computing linear address
  7.  
  8. boot: ;the bootloader is loaded at 0000:7c00h
  9. mov ax,0002h ; video mode
  10. int 10h
  11. mov ax,0000h ;flat segments (cs=ds=es=ss)
  12. mov ds,ax   ; ds and es segments may be loaded differently, but not cs
  13. mov es,ax
  14. mov si,0 ;important! set up source and dest
  15. mov di,0
  16.  
  17. [section .bss]
  18. ; The stack grows from HIGH to LOW mem!
  19. ;   [   ] <- sp points to the next free byte
  20. ;   [...]
  21. ;   [...] <- bp points to the current stack frame
  22. ;   etc.
  23. ;   (the stack should be 16-bit aligned for calls to C)
  24. ;
  25. ;   Short info on the cdecl calling convention
  26. ;       called function:
  27. ;       push ebp        ; parameters were pushed onto the stack by the caller
  28. ;       mov ebp,esp     ; bp:=sp, access args with [ebp+8] and upwards
  29. ;       ; do task       ; local variables may be pushed as needed
  30. ;       mov esp,ebp     ; sp:=bp, cleans local variables
  31. ;       pop ebp         ; after returning, the caller will clean the stack
  32. ;       ret
  33. align 4
  34. stack resb 2000h
  35. .end:
  36.  
  37. [section .text]
  38. mov ss,ax ; the stack will be set up again later (after setting up the GDT)
  39. mov sp,stack.end ; stack pointer
  40.  
  41. mov ax,0211h ;ah=02h, al=read n sectors
  42. mov cx,0002h ;track 0, sector 2
  43. mov dx,0000h ;head 0, floppy 0
  44. mov bx,7e00h ;es:bx -> base of output buffer
  45. int 13h ; do it!
  46. mov ah,0eh
  47. mov al,'L'
  48. int 10h
  49.  
  50. ;xchg bx,bx ; bochs magic breakpoint
  51. jmp 0:7e00h ; => jump beyond boot sector
  52.             ; needs to be a far jump to 0:7e00h (linear address)
  53.             ; or (different setup:) load ds with 07c0h, read sectors to 200h and jump to (ds:)200h
  54.  
  55. times 510-($-$$) db 00h ;$='here', $$=beginning of section
  56. dw 0xAA55
  57.  
  58. ;use only in real mode, or a triple fault (hard reset) will occur
  59. %macro bios_printc 1
  60. mov byte al,%1
  61. mov ah,0eh
  62. int 10h
  63. %endmacro
  64. %macro bios_print 1
  65. mov si,%1
  66. .loop lodsb
  67. cmp al,0
  68. je .done
  69. printc al
  70. jmp .loop
  71. .done:
  72. %endmacro
  73. %macro ef 0
  74. push ebp
  75. mov ebp,esp
  76. %endmacro
  77. %macro lf 0
  78. mov esp,ebp
  79. pop ebp
  80. %endmacro
  81.  
  82. ; use these VGA methods only in protected mode
  83. vgai dw 4
  84. %macro putc 1
  85. mov eax,0xb8000
  86. add ax,[vgai]
  87. mov bx,%1
  88. mov [eax],0fh ; white fg, black bg
  89. mov [eax+1],bx
  90. mov ax,[vgai]
  91. mov word [vgai],ax+2
  92. %endmacro
  93.  
  94. loader:
  95. bios_printc '!'
  96. ;xchg bx,bx
  97.  
  98. ; retrieve information
  99.  
  100. ; clear interrupts
  101. cli
  102. jmp setup_gdt
  103.  
  104. ; load gdt
  105. ;   The GDT: a memory array of 8-byte descriptors
  106. ;   Descriptor:
  107. ;       limit_l     lower word of the segment limit
  108. ;       base_l          "   "   of the segment base
  109. ;       base_m      middle byte     "   "
  110. ;       access      bits: 1PPS_TEW0
  111. ;                       Privilege: descriptor privilige level (ring 0-3)
  112. ;                       SegmentDescriptorType: 0 for system, 1 for code/data
  113. ;                       Type: 0 for data segment, 1 for code segment
  114. ;                       (the following bits have different meanings for a data or code segment:)
  115. ;                       - ExpandDown or Conforming: 0 for DS(!), 1 for CS(?)
  116. ;                       - Writable or Readable: 1
  117. ;                       Accessed: set by the CPU on access, leave at 0
  118. ;       limit_h     higher nibble of the limit
  119. ;       flags       bits: GDL0
  120. ;                       Granularity: interpret limit in 1B/4KB
  121. ;                       DefaultSize/UpperBound:
  122. ;                        - for CS/SS: 16/32 bit default operation/stack pointer size
  123. ;                           -> if CS: setting to 1 will cause a mess with opcodes, but enable jmps to 32-bit C code
  124. ;                        - for expand-down DS: limit interpreted as 64KB/4GB
  125. ;                       LongSeg: set if 64-bit segment (only in IA32-e mode)
  126. ;       base_h      higher byte of the base
  127. ;   Selector:
  128. ;       index       13 bits: offset into the table
  129. ;       flags       bits: TPP (Table: look in GDT/LDT, Privilige: Request Privilege Level 0-3 access)
  130. ;                    (-> 0x08=1,0x10=2,0x1b=3,0x23=4,... in GDT with ring 0)
  131. gdt dq 0 ; the initial entry must be zero
  132. ; set up CS
  133. dw 0xFFFF ; limit_l
  134. dw 0x0000 ; base_l
  135. db 0x00 ; base_m
  136. db 1001_1110b ;access (0x9A/0x9E)
  137. db (1100b<<4)|0xF ;flags|limit_h
  138. db 0x00 ;base_h
  139. ; set up DS
  140. dw 0xFFFF
  141. dw 0x0000
  142. db 0x00
  143. db 1001_0010b ;access (0x92)
  144. db (1100b<<4)|0xF
  145. db 0x00
  146. .fin db 0fh
  147. gdtr dw 0000h ; limit (size-1)
  148. dd 0000000h ; base address
  149. ;;; Set up the GDT ;;;
  150. setup_gdt:
  151. mov word [gdtr],(gdt.fin-gdt-1)
  152. mov ax,ds
  153. shl eax,4 ; seg*16+offs = linear address
  154. add eax,gdt
  155. ;xchg bx,bx
  156. mov dword [gdtr+2],eax  ; only the lower EAX register (aka AX) can be accessed in real mode
  157. lgdt [gdtr] ; load the limit+base into the cpu's GDTR register
  158. ;jmp enable_pm
  159.  
  160. ;enable A20
  161. ;mov ax,2401h
  162. ;int 15h
  163.  
  164. ; enter protected mode
  165. ;   In Protected Mode, 32-bit instructions will now work properly
  166. ;   mov eax,[long_value] -> eax=10203040
  167. enable_pm:
  168. mov eax,cr0
  169. or eax,1
  170. mov cr0,eax
  171.  
  172. ; load segment selectors
  173. mov ax,0x10
  174. mov ds,ax
  175. mov es,ax
  176. mov fs,ax
  177. mov gs,ax
  178. ;xchg bx,bx
  179. mov ss,ax
  180. mov sp,stack.end
  181. jmp 0x08:setup_idt  ; 0x08 is the code segment selector
  182.  
  183. bits 32 ; the CS has a 32-bit DefaultSize, so this is necessary!
  184.  
  185. ; load idt
  186. ;   The IDT: a table of 256 8-byte gate descriptors
  187. ;   Gate Descriptor: specifies interrupt/task/trap gate
  188. ;   Interrupt Gate:
  189. ;       offset_l        lower word of the offset to the interrupt handler
  190. ;       selector        (word) segment selector to which to apply the offset
  191. ;       zero            reserved zero byte
  192. ;       type            bits: 1PP0_S110
  193. ;                           Privilege: descriptor privilege level (ring 0-3)
  194. ;                           Size: 16-bit/32-bit gate size
  195. ;       offset_h        higher word of the offset
  196. ;   the gate for INT x is accessed by [idt+8*x]
  197. %define idt_selector 0x08
  198. %define idt_zero 0x00
  199. %define idt_type 1000_1110b
  200. %macro make_int 2
  201. mov eax,%2
  202. mov word [idt+%1*8+0],ax
  203. mov word [idt+%1*8+2],idt_selector
  204. mov byte [idt+%1*8+4],idt_zero
  205. mov byte [idt+%1*8+5],idt_type
  206. shr eax,16
  207. mov word [idt+%1*8+6],ax
  208. %endmacro
  209.  
  210. ; Interrupt Procedures
  211. ;   when the cpu calls an interrupt/exception handling procedure:
  212. ;   - pushed on stack (in this order): EFLAGS, CS, EIP, error code (if exception)
  213. int30handler:
  214. mov eax,0xb8000+4
  215. mov dword [eax],'I ' ; test
  216. iret
  217. nul_handler:
  218. iret
  219. ; The IDT is nested in the loader sectors (to prevent overwriting by the kernel sectors)
  220. idt dq 0 ; int 00h
  221. dq 0 ; int 01h
  222. times 256*8-($-idt) db 0    ; fill to 256 entries
  223. .fin db 0fh
  224. idtr dw 0000h ;limit (size-1)
  225. dd 00000000h ;base
  226. ;;; Set up the IDT ;;;
  227. setup_idt:
  228. ;xchg bx,bx
  229. make_int 08,nul_handler
  230. make_int 14,nul_handler
  231. make_int 30,int30handler
  232. mov word [idtr],(idt.fin-idt-1)
  233. mov dword [idtr+2],idt
  234. lidt [idtr]
  235.  
  236. ; enable interrupts
  237. sti
  238. ;xchg bx,bx
  239. int 30 ; test
  240.  
  241. ; enable A20 ; -> moved before enable_pm
  242. ;...
  243.  
  244. ; jmp to kernel
  245. goto_kernel:
  246. xchg bx,bx
  247. call 0x08:kernel_area   ; jump to the pasted kernel (the floppy track 0 is loaded in memory)
  248.                 ;   7c00h           entry (sector 0)
  249.                 ;   +200h           beginning of this loader (sector 1)
  250.                 ;   +((n-1)*200h)   beginning of kernel (sector n)
  251.                 ;   +x              => the entry method (best at 0x0)
  252. jmp $
  253. times 512*6-($-$$) db 0
  254. kernel_area:
RAW Paste Data