realmode.asm 982 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. ;; Inspired to https://wiki.osdev.org/Real_Mode
  2. org 0x500
  3. bits 32
  4. ;; Interrupts should already be disabled, but who knows...
  5. cli
  6. ;; Load 16 bit GDT prepared by C code
  7. lgdt [real_gdt]
  8. jmp 0x10:disable_real_mode
  9. bits 16
  10. disable_real_mode:
  11. ;; Load 16 bit data segments
  12. mov ax, 0x18
  13. mov ds, ax
  14. mov es, ax
  15. mov fs, ax
  16. mov gs, ax
  17. mov ss, ax
  18. ;; Disable protected mode (assume that paging is already disabled)
  19. mov eax, cr0
  20. and eax, 0xfffffffe
  21. mov cr0, eax
  22. jmp 0x0:real_mode
  23. real_mode:
  24. ;; Reload segments and stack pointer
  25. mov ax, 0
  26. mov ds, ax
  27. mov es, ax
  28. mov fs, ax
  29. mov gs, ax
  30. mov ss, ax
  31. mov sp, 0xe000
  32. ;; Reload IDT
  33. lidt [real_idt]
  34. ;; Now load segments for Linux booting
  35. mov ax, 0x1000
  36. mov ds, ax
  37. mov es, ax
  38. mov fs, ax
  39. mov gs, ax
  40. mov ss, ax
  41. mov sp, 0xe000
  42. ;; Boot Linux
  43. jmp 0x1020:0x0000
  44. align 4
  45. ;; IDT data
  46. real_idt:
  47. dw 0x3ff
  48. dd 0x00000000
  49. align 4
  50. real_gdt:
  51. dw 31
  52. dd 0x00000800