IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 一个操作系统的实现4——Loader -> 正文阅读

[系统运维]一个操作系统的实现4——Loader

一个操作系统的实现4——Loader

loader.asm

org	10000h
	jmp	Della_Start
%include	"Fat12.inc"
BaseOfKernelFile	equ	0x00
OffsetOfKernelFile	equ	0x100000		;1048576=1024*1024

BaseTempOfKernelAddr	equ	0x00
OffsetTempOfKernelFile	equ	0x7E00

MemoryStructBufferAddr	equ	0x7E00

RootDirSizeForLoop	dw	RootDirSectors
SectorNo		dw	0
Odd			db	0

DisplayPosition		dd	0

LoaderMessage:		db	"Della Loader"
NoKernelMessage:	db	"No kernel!"
HasKernelMessage:	db	"Has kernel"

StartGetMemStructMessage:	db	"Start Get Memory Struct."
GetMemStructErrMessage:	db	"Get Memory Struct ERROR"
GetMemStructOKMessage:	db	"Get Memory Struct SUCCESSFUL!"

StartGetSVGAVBEInfoMessage:	db	"Start Get SVGA VBE Info"
GetSVGAVBEInfoErrMessage:	db	"Get SVGA VBE Info ERROR"
GetSVGAVBEInfoOKMessage:	db	"Get SVGA VBE Info SUCCESSFUL!"

StartGetSVGAModeInfoMessage:	db	"Start Get SVGA Mode Info"
GetSVGAModeInfoErrMessage:	db	"Get SVGA Mode Info ERROR"
GetSVGAModeInfoOKMessage:	db	"Get SVGA Mode Info SUCCESSFUL!"
ProtectModeMessage	db	"Protect Mode Ready!"
KernelFileName:	db	"KERNEL  BIN",0

OffsetOfKernelFileCount	dd	OffsetOfKernelFile

[SECTION gdt]			;保护模式数据结构

LABEL_GDT:		dd	0,0
LABEL_DESC_CODE32:	dd	0x0000FFFF,0x00CF9A00
LABEL_DESC_DATA32:	dd	0x0000FFFF,0x00CF9200

GdtLen	equ	$ - LABEL_GDT
GdtPtr	dw	GdtLen - 1
	dd	LABEL_GDT

SelectorCode32	equ	LABEL_DESC_CODE32 - LABEL_GDT
SelectorData32	equ	LABEL_DESC_DATA32 - LABEL_GDT

[SECTION gdt64]

LABEL_GDT64:		dq	0x0000000000000000
LABEL_DESC_CODE64:	dq	0x0020980000000000
LABEL_DESC_DATA64:	dq	0x0000920000000000

GdtLen64	equ	$ - LABEL_GDT64
GdtPtr64	dw	GdtLen64 - 1
		dd	LABEL_GDT64

SelectorCode64	equ	LABEL_DESC_CODE64 - LABEL_GDT64
SelectorData64	equ	LABEL_DESC_DATA64 - LABEL_GDT64

[SECTION .s16]
[BITS 16]

Della_Start:
	;重置寄存器
	mov	ax,	cs
	mov	ds,	ax
	mov	es,	ax
	mov	ax,	0x00
	mov	ss,	ax
	mov	sp,	0x7c00
	;打印字符串
	mov	ax,	1301h
	mov	bx,	000fh
	mov	dx,	0000h
	mov	cx,	12
	mov	bp,	LoaderMessage
	int	10h
	;打开A20地址线
	push	ax
	in	al,	92h
	or	al,	00000010b
	out	92h,	al
	pop	ax
	;初始化保护模式数据结构
	cli				;禁止中断
	db	0x66
	lgdt	[GdtPtr]	

	mov	eax,	cr0
	or	eax,	1
	mov	cr0,	eax

	mov	ax,	SelectorData32
	mov	fs,	ax
	mov	eax,	cr0
	and	al,	11111110b
	mov	cr0,	eax
	sti				;允许中断

	;软驱复位
	xor	ah,	ah
	xor	dl,	dl
	int	13h

;寻找kernel.bin
	mov	word	[SectorNo],	SectorNumOfRootDirStart
;遍历目录
Search_In_Root_Dir:
	cmp	word	[RootDirSizeForLoop],	0
	jz	No_Kernel
	dec	word	[RootDirSizeForLoop]	
	mov	ax,	00h
	mov	es,	ax
	mov	bx,	8000h
	mov	ax,	[SectorNo]
	mov	cl,	1
	call	ReadSector
	mov	si,	KernelFileName
	mov	di,	8000h
	cld
	mov	dx,	10h
;查找kernel
Search_Kernel:
	cmp	dx,	0
	jz	Next_Sector_In_Root_Dir
	dec	dx
	mov	cx,	11
;比较文件名
Compare_FileName:
	cmp	cx,	0
	jz	Has_Loader
	dec	cx
	lodsb	
	cmp	al,	byte	[es:di]
	jz	Go_On
	jmp	FileName_Different
Go_On:
	inc	di
	jmp	Compare_FileName
FileName_Different:
	and	di,	0FFE0h
	add	di,	20h
	mov	si,	KernelFileName
	jmp	Search_Kernel
Next_Sector_In_Root_Dir:
	add	word	[SectorNo],	1
	jmp	Search_In_Root_Dir
;kernel未找到
No_Kernel:
	mov	ax,	1301h
	mov	bx,	008Ch
	mov	dx,	0300h		;row 3
	mov	cx,	10
	push	ax
	mov	ax,	ds
	mov	es,	ax
	pop	ax
	mov	bp,	NoKernelMessage
	int	10h
	jmp	$
;找到了kernel
Has_Loader:
	mov	ax,	RootDirSectors
	and	di,	0FFE0h
	add	di,	01Ah
	mov	cx,	word	[es:di]
	push	cx
	add	cx,	ax
	add	cx,	SectorBalance
	mov	eax,	BaseTempOfKernelAddr	;BaseOfKernelFile
	mov	es,	eax
	mov	bx,	OffsetTempOfKernelFile	;OffsetOfKernelFile
	mov	ax,	cx
On_Loading:
	push	ax
	push	bx
	mov	ah,	0Eh
	mov	al,	'.'
	mov	bl,	0Fh
	int	10h
	pop	bx
	pop	ax

	mov	cl,	1
	call	ReadSector
	pop	ax
	push	cx
	push	eax
	push	fs
	push	edi
	push	ds
	push	esi

	mov	cx,	200h
	mov	ax,	BaseOfKernelFile
	mov	fs,	ax
	mov	edi,	dword	[OffsetOfKernelFileCount]

	mov	ax,	BaseTempOfKernelAddr
	mov	ds,	ax
	mov	esi,	OffsetTempOfKernelFile
;移动内核
Mov_Kernel:
	
	mov	al,	byte	[ds:esi]
	mov	byte	[fs:edi],	al

	inc	esi
	inc	edi

	loop	Mov_Kernel

	mov	eax,	0x1000
	mov	ds,	eax

	mov	dword	[OffsetOfKernelFileCount],	edi

	pop	esi
	pop	ds
	pop	edi
	pop	fs
	pop	eax
	pop	cx

	call	FATEntry
	cmp	ax,	0FFFh
	jz	On_Loaded
	push	ax
	mov	dx,	RootDirSectors
	add	ax,	dx
	add	ax,	SectorBalance

	jmp	On_Loading
On_Loaded:
	mov	ax, 0B800h
	mov	gs, ax
	mov	ah, 0Fh
	mov	al, 'D'
	mov	[gs:((80 * 0 + 39) * 2)], ax
;关闭软驱
KillMotor:
	
	push	dx
	mov	dx,	03F2h
	mov	al,	0	
	out	dx,	al
	pop	dx
	;开始获取内存信息
	mov	ax,	1301h
	mov	bx,	000Fh
	mov	dx,	0400h		;row 4
	mov	cx,	24
	push	ax
	mov	ax,	ds
	mov	es,	ax
	pop	ax
	mov	bp,	StartGetMemStructMessage
	int	10h

	mov	ebx,	0
	mov	ax,	0x00
	mov	es,	ax
	mov	di,	MemoryStructBufferAddr	
;内存结构
Mem_Struct:
	mov	eax,	0x0E820
	mov	ecx,	20
	mov	edx,	0x534D4150
	int	15h
	jc	Mem_Fail
	add	di,	20

	cmp	ebx,	0
	jne	Mem_Struct
	jmp	Mem_Loaded
;获取内存信息完失败
Mem_Fail:
	mov	ax,	1301h
	mov	bx,	008Ch
	mov	dx,	0500h		;row 5
	mov	cx,	23
	push	ax
	mov	ax,	ds
	mov	es,	ax
	pop	ax
	mov	bp,	GetMemStructErrMessage
	int	10h
	jmp	$
;获取内存信息完毕
Mem_Loaded:
	mov	ax,	1301h
	mov	bx,	000Fh
	mov	dx,	0600h		;row 6
	mov	cx,	29
	push	ax
	mov	ax,	ds
	mov	es,	ax
	pop	ax
	mov	bp,	GetMemStructOKMessage
	int	10h
	;开始获取SVGA信息
	mov	ax,	1301h
	mov	bx,	000Fh
	mov	dx,	0800h		;row 8
	mov	cx,	23
	push	ax
	mov	ax,	ds
	mov	es,	ax
	pop	ax
	mov	bp,	StartGetSVGAVBEInfoMessage
	int	10h

	mov	ax,	0x00
	mov	es,	ax
	mov	di,	0x8000
	mov	ax,	4F00h

	int	10h

	cmp	ax,	004Fh

	jz	.SVGA_Loaded
	;获取SVGA信息失败
	mov	ax,	1301h
	mov	bx,	008Ch
	mov	dx,	0900h		;row 9
	mov	cx,	23
	push	ax
	mov	ax,	ds
	mov	es,	ax
	pop	ax
	mov	bp,	GetSVGAVBEInfoErrMessage
	int	10h

	jmp	$
;获取SVGA信息成功
.SVGA_Loaded:
	mov	ax,	1301h
	mov	bx,	000Fh
	mov	dx,	0A00h		;row 10
	mov	cx,	29
	push	ax
	mov	ax,	ds
	mov	es,	ax
	pop	ax
	mov	bp,	GetSVGAVBEInfoOKMessage
	int	10h
	;开始获取SVGA显示模式信息
	mov	ax,	1301h
	mov	bx,	000Fh
	mov	dx,	0C00h		;row 12
	mov	cx,	24
	push	ax
	mov	ax,	ds
	mov	es,	ax
	pop	ax
	mov	bp,	StartGetSVGAModeInfoMessage
	int	10h

	mov	ax,	0x00
	mov	es,	ax
	mov	si,	0x800e

	mov	esi,	dword	[es:si]
	mov	edi,	0x8200
;获取SVGA显示模式信息
SVGA_Mode_Info:
	mov	cx,	word	[es:esi]
	;打印SVGA显示模式信息
	push	ax
	
	mov	ax,	00h
	mov	al,	ch
	call	DispAL

	mov	ax,	00h
	mov	al,	cl	
	call	DispAL
	
	pop	ax
	
	cmp	cx,	0FFFFh
	jz	SVGA_Mode_Info_Finish

	mov	ax,	4F01h
	int	10h

	cmp	ax,	004Fh

	jnz	SVGA_Mode_Info_FAIL	

	add	esi,	2
	add	edi,	0x100

	jmp	SVGA_Mode_Info
;获取SVGA显示模式信息失败
SVGA_Mode_Info_FAIL:
	mov	ax,	1301h
	mov	bx,	008Ch
	mov	dx,	0D00h
	mov	cx,	24
	push	ax
	mov	ax,	ds
	mov	es,	ax
	pop	ax
	mov	bp,	GetSVGAModeInfoErrMessage
	int	10h
;设置SVGA显示模式信息失败
SET_SVGA_Mode_VESA_VBE_FAIL:
	jmp	$
;获取SVGA显示模式信息成功
SVGA_Mode_Info_Finish:

	mov	ax,	1301h
	mov	bx,	000Fh
	mov	dx,	0E00h		;row 14
	mov	cx,	30
	push	ax
	mov	ax,	ds
	mov	es,	ax
	pop	ax
	mov	bp,	GetSVGAModeInfoOKMessage
	int	10h
	;设置SVGA显示模式信息
	mov	ax,	4F02h
	mov	bx,	4180h	;========================mode : 0x180 or 0x143
	int 	10h

	cmp	ax,	004Fh
	jnz	SET_SVGA_Mode_VESA_VBE_FAIL

	;初始化IDT、GDT
	cli

	db	0x66
	lgdt	[GdtPtr]

;	db	0x66
;	lidt	[IDT_POINTER]

	mov	eax,	cr0
	or	eax,	1
	mov	cr0,	eax	

	jmp	dword SelectorCode32:Protect_Mode
[SECTION .s32]
[BITS 32]

Protect_Mode:
	;为长模式作准备
	mov	ax,	0x10
	mov	ds,	ax
	mov	es,	ax
	mov	fs,	ax
	mov	ss,	ax
	mov	esp,	7E00h

	call	Test_Long_Mode
	test	eax,	eax

	jz	No_Support_Long_Mode
	;初始化页表
	mov	dword	[0x90000],	0x91007
	mov	dword	[0x90800],	0x91007		
	mov	dword	[0x91000],	0x92007
	mov	dword	[0x92000],	0x000083
	mov	dword	[0x92008],	0x200083
	mov	dword	[0x92010],	0x400083
	mov	dword	[0x92018],	0x600083
	mov	dword	[0x92020],	0x800083
	mov	dword	[0x92028],	0xa00083
	;加载GDTR
	db	0x66
	lgdt	[GdtPtr64]
	mov	ax,	0x10
	mov	ds,	ax
	mov	es,	ax
	mov	fs,	ax
	mov	gs,	ax
	mov	ss,	ax

	mov	esp,	7E00h
	;打开PAE
	mov	eax,	cr4
	bts	eax,	5
	mov	cr4,	eax
	;打开cr3
	mov	eax,	0x90000
	mov	cr3,	eax
	;启用长模式
	mov	ecx,	0C0000080h		;IA32_EFER
	rdmsr

	bts	eax,	8
	wrmsr
	;打开PE和分页
	mov	eax,	cr0
	bts	eax,	0
	bts	eax,	31
	mov	cr0,	eax

	jmp	SelectorCode64:OffsetOfKernelFile
;测试是否支持长模式
Test_Long_Mode:

	mov	eax,	0x80000000
	cpuid
	cmp	eax,	0x80000001
	setnb	al	
	jb	Support_Long_Mode
	mov	eax,	0x80000001
	cpuid
	bt	edx,	29
	setc	al
;支持长模式
Support_Long_Mode:
	
	movzx	eax,	al
	ret
;不支持长模式
No_Support_Long_Mode:
	jmp	$
[SECTION .s16lib]
[BITS 16]
;读取扇区
ReadSector:
	push	bp
	mov	bp,	sp
	sub	esp,	2
	mov	byte	[bp - 2],	cl
	push	bx
	mov	bl,	[BPB_SecPerTrk]
	div	bl
	inc	ah
	mov	cl,	ah
	mov	dh,	al
	shr	al,	1
	mov	ch,	al
	and	dh,	1
	pop	bx
	mov	dl,	[BS_DrvNum]
On_Reading:
	mov	ah,	2
	mov	al,	byte	[bp - 2]
	int	13h
	jc	On_Reading
	add	esp,	2
	pop	bp
	ret
;获取FAT项值
FATEntry:
	push	es
	push	bx
	push	ax
	mov	ax,	00
	mov	es,	ax
	pop	ax
	mov	byte	[Odd],	0
	mov	bx,	3
	mul	bx
	mov	bx,	2
	div	bx
	cmp	dx,	0
	jz	EvenNumber
	mov	byte	[Odd],	1
EvenNumber:
	xor	dx,	dx
	mov	bx,	[BPB_BytesPerSec]
	div	bx
	push	dx
	mov	bx,	8000h
	add	ax,	SectorNumOfFAT1Start
	mov	cl,	2
	call	ReadSector
	
	pop	dx
	add	bx,	dx
	mov	ax,	[es:bx]
	cmp	byte	[Odd],	1
	jnz	OddNumber
	shr	ax,	4
OddNumber:
	and	ax,	0fffh
	pop	bx
	pop	es
	ret
;打印16进制数字
DispAL:
	push	ecx
	push	edx
	push	edi
	
	mov	edi,	[DisplayPosition]
	mov	ah,	0Fh
	mov	dl,	al
	shr	al,	4
	mov	ecx,	2
.begin:
	and	al,	0Fh
	cmp	al,	9
	ja	.1
	add	al,	'0'
	jmp	.2
.1:
	sub	al,	0Ah
	add	al,	'A'
.2:
	mov	[gs:edi],	ax
	add	edi,	2
	
	mov	al,	dl
	loop	.begin

	mov	[DisplayPosition],	edi

	pop	edi
	pop	edx
	pop	ecx
	
	ret

可以搭配kernel.asm测试以下,bochs窗口会变大,也可阶段测试,查看打印信息

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-08-30 12:34:54  更:2021-08-30 12:37:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 11:42:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码