哈工大操作系统实验一:操作系统的引导

操作系统实验链接


前言

做实验前一定要先拍个快照!!

在这里插入图片描述

操作系统实验环境的搭建请看如下链接(Ubuntu系统)

Linux0.11环境搭建





一.实验内容

两个部分

1.第一个部分

改写 bootsect.s 主要完成如下功能:

bootsect.s 能在屏幕上打印一段提示信息“XXX is booting…”,其中 XXX 是你给自己的操作系统起的名字,例如 LZJos、Sunix 等(可以上论坛上秀秀谁的 OS 名字最帅,也可以显示一个特色 logo,以表示自己操作系统的与众不同。)

2.第二个部分

改写 setup.s 主要完成如下功能:

bootsect.s 能完成 setup.s 的载入,并跳转到 setup.s 开始地址执行。而 setup.s 向屏幕输出一行"Now we are in SETUP"。
setup.s 能获取至少一个基本的硬件参数(如内存参数、显卡参数、硬盘参数等),将其存放在内存的特定地址,并输出到屏幕上。
setup.s 不再加载 Linux 内核,保持上述信息显示在屏幕上即可。


二、实验内容1

在这里插入图片描述
步骤一:进入到如下路径:/home/你的用户名/oslab/linux-0.11/boot
步骤二:打开bootsect.s,找到第244行的msg1

在这里插入图片描述
步骤三:修改.ascii,我这里修改成:“Hello OS world, my name is laoye!”
在这里插入图片描述
步骤四:找到98行的 mov cx,#24。并修改cx的值,

这里需要修改的是字符串长度,即用需要输出的字符串长度替换 mov cx,#24 中的 24。要注意:除了我们设置的字符串 msg1 之外,还有三个换行 + 回车,一共是 6 个字符。比如这里 Hello OS world, my name is laoye! 的长度是 33,加上 6 后是 39,所以代码应该修改为 mov cx,#39。
在这里插入图片描述
注:es:bp 寄存器保存需要显示字符串 msg1 起始位置,cx 保存字符串 msg1 的字符数

步骤五:在此路径下打开终端
在这里插入图片描述
步骤六:获取root权限后,按顺序输入代码

as86 -0 -a -o bootsect.o bootsect.s
ld86 -0 -s -o bootsect bootsect.o

其中 -0(注意:这是数字 0,不是字母 O)表示生成 8086 的 16 位目标程序,-a 表示生成与 GNU as 和 ld 部分兼容的代码,-s 告诉链接器 ld86 去除最后生成的可执行文件中的符号信息。

如果这两个命令没有任何输出,说明编译与链接都通过了。
没有报错的话,会出现以下.o文件

在这里插入图片描述
其中 bootsect.o 是中间文件。bootsect 是编译、链接后的目标文件。

需要留意的文件是 bootsect 的文件大小是 544 字节,而引导程序必须要正好占用一个磁盘扇区,即 512 个字节。造成多了 32 个字节的原因是 ld86 产生的是 Minix 可执行文件格式,这样的可执行文件除了文本段、数据段等部分以外,还包括一个 Minix 可执行文件头部


步骤七:去掉这 32 个字节的文件头部,输入以下代码

dd bs=1 if=bootsect of=Image skip=32

生成的 Image 就是去掉文件头的 bootsect。
去掉这 32 个字节后,将生成的文件拷贝到 linux-0.11 目录下,并一定要命名为“Image”(注意大小写)。然后就“run”吧!


步骤八:输入以下代码,可以看到我们修改的结果

cp ./Image ../Image
../../run

在这里插入图片描述

二、实验内容2

内容2的第一部分,向屏幕输出 Now we are in setup

在这里插入图片描述

步骤一:进入boot目录下的setup.s文件,清除89行~224行加载SYSTEM模块的内容,避免重复启动的现象出现
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


步骤二:从第32行开始输入以下代码

 mov ax,#0x9000
 mov es,ax

 mov ax,#0x0300
 xor bh,bh
 int 0x10

mov cx,#25
mov bp,#msg2
mov bx,#0x0007
mov ax,#0x1301
int 0x10

在这里插入图片描述

步骤三:在第109行开始输入如下代码,保存退出

msg2:
	.byte 13,10
	.ascii "Now we are in setup!"
	.byte 13,10,13,10

在这里插入图片描述
步骤四:在linux-0.11目录下打开终端,输入以下代码,不出意外,他应该会报错

make BootImage

在这里插入图片描述


步骤五:打个小补丁,修改build.c的代码

上面有 Error的原因是因为 make 根据 Makefile 的指引执行了 tools/build.c,它是为生成整个内核的镜像文件而设计的,没考虑我们只需要 bootsect.s 和 setup.s 的情况。它在向我们要 “系统” 的核心代码。为完成实验,接下来给它打个小补丁。

build.c 从命令行参数得到 bootsect、setup 和 system 内核的文件名,将三者做简单的整理后一起写入 Image。其中 system 是第三个参数(argv[3])。当 “make all” 或者 “makeall” 的时候,这个参数传过来的是正确的文件名,build.c 会打开它,将内容写入 Image。而 “make BootImage” 时,传过来的是字符串 “none”。所以,改造 build.c 的思路就是当 argv[3] 是"none"的时候,只写 bootsect 和 setup,忽略所有与 system 有关的工作,或者在该写 system 的位置都写上 “0”。

把第178行到第190行的内容全部注释掉
在这里插入图片描述




步骤6:重新运行,在路径为linux-0.11的终端下输入以下代码

make BootImage
../run

在这里插入图片描述




参考自如下链接


		INT 0x10功能0x03

描述:
在文本坐标下,读取光标各种信息
接受参数:
AH 0x03
BH 显示页码
返回值:
CH 光标的起始行
CL 光标的终止行
DH 行(Y 坐标)
DL 列(X 坐标)


使用BIOS中断 int 0x10 功能号 0x03 获取光标:

mov	ah,#0x03BIOS中断0x10功能号 ah=0x03 获取光标的位置
xor	bh,bh				! bh寄存器清0,bh寄存器存储带获取光标的页号0
int	0x10				!执行 BIOS 0x10号中断


		INT 0x10功能0x13

描述:
以电传打字机的方式显示字符串
接受参数:
AH 0x13
AL 显示模式
BH 视频页
BL 属性值(如果AL=0x00或0x01)
CX 字符串的长度
DH,DL 屏幕上显示起始位置的行、列值
ES:BP 字符串的段:偏移地址
返回值:

显示模式(AL):
0x00:字符串只包含字符码,显示之后不更新光标位置,属性值在BL中
0x01:字符串只包含字符码,显示之后更新光标位置,属性值在BL中
0x02:字符串包含字符码及属性值,显示之后不更新光标位置
0x03:字符串包含字符码及属性值,显示之后更新光标位置


使用BIOS中断 int 0x10 功能号 0x13 显示字符串:

mov	ax,#SETUPSEG		! 将段寄存器 es 设置为 setup.s 开始位置
mov	es,ax
mov	bp,#MSG_SETUP		!es:bp 寄存器保存显示的字符串的地址

mov	cx,#25				! 字符串长度
mov	bx,#0x0007			! 页号 0,光标属性为停在字符串结尾处
                        ! 属性值,79都可以

mov	ax,#0x1301BIOS中断0x10功能号 ah=0x13 显示字符串
int	0x10				!执行 BIOS 0x10号中断




内容2的第二个部分,获取硬件参数

在这里插入图片描述

硬件参数在内存中的位置如下图所示

在这里插入图片描述




步骤一:进入setup.s文件,在第104行后添加如下代码并且后面所有步骤的代码都是从104行开始

  mov ax,#0x9020
  mov ds,ax
  mov es,ax
  / /此时的数据段从setup模块开始

在这里插入图片描述

步骤二:打印要输出的光标位置的提示信息,输入以下代码

在这里插入图片描述
在这里插入图片描述

mov ax,#0x0300
xor bh,bh
int 0x10

mov cx,#18
mov bp,#CURSOR_POSITION
mov bx,#0x0009 / / 或者是mov bx,#0x0007
mov ax,#0x1301
int 0x10

mov ax,#0x9000
mov ds,ax


步骤三:验证一下结果,在linux-0.11路径下输入以下代码

make BootImage
../run

结果正确
在这里插入图片描述

步骤四:显示硬件参数具体的信息,这是关键也是难点,提供以下两份原码,以及详细解释

小贴士

1.cmp指令请看这

2.rol左移指令请看这

3.跳转指令请看这一篇
还有这一篇

4.loop指令请看这

5.条件判断指令AND和XOR等请看这

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

源码一
print_hex1:
	mov	cx,#4			! 循环计数器
    mov	dx,[0]         
print_digit1:	
	rol	dx,#4			! 循环左移4位
	mov	ax,#0xe0f		! BIOS中断0x10功能号 ah=0x0E 显示一个字符
	and	al,dl			! 获取dl的低4比特值
	add	al,#0x30		! 数字加0x30
	cmp	al,#0x3a
	jl	outp1				
	add	al,#0x07		! 字母多加0x37
outp1:
   	int	0x10			! 执行 BIOS 0x10号中断
   	loop	print_digit1	! loop指令:cx减1,然后判断cx是否等于0

源码二
!显示数字 
	mov cx,#4 !416进制数 
	mov dx,[0] ! cursor  0x90000  
   PRINT_DIGIT1:
	rol dx,#4 !循环移位 高4位变低四位 
	mov ax,#0xe0f	!ah = 0e 显示一个字符(al)
	and al,dl	!DL的低四位 
	add al,#0x30	!转换成 ascii
	cmp al,#0x3A	!大于10? 
	jl OUTP1
	add al,#0x07	!大于10+7
  OUTP1:
	int 0x10
	loop PRINT_DIGIT1 ! CX--



不仅可以打印光标位置,其他硬件同理,也可打印

以扩展内存为例,输入以下代码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

! 打印提示信息
mov ah,#0x03
xor bh,bh
int 0x10

mov cx,#
mov bp,#EXPAND_MENMORY
mov bx,#0x0007
mov ax,#0x1301
int 0x10


mov ax,#0x9000
mov ds,ax
mov es,ax

! 打印扩展内存
print_hex2:
     rol dx,#4
     mov ax,#0x0e0f
print_digit2:     
     and al,dl
     add al,#0x30
     cmp al,#0x3a
     jl output2
     add al,#0x07
output2:
     int 0x10
     loop print_digit2




步骤五:验证结果,linux-0.11路径下输入以下代码

make BootImage
../run

在这里插入图片描述


  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值