|
发表于 2020-8-30 17:00:41
|
查看: 5121 |
回复: 2
该系列文章是在学习《操作系统真相还原》时通过自己的话加以理解总结的笔记,首先,致敬作者-郑刚!在读本书时不得不佩服作者底层功力的深厚,让我由衷感叹:不愧是北大的学子,其讲解的也通俗易懂,十分详细,我会努力把它学好,学精做好笔记,并加以改进,做出一款自己DIY的操作系统。
BIOS 软件接力第一棒 BIOS 基本输入输出系统,BIOS代码所做的工作是一成不变的,所以他是被固化到ROM中的一块只读区域中,在开机时此ROM会被映射到低端1MB内存的顶部,原因是系统在开启时默认是实地址模式(该模式最大寻址范围0-fffff),所以其寻址范围也就被限制在了0xF0000-x0xFFFFF区域中,这64KB的内存就是BIOS的执行代码.
在开机的一瞬间,CPU的CS:IP寄存器会被强制初始化为0xF000:0xFFF0,在实地址模式下该地址需要乘以16也就是左移四位加上偏移地址得到,于是0xF000:0xFFF0就等效于0xFFFF0此处的地址距离0xFFFFF只有16个字节的空间,里面存放着一条jmp far f000:e05b = fe05b的汇编指令,该指令将跳转到真正的BIOS开始的位置.
接着BIOS将会通过自身的代码对硬件进行自检测,在初始化硬件后,则开始向内存0x000-0x3ff中初始化数据结构以及拷贝中断向量表,紧接着BIOS将会通过调用int 19h中断,此中断用以检测计算机中的硬盘,如果检测到0盘0道1扇区末尾的两个字节是0x55,0xaa则认为此扇区确实存在,于是就会将此区域中的内容,加载到内存7c00的位置,并通过一条jmp far 0:0x7c00h的指令跳转到该位置执行,这样BIOS就将CPU控制权交给了MBR了,而BIOS将会再次睡去.
MBR 收到跳转来源,继续执行。 此处的7c000就是MBR代码的开始位置,之所以是7C00是因为,DOS中要求最小内存是32KB,而MBR大小必须是512字节(1KB),所以选择32kB中的最后1KB的位置最为合适,32KB(0x8000)-1KB(0x400)=>0x7c00,这就是7C00的由来,同时还需要保证第510-511字节必须为0x55,0xaa才可以.
保存以下汇编代码,并使用 nasm -o mbr.bin mbr.asm编译简易版MBR文件.
SECTION MBR vstart=0x7c00 ; 告诉编译器加载到7c00内存处
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov fs,ax
mov sp,0x7c00
mov ax,Message
mov bp,ax ; 保存字符串地址
mov cx,15 ; 保存字符串长度
mov ax,01301h ; 子功能号13是显示字符及属性
mov bx,000ch ; 页号位0,使用黑色为背景色,红色为字体颜色
mov dl,0
int 10h ; 10h中断,用来显示字符
ret
Message: db "hello lyshark !"
times 510-($-$) db 0 ; 填充510字节为0
db 0x55,0xaa ; mbr的结束标志
进入Bochs目录下执行bximage.exe生成一个映像文件,默认是a.img,并将编译好的mbr.bin写入到镜像中
dd if=mbr.bin of=a.img bs=512 count=1 conv=notrunc
在Bochs目录下新建并编辑bosh.src保存,然后执行bochs.exe -f bosh.src模拟执行MBR代码.
megs:32
romimage:file=$BXSHARE/BIOS-bochs-latest
vgaromimage:file=$BXSHARE/VGABIOS-lgpl-latest
floppya:1_44=a.img,status=inserted
boot:floppy
log:bochsout.txt
mouse:enabled=0
keyboard: keymap=$BXSHARE/keymaps/x11-pc-de.map
操作系统开发:BIOS/MBR 引导
上方屏幕会比较混乱,这里我们先来进行清屏操作,清屏中断调用也是int10
SECTION MBR vstart=0x7c00 ; 告诉编译器加载到7c00内存处
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov fs,ax
mov sp,0x7c00
mov ax,0x600 ; 清屏范围,也就是宽度
mov bx,0x0
mov cx,0x0 ; 清屏 左上角(0,0)
mov dx,0x184f ; 清屏 右下角(80=0x4f,25=0x18)
int 0x10
mov ax,Message
mov bp,ax ; 保存字符串地址
mov cx,15 ; 保存字符串长度
mov ax,01301h ; 子功能号13是显示字符及属性
mov bx,000ch ; 页号位0,使用黑色为背景色,红色为字体颜色
mov dl,0
int 10h ; 调用10h号中断,用来显示字符
ret
Message: db "hello lyshark !"
times 510-($-$) db 0 ; 填充510字节为0
db 0x55,0xaa ; mbr的结束标志
执行结果,如下,但是,打印字符串,在底部,因为光标在底部。
操作系统开发:BIOS/MBR 引导
设置光标到顶部,这里百度一下光标中断,发现了。
操作系统开发:BIOS/MBR 引导
接着改进代码
SECTION MBR vstart=0x7c00 ; 告诉编译器加载到7c00内存处
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov fs,ax
mov sp,0x7c00
mov ax,0x600 ; 清屏范围,也就是宽度
mov bx,0x0
mov cx,0x0 ; 清屏 左上角(0,0)
mov dx,0x184f ; 清屏 右下角(80=0x4f,25=0x18)
int 0x10
mov dh,0x0 ; 设置光标列号
mov dl,0x0 ; 设置光标行号
mov bh,0x0 ; 页码
int 0x10
mov ax,Message
mov bp,ax ; 保存字符串地址
mov cx,15 ; 保存字符串长度
mov ax,01301h ; 子功能号13是显示字符及属性
mov bx,000ch ; 页号位0,使用黑色为背景色,红色为字体颜色
mov dl,0
int 10h ; 调用10h号中断,用来显示字符
ret
Message: db "hello lyshark !"
times 510-($-$) db 0 ; 填充剩余的510字节的空间为0
db 0x55,0xaa ; mbr的结束标志
完美结果。
操作系统开发:BIOS/MBR 引导
让我们对显卡说点什么? 上面我们通过调用BIOS提供的int 0x10中断来实现打印字符操作,但我们在后期必须要借助显卡来输出图像,而显卡是外部设备,必须通过总线来操作。
由于CPU使用的信号是TTL电平,而外部设备都是机械设备,故他们不会使用该电平驱动,这就导致CPU与硬件设备没有办法实现沟通,硬件工程师们提供的方法是,在这两者之间架起一座桥,也就是在CPU和外设之间加上一层IO接口,该接口的作用就是实现CPU和外设之间相互做协调转换。
其次外部设备的种类也是多种多样的,其输出的信号可能是数字信号,也可能是模拟信号,而我们的CPU只能处理数字信号,数字信号需要经过数模转换器成模拟量才能送到外设来驱动硬件工作,模拟量也同样需要经过模数转换器[url=]转换成数字量才能被CPU直接处理,所以接口电路中需要包括A/D转换器和D/A转换器。
转换后的数字信号,会经过总线进行传递,总线的别名是BUS,之所以叫做BUS是因为其是公共线路,所有硬件设备都会走此线路,但同一时刻,CPU只能和一个IO接口(寄存器/端口)通信,当有多个IO接口同时想和CPU通信时,那么IO仲裁模块会对其进行竞争与选优,仲裁模块固化到,输入输出控制中心(ICH)也就是南桥芯片上的。
多数情况下,南桥和北桥是成对出现的,南桥主要负责连接PCI,PCI-Express,AGP等低速设备,而北桥则用于链接高速设备,如内存等。
IO接口都是串行口,其在设计之初就是负责与CPU进行通信的,我们想要与CPU通信,其实是向这些接口中写入数据,同时为了区别CPU中的寄存器,所以把IO接口叫做端口,某些外设可以通过内存映射来访问,即把某些端口映射到指定内存中,访问某个内存区域就相当于访问了指定的端口。
SECTION MBR vstart=0x7c00 ; 告诉编译器加载到7c00内存处
mov ax,cs
mov sp,0x7c00
mov ax,0xb800
mov gs,ax
mov ax,0x600 ; 清屏范围,也就是宽度
mov bx,0x0
mov cx,0x0 ; 清屏 左上角(0,0)
mov dx,0x184f ; 清屏 右下角(80=0x4f,25=0x18)
int 0x10
mov dh,0x0 ; 设置光标列号
mov dl,0x0 ; 设置光标行号
mov bh,0x0 ; 页码
int 0x10
mov byte [gs:0x00],'M'
mov byte [gs:0x01],0xa4 ; 显示A=绿色闪烁 4=红色
mov byte [gs:0x02],'B'
mov byte [gs:0x03],0xa5
mov byte [gs:0x04],'R'
mov byte [gs:0x05],0xa6
ret
times 510-($-$) db 0 ; 填充剩余的510字节的空间为0
db 0x55,0xaa ; mbr的结束标志
[/url] |
温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【 投诉建议】板块发帖举报。
|