boot.s 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. .section .stage1
  2. .code32
  3. .globl start_32bit
  4. start_32bit:
  5. mov $0x10, %ax
  6. mov %ax, %ds
  7. mov %ax, %es
  8. mov %ax, %fs
  9. mov %ax, %gs
  10. mov %ax, %ss
  11. cld
  12. xor %eax, %eax
  13. # clear paging structures
  14. mov $0x100000, %edi
  15. mov %edi, %ecx
  16. shr $2, %ecx # %ecx /= 4
  17. rep stosl
  18. # set P, RW, G
  19. mov $0x00000103, %ebx
  20. xor %edx, %edx
  21. mov $0x00101000, %esi
  22. # PML4E 0x000
  23. # we need the first 1GB identically mapped
  24. # so that we won't trigger a triple fault after
  25. # enabling paging
  26. lea -0x1000(%esi), %edi # %edi = 0x100000
  27. call fill_pxe
  28. # PML4E 0xff0
  29. mov $0x80000000, %edx
  30. lea 0xff0(%edi), %edi
  31. call fill_pxe
  32. xor %edx, %edx
  33. # setup PDPT for physical memory mapping
  34. mov %esi, %edi
  35. # set PS
  36. or $0x00000080, %ebx
  37. mov $256, %ecx
  38. xor %esi, %esi
  39. _fill_loop1:
  40. call fill_pxe
  41. lea 8(%edi), %edi
  42. add $0x40000000, %esi # 1GB
  43. adc $0, %edx
  44. loop _fill_loop1
  45. mov $0x80000000, %edx
  46. # set PCD, PWT
  47. or $0x00000018, %ebx
  48. mov $256, %ecx
  49. xor %esi, %esi
  50. _fill_loop2:
  51. call fill_pxe
  52. lea 8(%edi), %edi
  53. add $0x40000000, %esi # 1GB
  54. adc $0, %edx
  55. loop _fill_loop2
  56. xor %edx, %edx
  57. # PML4E 0xff8
  58. mov %edi, %esi # 0x102000
  59. mov $0x100ff8, %edi
  60. # clear PCD, PWT, PS
  61. and $(~0x00000098), %ebx
  62. call fill_pxe
  63. # PDPTE 0xff8
  64. lea 0xff8(%esi), %edi # 0x102ff8
  65. lea 0x1000(%esi), %esi # 0x103000
  66. call fill_pxe
  67. # PDE 0xff0
  68. lea 0xff0(%esi), %edi # 0x103ff0
  69. lea 0x1000(%esi), %esi # 0x104000
  70. call fill_pxe
  71. # fill PT (kernel image)
  72. mov %esi, %edi # 0x104000
  73. mov $0x2000, %esi
  74. .extern KERNEL_PAGES
  75. mov $KIMAGE_PAGES, %ecx
  76. _fill_loop3:
  77. call fill_pxe
  78. lea 8(%edi), %edi
  79. lea 0x1000(%esi), %esi
  80. loop _fill_loop3
  81. # set msr
  82. mov $0xc0000080, %ecx
  83. rdmsr
  84. or $0x901, %eax # set LME, NXE, SCE
  85. wrmsr
  86. # set cr4
  87. mov %cr4, %eax
  88. or $0xa0, %eax # set PAE, PGE
  89. mov %eax, %cr4
  90. # load new page table
  91. xor %eax, %eax
  92. inc %eax
  93. shl $20, %eax # %eax = 0x100000
  94. mov %eax, %cr3
  95. mov %cr0, %eax
  96. // SET PE, WP, PG
  97. or $0x80010001, %eax
  98. mov %eax, %cr0
  99. # create gdt
  100. xor %eax, %eax # at 0x0000
  101. mov %eax, 0x00(%eax)
  102. mov %eax, 0x04(%eax) # null descriptor
  103. mov %eax, 0x08(%eax) # code segment lower
  104. mov %eax, 0x10(%eax) # data segment lower
  105. mov $0x00209a00, %ecx
  106. mov %ecx, 0x0c(%eax) # code segment higher
  107. mov $0x00009200, %ecx
  108. mov %ecx, 0x14(%eax) # data segment higher
  109. # gdt descriptor
  110. push %eax
  111. push %eax
  112. # pad with a word
  113. mov $0x00170000, %eax
  114. push %eax
  115. lgdt 2(%esp)
  116. add $12, %esp
  117. ljmp $0x08, $_64bit_entry
  118. # %ebx: attribute low
  119. # %edx: attribute high
  120. # %esi: page physical address
  121. # %edi: page x entry address
  122. fill_pxe:
  123. lea (%ebx, %esi, 1), %eax
  124. mov %eax, (%edi)
  125. mov %edx, 4(%edi)
  126. ret
  127. .code64
  128. _64bit_entry:
  129. jmp start_64bit
  130. .section .text.kinit
  131. start_64bit:
  132. # set stack pointer and clear stack bottom
  133. movzw %sp, %rdi
  134. xor %rsp, %rsp
  135. inc %rsp
  136. neg %rsp
  137. shr $40, %rsp
  138. shl $40, %rsp
  139. add %rdi, %rsp
  140. mov %rsp, %rdi
  141. # make stack frame
  142. lea -16(%rsp), %rsp
  143. mov %rsp, %rbp
  144. xor %rax, %rax
  145. mov %rax, (%rsp)
  146. mov %rax, 8(%rsp)
  147. call kernel_init
  148. _64bit_hlt:
  149. cli
  150. hlt
  151. jmp _64bit_hlt