hit-oslab 实验1和实验2

操作系统启动

注意:此部分的代码 /boot/bootsect.s 和 /boot/setup.s是需要重构的,而不是按照源码修改

1.1我对于开机的系统理解

1。就我个人而言开机相当于让整个机器热起来,在通电之后,机器是无知的,这时候需要让源源不断的“内容”加载到内存中,让处理器热起来一直处于工作状态!但是如果一开始不在内存中永久的加入相当于“指路功能的”boot,计算机永远找不到记录在磁盘上的数据,所以我们在内存0xffff0处添加了一直存在的信息就是为了找到操作系统的第一个程序bootsect.s!!!
2。根据0xffff0中的信息我们在磁盘中找到了bootsect.s并把程序加载到实地址0x7c00处,然后该段程序转移至0x90000,而bootsect.s的作用与boot有点相似就是将磁盘中的下一段程序setup.s载入0x90200,注意伏笔0x200正好是512
3。进入setup操作系统逐渐开始掌握计算机的主导权,这时候我们需要得知计算机的各项属性的值,然后从实地址20位寻址方式到了保护模式的32位寻址方式GDT,后面介绍GDT,然后按保护模式的方法将system模块导入
在这里插入图片描述
如图所示

1.2bootsect.s实验源码

SETUPLEN=2
SETUPSEG=0x07e0  !bootsect最后跳转到了0x9000处,但是我们现在写的这个代码只是用来模拟linux-0.11所以说
				 !直接0x07c0+0x0020 这里注意!

entry _start
_start:
	mov ah,#0x03 !  INT10 中断读光标位置
	xor bh,bh    !  page 0
	int 0x10

	mov cx,#27     ! 字符串长度需要在后面确认
	mov bx,#0x0007 ! page--0  line--7
	mov bp,#msg1 !  跳转至.msg1
	mov ax,#0x07c0
	mov es,ax    !  es:bp此寄存器指向要显示的字符串的初始位置
				 !  但是重构代码的时候,并没有在一开始的时候就给es赋值所以需要在这里赋值,区别于源代码
	mov ax,#0x1301  ! ah---13 al---01
	int 0x10

load_setup:    ! 加载外存中SETUP有关的代码
	mov dx,#0x0000 ! 0号磁头---dh 0号驱动---dl
	mov cx,#0x0002 ! 0号磁道---ch 第二个扇区开始
	mov bx,#0x0200 ! 读磁盘操作
	mov ax,#0x0200+SETUPLEN
	int 0x13
	jnc ok_load_setup   ! 成功就跳转
	mov dx,#0x0000
	mov ax,#0x0000
	int 0x13
	jmp load_setup

ok_load_setup:
	jmpi 0,SETUPSEG    !跳转至SETUP开始的阶段

msg1:
	.byte 13,10
	.ascii "to define is to limit"
	.byte 13,10,13,10

.org 510 		! 508+2 与ROOT_DEV有关 这里不做详细的解释

boot_flag:
	.word 0xAA55  !这里的0xAA55正好是一个字---两字节 bootsect总大小 510+2=512 
							 !也就是开头的0x200 世界线回收QAQ


1.3 setup.s

INITSEG = 0x9000
entry _start
_start:
!屏幕输出功能
	mov ah, #0x03
	xor bh, bh
	int 0x10
	
	mov cx, #25
	mov bx, #0x0007
	mov ax, cs  ! cs存储的就是该段的基地址
	mov es, ax  !修改es的值为cs
	mov ax, #0x1301
	mov bp, #msg2
	int 0x10

!将硬件参数取出来放在内存0x90000处
	mov ax,#INITSEG
	mov ds,ax  !数据段的基地址0x9000
	
	!读光标位置
	xor bh,bh
	mov ah,#0x03
	int 0x10
	mov [0],dx  !dh=行号,dl=列号
	
	!读扩展内存大小,超过1M则为扩展
	mov ah,#0x88
	int 0x15
	mov [2],ax
	
	!读第1个磁盘参数表,共16个字节大小;其首地址在int 0x41的中断向量位置
	!中断向量表的起始地址是0x000,1KB大小,并且每个表项占4B
	!所以第1个磁盘参数表的首地址的地址:0x41*4=0x104, 此处4B由段地址和偏移地址组成
	mov ax,#0x0000
	mov ds,ax  !中断向量表的起始地址
	lds si,[4*0x41]  !先存入的是偏移地址,取出存到si中 !取出的4个字节,高位存入ds,低位存入si
	
	mov ax,#INITSEG
	mov es,ax
	mov di,#0x0004      !光标和内存共占4B;  不是mov di,#0x0080 !目标地址 : 0x9000:0x0080  
	mov cx,#16
	rep
	movsb !按字节传送
	
	
!打印前的准备
	mov ax,cs
	mov es,ax  !setup所在的代码段	
	mov ax,#INITSEG
	mov ds,ax !数据段,指向参数所在的地方

!读光标位置,显示提示语,并把数值入栈
	mov ah,#0x03
	xor bh,bh
	int 0x10
	
	mov cx,#18 !16+2
	mov bx,#0x0007
	mov bp,#msg_cursor !"Cursor position:" es:bp
	mov ax,#0x1301
	int 0x10
	
	mov dx,[0] !存好的光标位置读出存到dx中,那没必要再读光标了吧;显示字符串需要放置光标,所以要读
	call print_hex !打印光标位置
	
	
!显示内存大小
	mov ah,#0x03
	xor bh,bh
	int 0x10
	
	mov cx,#14 !12+2
	mov bx,#0x0007
	mov bp,#msg_memory !"Memory Size:"
	mov ax,#0x1301
	int 0x10
	mov dx,[2]
	call print_hex	
	
!补上KB
	mov ah,#0x03
	xor bh,bh
	int 0x10
	
	mov cx,#2
	mov bx,#0x0007
	mov bp,#msg_kb
	mov ax,#0x1301
	int 0x10
	
!柱面,cylinder Cyles
	mov ah,#0x03
	xor bh,bh
	int 0x10
	
	mov cx,#8
	mov bx,#0x0007
	mov bp,#msg_cyles
	mov ax,#0x1301
	int 0x10
	mov dx,[4]
	call print_hex
	
!磁头 Heads
	mov ah,#0x03
	xor bh,bh
	int 0x10
	
	mov cx,#8
	mov bx,#0x0007
	mov bp,#msg_heads
	mov ax,#0x1301
	int 0x10
	mov dx,[6]
	call print_hex
	
!扇区 sectors
	mov ah,#0x03
	xor bh,bh
	int 0x10
	
	mov cx,#10
	mov bx,#0x0007
	mov bp,#msg_sectors
	mov ax,#0x1301
	int 0x10
	mov dx,[18]   !应该是18,而不是12吧
	call print_hex
	
inf_loop:
	jmp inf_loop
	
!显示硬件参数(16位形式)
print_hex:
	!416进制数进行显示
	mov cx,#4
	!mov dx,(bp)  !bp指向栈顶,将其指向的指存入dx?什么栈顶? bp指向的不是msg2吗?不用管栈

print_digit:
	!使从高位到低位显示416进制数
	rol dx,#4
	!ah=0x0e,显示一个字符;al=要显示的字符的ascii码;BIOS中断为int 0x10
	mov ax,#0x0e0f !此时的al未半字节的掩码
	and al,dl !取dl的低4位存入al中
	add al,#0x30
	cmp al,#0x3a !如果是数字,范围是0x30~0x39,即小于0x3a
	jl outp !al小于#0x3a跳转,即数字则跳转
	add al,#0x07 !字母则加上0x07,a~f的范围0x41~0x46

outp:
	int 0x10
	loop print_digit !每次执行 loop 指令,cx 减 1,然后判断 cx 是否等于 0。 这里即执行4次
	ret

!打印回车换行
print_nl:
	!CR 回车
	mov ax,#0x0e0d
	int 0x10
	
	!LF 换行
	mov ax,#0x0e0a
	int 0x10
	ret
	
msg2:
	.byte 13,10
	.ascii "Now we are in SETUP"
	.byte 13,10,13,10
	
msg_cursor:
	 .byte 13,10
	 .ascii "Cursor position:"

msg_memory:
         .byte 13,10
	  .ascii "Memory Size:"
	  
msg_cyles:
          .byte 13,10
          .ascii "Cyles:"
          
msg_heads:
          .byte 13,10
          .ascii "Heads:"
          
msg_sectors:
           .byte 13,10
           .ascii "Sectors:"
           
msg_kb:
           .ascii "KB"

.org 510
boot_flag:
	.word 0xAA55

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值