oranges一个操作系统的实现笔记一

第一部分:实现一个最小的操作系统

oranges一个操作系统的实现笔记一_第1张图片
这部分代码需要注意如下几点:
1.代码需要加载到0x07c00H处的内存上,才能得到有效的执行,这是bios规定的。
2.因为一个扇区是512字节的大小,所以这段bootloader必须占有512字节的大小。
3.整个扇区必须以0xaa55作为结尾。
4.int 10h是显示字符串用的bios中断。

第二部分:保护模式:

org 07c00h
jmp LABEL_BEGIN

[SECTION .gdt]
; GDT
; 段基址, 段界限 , 属性
LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32; 非一致代码段
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ; 显存首地址
; GDT 结束

GdtLen equ $ - LABEL_GDT ; GDT长度
GdtPtr dw GdtLen - 1 ; GDT界限
dd 0 ; GDT基地址

; GDT 选择子
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
; END of [SECTION .gdt]

[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0100h

; 初始化 32 位代码段描述符
xor	eax, eax
mov	ax, cs
shl	eax, 4
add	eax, LABEL_SEG_CODE32
mov	word [LABEL_DESC_CODE32 + 2], ax
shr	eax, 16
mov	byte [LABEL_DESC_CODE32 + 4], al
mov	byte [LABEL_DESC_CODE32 + 7], ah

; 为加载 GDTR 作准备
xor	eax, eax
mov	ax, ds
shl	eax, 4
add	eax, LABEL_GDT		; eax <- gdt 基地址
mov	dword [GdtPtr + 2], eax	; [GdtPtr + 2] <- gdt 基地址

; 加载 GDTR
lgdt	[GdtPtr]

; 关中断
cli

; 打开地址线A20
in	al, 92h
or	al, 00000010b
out	92h, al

; 准备切换到保护模式
mov	eax, cr0
or	eax, 1
mov	cr0, eax

; 真正进入保护模式
jmp	dword SelectorCode32:0	; 执行这一句会把 SelectorCode32 装入 cs,
				; 并跳转到 Code32Selector:0  处

; END of [SECTION .s16]

[SECTION .s32]; 32 位代码段. 由实模式跳入.
[BITS 32]

LABEL_SEG_CODE32:
mov ax, SelectorVideo
mov gs, ax ; 视频段选择子(目的)

mov	edi, (80 * 11 + 79) * 2	; 屏幕第 11 行, 第 79 列。
mov	ah, 0Ch			; 0000: 黑底    1100: 红字
mov	al, 'P'
mov	[gs:edi], ax

; 到此停止
jmp	$

SegCode32Len equ $ - LABEL_SEG_CODE32
; END of [SECTION .s32]

这段代码需要注意的是:
1.GDT这个结构体的结构。把他当做一个不同大小组成的数组来看待可能更容易理解。
2.注意选择子是如何被调用的。
3.注意显存的地址被bios固定在了0B8000h的内存地址上。
4.注意他是如何初始化gdt内存地址里面的值的。
5.进入保护模式的几个步骤:1.初始化gdt和gdtr的值。2.加载gdtr。3,打开地址线A20。4.置位cr0的PE位为1,也就是最末尾的那一位。5.赋予一个32位的地址跳过去。

你可能感兴趣的:(orange一个操作系统的实现)