实验1:操作系统的引导

实验1:操作系统的引导

本章是操作系统实验1的实验记录,对应的课程笔记为:L1 操作系统的启动


! bootsect.s 的任务
! 1.将自己从内存的 0x7c00 搬移到 0x90000 处
! 2.屏幕上打印操作系统正在启动
! 3.将setup.s 从磁盘的第2个扇区,搬移到内存中(bootsect.s的后面)

! as86 linux 汇编语法 : https://blog.csdn.net/qq_26025363/article/details/72566093
! #表示立即数寻址bai。采用立即寻du址方式zhi的指令,在立即dao数前面加上立即zhuan寻址符“#”。
! 例如shu指令MOV A,#30H中30H就是立即数,指令功能为将30H赋给累加器A。
! @表示寄存器的间接寻址。
! 例如指令MOV A,@R0就使用了寄存器间接寻址方式,这条指令的意义为将地址指针R0指向的内部数据存储器单元中的数据送入累加器A中。
! 假设R0中内容为30H,则此指令的功能是以R0寄存器的内容30H为地址,把内部RAM 30H单元中的内容传送给累加器A。

! 一些调试方法:
! ./dbg-asm(启动调试)、reg(查看寄存器)、sreg(查看段寄存器)、xp /nuf addr(查看内存,如 xp /5wc 0x9000:0x0033)

.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss
begbss:
.text
BOOTSEG = 0x07c0    ! bootsect.s 起始段地址(偏移地址为0)
INITSEG = 0x9000    ! bootsect.s 搬移后的段地址(偏移地址为0)
SETUP_OFFSET = 0x0200! setup.s 在内存中存放的偏移地址
YELLOW = 0x0e   ! 淡青色
LIGHT_RED = 0x0c    ! 淡红色

entry _start  !程序入口
_start:
    mov ax, #BOOTSEG     ! 记得加 # ,表示立即数
    mov ds, ax
    mov ax, #INITSEG
    mov es, ax
    mov si, #0
    mov di, #0
    mov cx, #256
    cld
    rep 
    movw
    jmpi go, #INITSEG  ! 跳转到0x9000:go处
    
go:
    mov ax, cs
    mov es, ax
    mov ds, ax
    ! load setup.s   int 0x13中断:https://blog.csdn.net/xianjian1990/article/details/78559879
    !                              https://blog.csdn.net/nwpulei/article/details/5757309
    mov ah, 0x00
    mov dl, 0x00
    int 0x13        ! 复位磁盘

    mov al, #0xff
    mov ah, #0x01
    mov dl, #0x00
    int 0x13         ! 读磁盘状态信息  ! 注意这里不要有加“ # ”
    and ah, #0xff    ! 传出参数 成功:ah = 0x00 ; 错误:al为错误代码;这里注意正常情况用ah作为成功的判断条件,不要用al
    jnz go           ! 读磁盘失败了就跳回go  

    mov bx, #SETUP_OFFSET
    mov al, #0x04     ! 读4个扇区
    mov ch, #0x00     ! 0柱面
    mov cl, #0x02     ! 第2个扇区
    mov dh, #0x00     ! 0磁头
    mov dl, #0x00     ! 软盘,0盘(应该类似于c盘吧)
    mov ah, #0x02
    int 0x13          ! 将setup.s读/加载 到内存中取
    and ah, #0xff     
    jnz go            ! 若失败则跳回go处。 linux0.11中使用 jnc ok_load_setup 做跳转,jnc不是cf不为0跳转吗?有点怪怪的

ok_load_setup:        ! 到这里setup.s已经加载到了内存中 0x9000:0x0200
    ! print "hello OS is running !!!"  int 0x10 中断功能: https://blog.csdn.net/trochiluses/article/details/8970835
    mov ah, #3
    mov bh, #0
    int 0x10    ! 读光标位置   特别注意这里是0x10!!!
    
    mov ax, cs
    mov es, ax
    mov bp, #print  ! print 标签应该就是偏移地址(相对于本程序的偏移地址)
    add dh, #1
    mov dl, #0
    mov bl, #YELLOW
    mov cx, #23
    mov bh, #0
    mov al, #1
    mov ah, #0x13
    int 0x10

    mov ah, #2
    mov bh, #0
    add dh, #1
    mov dl, #0
    int 0x10    ! 置光标位置
    
    jmpi #SETUP_OFFSET, #INITSEG  ! 跳转到setup.s 

print:
    .ascii "hello OS is running !!!" ! 23 byte
.org 510        ! 这里也要注意一下,表示这里是从地址510处开始的

.word 0xaa55    ! 特别注意这里,引导程序的结尾要有这个

.text
endtext:
.data
enddata:
.bss
endbss:

! setup.s的任务
! 1、打印"Now we are in SETUP"
! 2、setup.s能获取至少一个基本的硬件参数(如内存参数、显卡参数、硬盘参数等),将其存放在内存的特定地址,并输出到屏幕上。
! 3、setup.s不再加载Linux内核,保持上述信息显示在屏幕上即可。

.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss
begbss:
.text
INITSEG = 0x9000    ! bootsect.s 搬移后的段地址(偏移地址为0)
SETUP_OFFSET = 0x0200! setup.s 在内存中存放的偏移地址

entry start
start:
    ! print "Now we are in SETUP"
    mov ah, #3
    mov bh, #0
    int 0x10    ! 读光标位置

    mov ax, cs
    mov es, ax
    mov ax, #print1
    add ax, #SETUP_OFFSET
    mov bp, ax    ! 记住要加0x200
    mov al, #0x01
    mov bl, #0x0c
    mov bh, #0
    mov cx, #20   ! 20 byte
    mov ah, #0x13
    int 0x10

    mov ah, #2
    mov bh, #0
    add dh, #1
    mov dl, #0
    int 0x10    ! 置光标位置

    mov ax, #print2
    add ax, #SETUP_OFFSET
    mov bp, ax    ! 记住要加0x200
    mov al, #0x01
    mov bl, #0x0f
    mov bh, #0
    mov cx, #27   ! 27 byte
    mov ah, #0x13
    int 0x10

    mov ah, #2
    mov bh, #0
    mov dl, #17
    int 0x10    ! 置光标位置
    ! 设置寄存器
    mov ax, #INITSEG
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, #SETUP_OFFSET

    ! 获取扩展内存大小    int 15h 中断 : https://blog.csdn.net/Yes_life/article/details/6839453
    mov ah, #0x88
    int 0x15
    mov [2], ax

    ! 把扩展内存大小打印出来,
    mov dx, ax
    mov cl, #0x04
    mov bx, #0x04

to_char:
    rol dx, cl
    mov ax, dx
    and ax, #0x000f
    cmp ax, #0x0a
    jl less
    add al,#0x37
    jmp continue
less:
    add al, #0x30
continue:
    mov ah, #0x0e
    int 0x10
    !loop to_char   ! 不用loop,不知道为什么 loop 不能跳转
    dec bx
    jnz to_char
    
! 程序在这里停下
l: jmp l   

print1:
    .ascii "Now we are in setup!"   ! 20 byte

print2:
    .ascii "extern memory: 0x        KB"   ! 27 byte


.text
endtext:
.data
enddata:
.bss
endbss:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值