/asm/boot/test/kernel.s

http://github.com/dennis-gemini/tests · Assembly · 164 lines · 142 code · 22 blank · 0 comment · 9 complexity · 260e517e9e54ea60d44b98ea0708147c MD5 · raw file

  1. #
  2. # type := [Pr Priv*2 1 Ex DC RW Ac]
  3. #
  4. # Pr := {0: absent, 1: present}
  5. #
  6. # Priv := {0:ring 0 (highest), 1:ring 1, 2:ring 2, 3:ring 3(lowest)}
  7. #
  8. # Ex := {1:exec, 0:data}
  9. #
  10. # DC := direction bit for data {
  11. # 0:grows up,
  12. # 1:grows down (offset >= base)
  13. # }
  14. # confirming bit for code {
  15. # 0: executed with cpl = Priv,
  16. # 1: executed with cpl <= Priv,
  17. # }
  18. #
  19. # RW := readable for code selectors {
  20. # 1: readable (write access is never allowed for code segment)
  21. # }
  22. # writable for data selectors {
  23. # 1: writable (read access is always allowed for data segment)
  24. # }
  25. #
  26. # Ac := {0: initially set, not-accessed, 1: set by CPU if accessed}
  27. #
  28. # flags := [Gr Sz 00 0000]
  29. #
  30. # Gr := {0: 1B, 1: 4K}
  31. #
  32. # Sz := {0: 16bit, 1: 32bit}
  33. #
  34. .macro GDT_ENTRY base, limit, type, flags
  35. .byte ((\limit) >> 0) & 0xff
  36. .byte ((\limit) >> 8) & 0xff
  37. .byte ((\base ) >> 0) & 0xff
  38. .byte ((\base ) >> 8) & 0xff
  39. .byte ((\base ) >> 16) & 0xff
  40. .byte ((\type ) >> 0) & 0xff
  41. .byte ((\limit) >> 16) & 0x0f | ((\flags ) & 0xf0)
  42. .byte ((\base ) >> 24) & 0xff
  43. .endm
  44. .text
  45. .code16
  46. start16:
  47. mov %cs, %ax
  48. mov %ax, %ds
  49. mov %ax, %es
  50. mov %ax, %ss
  51. mov $top_of_stack, %ax
  52. mov %ax, %sp
  53. mov $msg_loader_started, %si
  54. call print
  55. #########################################
  56. # Fast A20 gate
  57. inb $0x92, %al
  58. or $2, %al
  59. outb %al, $0x92
  60. # Use BIOS INT15, 2401
  61. # mov $0x2401, %ax
  62. # int $0x15
  63. # Alternative way to turn on A20
  64. #1: inb $0x64, %al
  65. # testb $0x02, %al
  66. # jnz 1b
  67. #
  68. # movb $0xd1, %al
  69. # outb %al, $0x64
  70. #
  71. #2: inb $0x64, %al
  72. # testb $0x02, %al
  73. # jnz 2b
  74. #
  75. # movb $0xdf, %al
  76. # outb %al, $0x60
  77. #########################################
  78. # Load GDT and IDT
  79. # xor %eax, %eax
  80. # mov %ds, %ax
  81. # shl $4, %eax
  82. # addl $gdt_begin, %eax
  83. # mov %eax, gdt_base
  84. xorw %ax, %ax
  85. movw %ax, %ds
  86. movw %ax, %es
  87. movw %ax, %ss
  88. cli
  89. cld
  90. lidtw idt_desc
  91. lgdtw gdt_desc
  92. #########################################
  93. # Enter protected mode
  94. # for 386
  95. mov %cr0, %eax
  96. or $1, %eax
  97. mov %eax, %cr0
  98. # for 286
  99. # smsw %ax
  100. # or $1, %ax
  101. # lmsw %ax
  102. #########################################
  103. # Align segment registers
  104. ljmpl $0x08, $start32
  105. #########################################
  106. .code32
  107. start32:
  108. mov $0x10, %ax
  109. mov %ax, %ds
  110. mov %ax, %es
  111. mov %ax, %fs
  112. mov %ax, %gs
  113. mov %ax, %ss
  114. movb $'*', %al
  115. movb $0x0C, %ah
  116. # movl $0xb8000, %ebx
  117. # movw %ax, %es: (%ebx)
  118. movl $(80 * 25), %ecx
  119. movl $0xb8000, %edi
  120. cld
  121. repnz
  122. stosw
  123. 1:
  124. nop
  125. jmp 1b
  126. .code16
  127. msg_loader_started: .ascii "Hello, Real Mode!\r\n\0"
  128. stack: .space 1024
  129. top_of_stack:
  130. .balign 4
  131. gdt_begin:
  132. GDT_ENTRY 0x00000000, 0x00000, 0x00, 0x00 #0x00 dummy segment
  133. GDT_ENTRY 0x00000000, 0xfffff, 0x9a, 0xc0 #0x08 code segment
  134. GDT_ENTRY 0x00000000, 0xfffff, 0x92, 0xc0 #0x10 data segment
  135. gdt_end:
  136. gdt_desc:
  137. gdt_len: .word (gdt_end - gdt_begin - 1)
  138. gdt_base:.long gdt_begin
  139. .balign 4
  140. idt_desc:
  141. .word 0
  142. .long 0