操作系统的引导(三)
来源:互联网 发布:淘宝的人工服务怎么找 编辑:程序博客网 时间:2024/05/05 10:44
再学习了前面那些背景知识后,我们可以继续引导操作系统了。
在《操作系统的引导(二)》一篇中,我们已经通过分区引导程序将文件系统中的引导程序RMOSLDR加载到了内存5000:7C00的地方。现在我们来编写RMOSLDR把操作系统的内核从硬盘加载到内存中。RMOSLDR有两部分,第一部分是实模式汇编语言的部分,而第二部分则是C++的代码。这一节中我们先来编写汇编语言的部分
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; This file is the first part of the RMOSLDR. The mission of this program is
;; To create the running environment of the 2nd part of RMOSLDR which is a 32-
;; bit c++ program. A stack, a flat protected memory model is needed.
;;
;; Remember that in bootstrap, RMOSLDR has been loaded to 0x5000:7c00. Memory
;; Address space 5000:0000 - 5000:FFFF is reserved for this file. And the C++
;; part starts from 6000:0000.
;;
;; This program will do the following things:
;; 1: Get the total size of the memory. We won't be able to do so later in
;; protected mode
;;
;; 2: Setup the GDT. we need a Kernel CS, a Kernel DS, and a Kernel FS. This
;; GDT is temperory for the RMOSLDR. The kernel will re-initialize the virtual
;; Memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
先定义一些常数
;;;;;;;;;;;;;;;;;;;;
; Constants
MemTable EQU 1000h ; Pointer of the memory layout info
AddressRangeMemory EQU 01 ; Memory available
AddressRangeReserved EQU 02 ; Memory reserved
;;;;;;;;;;;;;;;;;;;;
; Directives
.model tiny
.686p
;;;;;;;;;;;;;;;;;;;;
; Begin Code segment
依然是16位模式,并且偏移地址是7C00
_TEXT SEGMENT use16 ; 16-bit code segment
.code
ORG 7c00h ; BootStrap puts us at 5000h:7c00
第一步:初始化各个段寄存器,并把堆栈建立在4000:FFF0处
start:
; Set the segment registers
mov ax, 5000h
mov ds, ax;
mov es, ax;
mov ax, 4000h
mov ss, ax;
mov sp, 0fff0h;
用前面提到的E820功能得到内存大小,把结果放在5000:1000处
; Use E820H of INT 15h to get the available memory
mov eax, 0E820h
mov ebx, 0
mov edi, MemTable;
mov ecx, 20;
mov edx, 'SMAP'
GetMemoryLayout:
int 15h
jc ErrorGetMemoryLayout ;Error
and ebx, ebx
jz EndGetMemoryLayout
add di, 20
mov eax, 0E820h
jmp GetMemoryLayout ;Get next block
最后追加一个全0块作为结束标记(后面的C++代码会用到)
EndGetMemoryLayout:
mov dword ptr es:[di], 0
mov dword ptr es:[di + 4], 0
mov dword ptr es:[di + 8], 0
mov dword ptr es:[di + 12], 0
现在是时候切换入保护模式了,首先要关中断
; We have successfully got the memory layout. now, it's time to prepare to switch to protected mode
cli ; disable interrupt
接下来打开A20
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;A20 shall be enabled next
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Step1:
call Empty8042 ;we must wait until the buffer is empty
mov al,0d1h
out 64h,al
call Empty8042
mov al,0dfh
out 60h,al
call Empty8042
设置全局描述符表,GDT_PTR中存放着描述符表的地址和长度
step2:
lgdt fword ptr [GDT_PTR]
设置段选择子,CS为内核代码段,DS,ES,GS为内核数据段,FS比较特殊,是为VC++的异常准备的
;Set all segment registers
mov ax, 0010h
mov ds, ax
mov es, ax
mov gs, ax
mov ss, ax
mov ax, 0018h
mov fs, ax
设置控制寄存器,把CPU切换到保护模式
mov eax, cr0
or eax, 00000001h
mov cr0, eax
现在跳转到在61000的C++部分
; Jump to the C++ code of RMOSLDR
db 66h, 0eah ; The machine code for jump
dd 61000h
dw 0008h
这个子程序是打开A20门用的,现在看不懂没关系,当我们讲到键盘驱动的时候会再次提到这个8042控制器的
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Routine Empty8042
;This routine will empty the 8042 controller buffer, so that
;we can operate on A20 Gate
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Empty8042 PROC NEAR
dw 00ebh, 00ebh ;delay
in al, 64h ;check the 8042 status register
test al, 2 ;check if the buffer is empty
jnz Empty8042
ret
Empty8042 ENDP
ErrorGetMemoryLayout:
mov si, offset ErrorGetMemoryLayoutMessage
jmp PrintError
PrintError:
mov ah, 0eh
mov al, [si]
or al, al
jz infloop
int 10h
inc si
jmp PrintError
infloop:
jmp infloop
ErrorGetMemoryLayoutMessage:
db "Cannot Get size of system memory", 0dh, 0ah, 0h
这里是描述符表,总共5个描述符
org 9000h
GDT_Table:
dq 00000000000000000h ; 00: NULL segment [NULL_SELECTOR].
dq 000CF9A000000FFFFh ; 08: PM code segment [PM_CODE_SELECTOR].
dq 000CF92000000FFFFh ; 10: PM data segment [PM_DATA_SELECTOR].
dq 000CF92005000FFFFh ; 18: FS segment [PROCESSOR_SELECTOR].
dq 00000000000000000h ; 20 [UNUSED_SELECTOR].
GDT_PTR:
dw 0800h
dw OFFSET GDT_Table , 5h
END start
所有的汇编语言程序到此结束,下面我们就要进入C++的天地了
- 操作系统的引导(三)
- 操作系统的引导(一)
- 操作系统的引导(二)
- 操作系统的引导
- 操作系统内核的引导
- 操作系统引导的学习
- 操作系统的引导
- 操作系统内核Hack:(三)引导程序制作
- 多硬盘操作系统的引导
- 引导操作系统是个很有意思的
- 操作系统的引导与修复
- 实验2 操作系统的引导
- 哈工大操作系统试验1 操作系统的引导
- 恢复Linux和Windows Xp + Vista 三操作系统的引导菜单
- 操作系统引导
- 操作系统引导
- 写操作系统(三)执着 初始引导程序
- 恢复Linux操作系统的GRUB引导程序
- TXSeries CICS
- 7种常见的浪费
- Getting image from wewbsite
- Ice.MemoryLimitException异常解决办法。
- [英语阅读]匈牙利评选最美“整容小姐”
- 操作系统的引导(三)
- 遇上了五百年一遇
- 中美经商之道的差异
- CICS 系统管理
- Dirty pool 不正当手段
- AS3的BASE64编码与解码类
- CICS Client编程
- 在RHEL5上安装 DB2 V9.5
- 禁用VS2005实时调试和恢复方法