第四章 进入保护模式,理论的抽象轰炸
写在前面
今天已经来到了9日,因为昨日状态不是很好,没有在往下进行,而是把前今天的内容做成博客发表上来,也是给自己一个复习的机会。今天争取拿下第四章!
进入正文
咱们还是先简单翻过前面的理论知识,记住里面的一些名词和简单概念,然后直接来到实战部分。前面说了,不要忘记主线任务,咱们之前已经完成了loader的基本实现,但是这一切都建立在实模式之下,我们需要进入保护模式。
mbr.S
首先是修改了MBR,
| mov cx, 1 call rd_disk_m_16
修改后代码
mov cx, 4 call rd_disk_m_16
|
boot.inc
然后对boot.inc进行一个补充,配置好loader以便后面在loader中进入保护模式。这里贴上boot.inc的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
LOADER_BASE_ADDR equ 0x900 LOADER_START_SECTOR equ 0x2
DESC_G_4K equ 1000_0000_0000_0000_0000_0000b
DESC_D_32 equ 1_00_0000_0000_0000_0000_0000b
DESC_L equ 0_0000_0000_0000_0000_0000_0000b
DESC_AVL equ 0_0000_0000_0000_0000_0000b DESC_LIMIT_CODE2 equ 1111_0000_0000_0000_0000b
DESC_LIMIT_DATA2 equ DESC_LIMIT_CODE2 DESC_LIMIT_VIDEO2 equ 0000_0000_0000_0000_0000b DESC_P equ 1_000_0000_0000_0000b DESC_DPL_0 equ 00_0_0000_0000_0000b DESC_DPL_1 equ 01_0_0000_0000_0000b DESC_DPL_2 equ 10_0_0000_0000_0000b DESC_DPL_3 equ 11_0_0000_0000_0000b DESC_S_CODE equ 1_0000_0000_0000b DESC_S_DATA equ DESC_S_CODE DESC_S_sys equ 0_0000_0000_0000b DESC_TYPE_CODE equ 1000_0000_0000b
DESC_TYPE_DATA equ 0010_0000_0000b
DESC_CODE_HIGH4 equ (0x00 << 24) + DESC_G_4K + DESC_D_32 + \ DESC_L + DESC_AVL + DESC_LIMIT_CODE2 + \ DESC_P + DESC_DPL_0 + DESC_S_CODE +\ DESC_TYPE_CODE + 0x00
DESC_DATA_HIGH4 equ (0x00 << 24) + DESC_G_4K + DESC_D_32 +\ DESC_L + DESC_AVL + DESC_LIMIT_DATA2 + \ DESC_P + DESC_DPL_0 + DESC_S_DATA + \ DESC_TYPE_DATA + 0x00
DESC_VIDEO_HIGH4 equ (0x00 << 24) + DESC_G_4K + DESC_D_32 +\ DESC_L + DESC_AVL + DESC_LIMIT_CODE2 + DESC_P + \ DESC_DPL_0 + DESC_S_DATA + DESC_TYPE_DATA + 0x0B
RPL0 equ 00b RPL1 equ 01b RPL2 equ 10b RPL3 equ 11b TI_GDT equ 000b TI_LDT equ 100b
|
注释比较详细了,注意这里都是以宏的形式编写的,说白了就是给nasm编译器看的,我觉得这里只需了解其背后隐含的理论就好,不必过于纠结代码形式。
loader.S
然后就要上正菜了,改一下loader。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| %include "boot.inc" section loader vstart=LOADER_BASE_ADDR LOADER_STACK_TOP equ LOADER_BASE_ADDR jmp loader_start
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 dd DESC_VIDEO_HIGH4 GDT_SIZE equ $ - GDT_BASE GDT_LIMIT equ GDT_SIZE - 1 times 60 dq 0
SELECTOR_CODE equ (0x0001 << 3) + TI_GDT + RPL0
SELECTOR_DATA equ (0x0002<< 3) + TI_GDT + RPL0 SELECTOR_VIDEO equ (0x0003 << 3) + TI_GDT + RPL0
gdt_ptr dw GDT_LIMIT dd GDT_BASE
loadermsg db '2 loader in real.'
loader_start:
mov sp, LOADER_BASE_ADDR mov bp, loadermsg mov cx, 17 mov ax, 0x1301 mov bx, 0x001f mov dx, 0x1800 int 0x10
in al,0x92 or al, 0000_0010B out 0x92,al
lgdt [gdt_ptr ]
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:0xA0], 'P' jmp $
|
然后编译运行,输入info gdt发现gdt顺利加载成功了。
写在后面
这一章真是遇到了很大的阻力,需要静下心来一行行地啃汇编代码,同时还需要不断学习理论知识,现在已经是9日的21点了,虽然代码过了一遍但还是有许多模棱两可的地方,随着后面章节的进行还是需要回看。