| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- ; loader
- ; 位于硬盘第 2 扇区(LBA 地址)
- ; ----------------------------------------------------------------
- %include "boot.inc"
- SECTION LOADER vstart=LOADER_BASE_ADDR
- LOADER_STACK_TOP equ LOADER_BASE_ADDR
- jmp loader_start
- ; 构建 GDT 及其内部描述符(GDT 的第 0 个描述符不可用)
- GDT_BASE: dd 0x00000000
- dd 0x00000000
- CODE_DESC: dd 0x0000FFFF
- dd DESC_CODE_HIGH4
- DATA_STACK_DESC: dd 0x0000FFFF
- dd DESC_DATA_HIGH4
- VIDEO_DESC: dd 0x80000007 ;limit=(0xbffff-0xb8000)/4k=0x7
- dd DESC_VIDEO_HIGH4 ;此时 dpl 为 0
- GDT_SIZE equ $ - GDT_BASE
- GDT_LIMIT equ GDT_SIZE - 1
- times 60 dq 0 ; 此处预留 60 个描述符的空位
- SELECTOR_CODE equ (0x0001<<3) + TI_GDT + RPL0 ; 相当于 (CODE_DESC - GDT_BASE)/8 + TI_GDT + RPL0
- SELECTOR_DATA equ (0x0002<<3) + TI_GDT + RPL0
- SELECTOR_VIDEO equ (0x0003<<3) + TI_GDT + RPL0
- ; 以下是 gdt 的指针,前 2 个字节是 gdt 界限,后 4 字节是 gdt 起始地址
- gdt_ptr dw GDT_LIMIT
- dd GDT_BASE
- loadermsg db '2 loader in real.'
- ;----------------------------------------------------------------
- ; INT 0x10 功能号:0x13 功能描述: 打印字符串
- ;----------------------------------------------------------------
- ; 输入:
- ; AH 子功能号 13H
- ; BH = 页码
- ; BL = 属性(若 AL=00H 或 01H)
- ; CX = 字符串长度
- ; (DH、DL) = 坐标(行,列)
- ; ES:BP = 字符串地址
- ; AL=显示输出方式
- ; 0 ---- 字符串中只含显示字符,其显示属性在 BL 中,显示后,光标位置不变
- ; 1 ---- 字符串中只含显示字符,其显示属性在 BL 中,显示后,光标位置不变
- ; 2 ---- 字符串中含显示字符和显示属性。显示后,光标位置不变
- ; 3 ---- 字符串中含显示字符和显示属性。显示后,光标位置改变
- ; 无返回值
- loader_start:
- mov sp, LOADER_BASE_ADDR
- mov bp, loadermsg ; ES:BP = 字符串地址
- mov cx, 17 ; CX = 字符串长度
- mov ax, 0x1301 ; AH = 13h, AL = 01h
- mov bx ,0x001f ; 页号 0(BH=0)蓝底粉红色(BL=1fh)
- mov dx, 0x1800 ; 坐标(行,列)
- int 0x10 ; 10h 号中断
- ;---------------------- 准备进入保护模式 ------------------------------------------
- ; 1 打开 A20
- ; 2 加载 GDT
- ; 3 将 cr0 的 pe 位置 1
- ;-------------------------- 打开 A20 --------------------------------
- in al, 0x92
- or al, 0000_0010b
- out 0x92, al
- ;-------------------------- 加载 GDT --------------------------------
- lgdt [gdt_ptr]
- ;-------------------------- cr0 第 0 位置 1 --------------------------
- mov eax, cr0
- or eax, 0x00000001
- mov cr0, eax
- jmp dword SELECTOR_CODE:p_mode_start ; 刷新流水线
- [bits 32]
- p_mode_start:
- mov ax, SELECTOR_DATA
- mov ds, ax
- mov es, ax
- mov ss, ax
- mov esp, LOADER_STACK_TOP
- mov ax, SELECTOR_VIDEO
- mov gs, ax
- mov byte [gs:160], 'P'
- jmp $
|