操作系统实验1:操作系统的引导

0.实验指导

  • https://hoverwinter.gitbooks.io/hit-oslab-manual/content/sy1_boot.html
  • https://github.com/hoverwinter/HIT-OSLab
  • 《Linux内核完全注释》

代码仓:https://gitee.com/zgw_yixi/linux-0.11-os-lab.git

1.实验目的

  • 熟悉实验环境;
  • 建立对操作系统引导过程的深入认识;
  • 掌握操作系统的基本开发过程;
  • 能对操作系统代码进行简单的控制,揭开操作系统的神秘面纱。

2.实验要求

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

  1. bootsect.s能在屏幕上打印一段提示信息“XXX is booting…”,其中XXX是你给自己的操作系统起的名字,例如LZJos、Sunix等
  2. bootsect.s能完成setup.s的载入,并跳转到setup.s开始地址执行。而setup.s向屏幕输出一行"Now we are in SETUP"。
  3. setup.s能获取至少一个基本的硬件参数(如内存参数、显卡参数、硬盘参数等),将其存放在内存的特定地址,并输出到屏幕上。
  4. setup.s不再加载Linux内核,保持上述信息显示在屏幕上即可。

3.实现

显示、获取硬件参数都要用BIOS中断,相关参数自行查询。

(1)打印加载信息

实现这个功能要明白两点:一是原始代码是在哪里显示正在加载操作系统的,即要知道操作系统的启动过程;二是要知道如何在屏幕上显示字符。
第一问题,原始代码中在bootsect中加载操作系统,并打印出正在加载操作系统的信息。第二问题,因为此时操作系统还没有建立,只能使用BIOS中断来显示。

	mov	ah,#0x03		! read cursor pos
	xor	bh,bh
	int	0x10
	
	mov	cx,#29
	mov	bx,#0x0007		! page 0, attribute 7 (normal)
	mov	bp,#msg1
	mov	ax,#0x1301		! write string, move cursor
	int	0x10
msg1:
	.byte 13,10
	.ascii "x-bit os is loading ..."
	.byte 13,10,13,10

编译执行:

make all
make start

在这里插入图片描述

(2) 打印"Now we are in SETUP"

仿照上面的显示方式即可,代码是现在setup.s文件中。

	mov ax, cs
	mov ds, ax
	mov es, ax

	mov	ah,#0x03		! read cursor pos
	xor	bh,bh
	int	0x10
	
	mov	cx,#26
	mov	bx,#0x000c		! page 0, attribute 7 (normal)
	mov	bp,#msg2
	mov	ax,#0x1301		! write string, move cursor
	int	0x10

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

在这里插入图片描述

(3)获取硬件参数

显示2字节的16进制的函数,数据放在dx寄存器中:

print_hex: 
	mov cx, #4  ! 2字节,一次显示4bit,需要显示4次
	!mov dx, (bp)
print_digit:
	rol dx, #4 ! 循环左移4位,最高4位就移动到了最低4位上
	mov ax, #0x0e0f  ! 0x10中断的参数,AH=0x0e表示显示一个字符,AL=字符,这里先赋值为f,后面会相与
	and al, dl ! 取出最低4位放到al上
	add al, #0x30  ! 转化为ASCII码,0x30是字符'0'的ASCII码
	cmp al, #0x3a  ! 判断数字范围,如果是10-16,需要再加上7;0x39是字符'9'的ASCII码
	jl outp   ! jl指令:当cmp x,y指令中的x < y时则跳转到outp位置
	add al, #0x07  ! 转化为'A' - 'F'
outp:
	int 0x10  ! 调用BIOS中断显示字符
	loop print_digit  ! 执行loop会先将cx寄存器减一然后判断cx是否为0,如果不是则跳转
	ret  ! 函数调用返回

打印换行和回车:

print_nl:
	mov ax, #0x0e0d
	int 0x10
	mov al, #0x0a 
	int 0x10 
	ret

读取光标位置和扩展内存的大小:

! 获取硬件参数
	mov ax, #INITSEG
	mov ds, ax
! 获取光标位置,写入到0x90000
	mov ah, #0x03
	xor bh, bh
	int 0x10
	mov [0], dx
! 读取扩展内存大小,写入到0x90002
	mov ah, #0x88
	int 0x15
	mov [2], ax

显示光标位置和扩展内存大小:

! 打印硬件信息
! 读取光标位置
	mov ah, #0x03
	xor bh, bh
	int 0x10
! 在当前光标位置显示cur_pos位置的字符串
	mov ax, #0x1301
	mov bx, #0x7
	mov cx, #17
	mov bp, #cur_pos
	int 0x10
! 打印16进制的光标位置
 	mov dx, [0] ! 把之前保存的位置数据读出来,这里显示的位置为这行的开头
	call print_hex
	call print_nl
! 读取光标位置
	mov ah, #0x03
	xor bh, bh
	int 0x10
! 显示mem_size位置处的字符串
	mov ax, #0x1301
	mov bx, #0x7
	mov cx, #12
	mov bp, #mem_size
	int 0x10
! 显示16进制的扩展内存大小
	mov dx, [2] ! 从0x90002位置处读出扩展内存大小
	call print_hex
	call print_nl

cur_pos:
	.ascii "current position:"
mem_size:
	.ascii "memory size:"

显示效果:
在这里插入图片描述

不再加载setup.s,停住:

_loop:
	jmp _loop
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忆昔z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值