loader.S 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. ; loader
  2. ; 位于硬盘第 2 扇区(LBA 地址)
  3. ; ----------------------------------------------------------------
  4. %include "boot.inc"
  5. SECTION LOADER vstart=LOADER_BASE_ADDR
  6. LOADER_STACK_TOP equ LOADER_BASE_ADDR
  7. jmp loader_start
  8. ; 构建 GDT 及其内部描述符(GDT 的第 0 个描述符不可用)
  9. GDT_BASE: dd 0x00000000
  10. dd 0x00000000
  11. CODE_DESC: dd 0x0000FFFF
  12. dd DESC_CODE_HIGH4
  13. DATA_STACK_DESC: dd 0x0000FFFF
  14. dd DESC_DATA_HIGH4
  15. VIDEO_DESC: dd 0x80000007 ;limit=(0xbffff-0xb8000)/4k=0x7
  16. dd DESC_VIDEO_HIGH4 ;此时 dpl 为 0
  17. GDT_SIZE equ $ - GDT_BASE
  18. GDT_LIMIT equ GDT_SIZE - 1
  19. times 60 dq 0 ; 此处预留 60 个描述符的空位
  20. SELECTOR_CODE equ (0x0001<<3) + TI_GDT + RPL0 ; 相当于 (CODE_DESC - GDT_BASE)/8 + TI_GDT + RPL0
  21. SELECTOR_DATA equ (0x0002<<3) + TI_GDT + RPL0
  22. SELECTOR_VIDEO equ (0x0003<<3) + TI_GDT + RPL0
  23. ; 以下是 gdt 的指针,前 2 个字节是 gdt 界限,后 4 字节是 gdt 起始地址
  24. gdt_ptr dw GDT_LIMIT
  25. dd GDT_BASE
  26. loadermsg db '2 loader in real.'
  27. ;----------------------------------------------------------------
  28. ; INT 0x10 功能号:0x13 功能描述: 打印字符串
  29. ;----------------------------------------------------------------
  30. ; 输入:
  31. ; AH 子功能号 13H
  32. ; BH = 页码
  33. ; BL = 属性(若 AL=00H 或 01H)
  34. ; CX = 字符串长度
  35. ; (DH、DL) = 坐标(行,列)
  36. ; ES:BP = 字符串地址
  37. ; AL=显示输出方式
  38. ; 0 ---- 字符串中只含显示字符,其显示属性在 BL 中,显示后,光标位置不变
  39. ; 1 ---- 字符串中只含显示字符,其显示属性在 BL 中,显示后,光标位置不变
  40. ; 2 ---- 字符串中含显示字符和显示属性。显示后,光标位置不变
  41. ; 3 ---- 字符串中含显示字符和显示属性。显示后,光标位置改变
  42. ; 无返回值
  43. loader_start:
  44. mov sp, LOADER_BASE_ADDR
  45. mov bp, loadermsg ; ES:BP = 字符串地址
  46. mov cx, 17 ; CX = 字符串长度
  47. mov ax, 0x1301 ; AH = 13h, AL = 01h
  48. mov bx ,0x001f ; 页号 0(BH=0)蓝底粉红色(BL=1fh)
  49. mov dx, 0x1800 ; 坐标(行,列)
  50. int 0x10 ; 10h 号中断
  51. ;---------------------- 准备进入保护模式 ------------------------------------------
  52. ; 1 打开 A20
  53. ; 2 加载 GDT
  54. ; 3 将 cr0 的 pe 位置 1
  55. ;-------------------------- 打开 A20 --------------------------------
  56. in al, 0x92
  57. or al, 0000_0010b
  58. out 0x92, al
  59. ;-------------------------- 加载 GDT --------------------------------
  60. lgdt [gdt_ptr]
  61. ;-------------------------- cr0 第 0 位置 1 --------------------------
  62. mov eax, cr0
  63. or eax, 0x00000001
  64. mov cr0, eax
  65. jmp dword SELECTOR_CODE:p_mode_start ; 刷新流水线
  66. [bits 32]
  67. p_mode_start:
  68. mov ax, SELECTOR_DATA
  69. mov ds, ax
  70. mov es, ax
  71. mov ss, ax
  72. mov esp, LOADER_STACK_TOP
  73. mov ax, SELECTOR_VIDEO
  74. mov gs, ax
  75. mov byte [gs:160], 'P'
  76. jmp $