学习笔记
使用教材(配书源码以及使用方法)
《一个64位操作系统的设计与实现》
http://www.ituring.com.cn/book/2450
https://www.jianshu.com/p/28f9713a9171
源码文件
- 第3章\程序\程序3-4\
loader.asm
代码清单3-18 源码 line : 110 ~ 178
:查找内核文件kernel.bin
-
源码与 程序3-3 loader.asm(Lable_Search_In_Root_Dir_Begin) 基本一致,只需修改要显示的字符串相关
KernelFileName: db "KERNEL BIN",0
-
3-3 loader.asm Lable_Search_In_Root_Dir_Begin
[OS64位][006]源码阅读:代码清单3-7 目标文件搜索 Lable_Search_In_Root_Dir_Begin
https://www.jianshu.com/p/2c03cdd67d4e
代码清单3-19 源码 line : 179 ~ 256
:内核读入内存
3-19 代码流程
- 将
kernel.bin
文件一个扇区的数据读取至物理内存0x7E00 ~ 0x7FFF
; - 接着马上将这512 字节数据逐字节复制到
0x 1 0 0 0 0 0
; - 反复地利用
0x7E00 ~ 0x7FFF
这段0x200(512)
字节作为临时转存空间,从而读完内核文件kernel.bin
的全部数据 ;
3-19 源码解析:移动数据到0x100000
3-19 源码解析:移动数据到0x1000003-19 源码解析:移动数据到0x100000 内存示意图
代码清单 3-19
的代码结构与代码清单3-10
是基本一致的 :
1、在软盘根目录区被读入到缓冲区0x8000
后,找到目标文件kernel.bin
的目录项,可读出目标文件的初始簇号;
2、根据初始簇号可以计算出目标文件位于软盘的起始扇区号,读一个扇区数据到内存缓冲区0x7E00
3、之后,马上将0x7E00
开始的512字节数据移动到内存地址0x100000
处(上图黑色代码部分);
4、接着,计算目标文件的下一个簇号,(期间需要将FAT表读入0x8000
);
5、循环反复,直到整个kernel.bin
文件的全部扇区读取完毕、移动完毕。
代码清单3-20 源码 line: 258 ~ 265
:显示字符 G
- 当内核程序被加载到
1 MB
以上物理内存地址后,在屏幕正中间显示一个字符'G'
Label_File_Loaded:
mov ax, 0B800h
mov gs, ax
mov ah, 0Fh ; 0000: 黑底 1111: 白字
mov al, 'G'
mov [gs:((80 * 0 + 39) * 2)], ax ; 屏幕第 0 行, 第 39 列。
mov [gs:((80 * 0 + 39) * 2)], ax ; 屏幕第 0 行, 第 39 列
代码清单3-21 源码 line : 266 ~272
: 关闭软驱
- 当Loader引导加载程序完成内核程序的加载工作后,软盘驱动器将不再使用
- 向I/O端口
03F2h
写入数值0
,关闭全部软盘驱动器
KillMotor:
push dx
mov dx, 03F2h
mov al, 0
out dx, al
pop dx
代码清单3-22 源码 line: 274 ~ 330
:保存物理地址空间信息
- 当内核程序不再借助临时转存空间后,这块临时转存空间
0x7E00 ~ 0x7FFF
将用于保存物理地址空间信息 - 使用
INT 15H
来获取物理地址空间信息
INT 15H 保存物理地址空间信息
参考资料
- FS寄存器
Segment registers
CS DS ES FS GS SS
ES,FS,GS : These are extra segment registers available for
far pointer addressing like video memory and such.x86 Registers
http://www.eecg.toronto.edu/~amza/www.mindsec.com/files/x86regs.html
- x86 Assembly
- [OS64位][010]源码阅读:代码清单3-10 从FAT12文件系统中加载loader.bin文件到内存 Label_FileName_Found
- [OS64位][008]软盘文件系统分配图:根目录项结构、FAT表项结构
- [OS64位][007]源码阅读:代码清单3-8 INT 10H字符串显示,找不到loader.bin 时显示提示信息
- int 15h中断获取内存信息
调用中断int 15h 之前,需要填充如下寄存器:
· eax int 15h 可以完成许多工作,主要有ax的值决定,我们想要获取内存信息,需要将ax赋值为0E820H。
· ebx 放置着“后续值(continuation value)”,第一次调用时ebx必须为0.
· es:di 指向一个地址范围描述结构 ARDS(Address Range Descriptor Structure), BIOS将会填充此结构。
· ecx es:di所指向的地址范围描述结构的大小,以字节为单位。无论es:di所指向的结构如何设置,BIOS最多将会填充ecx字节。不过,通常情况下无论ecx为多大,BIOS只填充20字节,有些BIOS忽略ecx的值,总是填充20字节。
· edx 0534D4150h('SMAP')——BIOS将会使用此标志,对调用者将要请求的系统映像信息进行校验,这些信息被BIOS放置到es:di所指向的结构中。
中断调用之后,结果存放于下列寄存器之中。
· CF CF=0表示没有错误,否则存在错误。
· eax 0534D4150h('SMAP')
· es:di 返回的地址范围描述符结构指针,和输入值相同。
· ecx BIOS填充在地址范围描述符中的字节数量,被BIOS所返回的最小值是20字节。
· ebx 这里放置着为等到下一个地址描述符所需要的后续值,这个值得实际形势依赖于具体的BIOS的实现,
调用者不必关心它的具体形式,自需在下一次迭代时将其原封不动地放置到ebx中,
就可以通过它获取下一个地址范围描述符。
如果它的值为0,并且CF没有进位,表示它是最后一个地址范围描述符。
网友评论