02-一个引导程序的框架——boot.s

蹲街弑〆低调 提交于 2020-03-17 22:40:04

抛个砖:电脑启动后,如何加载OS?

引块玉:

CPU上电后自动把CS设置为0xF000,段基地址为0xFFFF0000,段长度为64KB,而IP设置为0xFFF0
故,CPU代码指针指向0xFFFFFFF0处,即ROM BIOS存放的位置,开始执行BIOS的硬件自检和初始化功能

在执行完准备加载操作系统的引导程序到0x7c00处前,会检查引导程序是否有效,有效标志0xAA55.

若有效,则跳转到0x7c00处开始执行引导程序(这里是boot.s),否则会转去尝试其它启动设备,

若没有找到则显示“NO ROM BASIC”后死机。

boot.s测试程序:

!
! boot.s Linux0.12内核的bootsect.s的框架
! 功能:在屏幕上显示“Loading system ...”且鸣叫一声
!
! .global 声明全局标识符,供链接器使用(主要通过这些标识符可合并不同源文件的段)
!.global begtext,begdata,begbss,endtext,enddata,endbss
! 三个段定义在同一重叠地址范围中,因此本程序实际不分段
.text                
begtext:             !在代码段定义begtext标号
.data
begdata:             !在数据段定义begdata标号
.bss
begbss:              !在bss段定义begbss标号
.text                !切换到代码段开始编写随后的代码

BOOTSEG = 0x07c0     !BIOS加载bootsect代码的原始段地址
entry start          !告知链接程序,程序从start标号处开始执行
start:
    jmpi go,BOOTSEG  !jmpi段间跳转,cs=BOOTSEG(代码段地址) ip=go(代码段偏移地址)!组成的cs:ip=0x07c0:0x0005,构成下一条指令的地址
go: mov     ax,cs
    mov  ds,ax
    mov  es,ax       !ds es设置为cs,方便数据区(如msg1)寻址
    mov  [msg1+17],ah
    mov  cx,#20      !显示字符串的长度(包括回车换行符)
    mov  dx,#0x1004  !显示的行列数:第17行 第5列
    mov  bx,#0x000c  !字符显示属性(红色)
    mov  bp,#msg1    !指向要显示的字符串
    mov  ax,#0x1301  !功能号0x13 子功能01(写字符串并移动光标到串结尾处)
    int  0x10        !利用BIOS的中断调用0x10,功能0x13,子功能01
loop0: jmp loop0     !死循环
msg1: .ascii "Loading system ..."  !调用BIOS中断显示的信息,共20个ASCII字符
      .byte  13, 10
.org  510
      .word 0xAA55    		   !有效引导扇区标志,供BIOS加载引导扇区使用
.text
endtext:            		   !定义endtext,标志代码段的结束
.data
enddata:            		   !定义enddata,标志数据段的结束
.bss
endbss:                		   !定义endbss,标志bss段的结束

0.关于BIOS提供的0x13中断服务:
在这里插入图片描述

1.编译链接:
as86 -0 -a -o boot.o boot.s //-0:生成8086的16位目标程序
ld86 -0 -s -o boot boot.o //-a:指定生成与GNUas和ld部分兼容的代码 -s:去掉符号信息
备注:as86 和 ld86 在Ubuntu下的安装:
可先查找对应的软件包:apt-cache search as86 ld86
根据查询结果(bin86):apt-get install bin86
2.制作Image文件
dd bs=32 if=boot of=boot.img skip=1 //if:input file of:output file bs=32:去掉32B的头结构
3.bochsrc.bxrc文件:

#how much memory the emulated machine will have
msgs:32
#filename of ROM images
romimage:file=../BIOS-bochs-latest, address=0xf0000
vgaromimage:file=../VGABIOS-lgpl-latest
#hard disk
ata0:enabled=1,ioaddr1=0x1f0,ioaddr2=0x3f0,irq=14
ata0-master:type=disk,path="boot.img",cylinders=306,head=4,spt=17
#choose the boot disk
boot:disk
#where do we send log messages?
log:bochsout.txt

4.运行结果
最后一个点被鸣叫声的ASCII值0x07替换

参考资料:
对于使用BIOS的中断服务,可参阅下文博客:
https://blog.csdn.net/Asdfffy/article/details/84074665
《Linux内核完全剖析——基于0.12内核》第二章

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!