哈工大李志军操作系统实验1

时间:2022-07-23
本文章向大家介绍哈工大李志军操作系统实验1,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

本次实验是在Ubuntu 20.04下进行的。首先是bootsect.s代码。如下所示:

entry _start    ;entry告诉链接器从这里开始执行
_start:
    ;读取光标位置,BIOS的0x10中断的0x03功能是读取光标位置。
    mov ah,#0x03
    xor bh,bh
    int 0x10    

    mov cx,#23      ;字符串长度
    mov bx,#0x000c  ;显示红色的字符串
    mov bp,#msg1    ;向屏幕写入的字符串
    mov ax,#0x07c0  
    mov es,ax       ;给es写入0x07c0
    mov ax,#0x1301  ;向屏幕写字符串并移动光标到末尾
    int 0x10        ;BIOS的0x10中断的0x13功能的0x01子功能
inf_loop:
    jmp inf_loop    ;死循环
msg1:
    .byte   13,10   ;回车换行
    .ascii  "Zy's os is booting..."
    .byte   13,10
.org 510      ;之后的语句从510开始
boot_flag:
    .word   0xAA55  ;磁盘引导标志0xAA55

接下来进行汇编,链接。使用如下的命令:

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

如果你编译的时候as86提示as: error reading input.那么大概率是你所使用的编辑器的问题,这时候你只需要用vi打开bootsect.s,然后保存,就可以了。

经过上面的编译之后,生成了bootsect文件,然后使用ls -l命令查看大小,就会发现它是544kb,而不是512kb。引导程序必须要正好占用一个磁盘扇区,即 512 个字节。造成多了 32 个字节的原因是 ld86 产生的是 Minix 可执行文件格式。在Ubuntu下可以使用如下的命令去除这多余的32字节。

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

此时会生成一个名为Image的文件,它的大小刚好是512KB,我们移动他到linux-0.11目录下

可以看到Image是512字节大小,然后在执行oslab目录下的run即可看到bochs界面输出红色的一串字符串。如下所示:

之后的setup.s代码如下所示:

INITSEG  = 0x9000       
entry _start
_start:
! Print "NOW we are in SETUP"
    ;利用BIOS中断,读取光标所在位置
    mov ah,#0x03
    xor bh,bh
    int 0x10

    mov cx,#25          ;25个字符
    mov bx,#0x0007      ;字符串属性
    mov bp,#msg2        ;msg2就是NOW we are in SETUP这串字符串
    mov ax,cs           
    mov es,ax
    mov ax,#0x1301      ;向屏幕写字符串并移动光标到末尾
    int 0x10

    mov ax,cs
    mov es,ax
! init ss:sp            ;初始化栈指针为0x9ff00
    mov ax,#INITSEG
    mov ss,ax
    mov sp,#0xFF00

! Get Params
    mov ax,#INITSEG
    mov ds,ax
    mov ah,#0x03
    xor bh,bh
    int 0x10
    mov [0],dx
    mov ah,#0x88
    int 0x15
    mov [2],ax
    mov ax,#0x0000
    mov ds,ax
    lds si,[4*0x41]
    mov ax,#INITSEG
    mov es,ax
    mov di,#0x0004
    mov cx,#0x10
    rep
    movsbss

! Be Ready to Print
    mov ax,cs
    mov es,ax
    mov ax,#INITSEG
    mov ds,ax

! Cursor Position
    mov ah,#0x03
    xor bh,bh
    int 0x10
    mov cx,#18
    mov bx,#0x0007
    mov bp,#msg_cursor
    mov ax,#0x1301
    int 0x10
    mov dx,[0]
    call    print_hex
! Memory Size
    mov ah,#0x03
    xor bh,bh
    int 0x10
    mov cx,#14
    mov bx,#0x0007
    mov bp,#msg_memory
    mov ax,#0x1301
    int 0x10
    mov dx,[2]
    call    print_hex
! Add KB
    mov ah,#0x03
    xor bh,bh
    int 0x10
    mov cx,#2
    mov bx,#0x0007
    mov bp,#msg_kb
    mov ax,#0x1301
    int 0x10
! Cyles
    mov ah,#0x03
    xor bh,bh
    int 0x10
    mov cx,#7
    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
! Secotrs
    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,[12]
    call    print_hex

inf_loop:
    jmp inf_loop

print_hex:
    mov    cx,#4
print_digit:
    rol    dx,#4
    mov    ax,#0xe0f
    and    al,dl
    add    al,#0x30
    cmp    al,#0x3a
    jl     outp
    add    al,#0x07
outp:
    int    0x10
    loop   print_digit
    ret
print_nl:
    mov    ax,#0xe0d     ! CR
    int    0x10
    mov    al,#0xa     ! LF
    int    0x10
    ret

msg2:
    .byte 13,10,13,10
    .ascii "NOW we are in SETUP"
    .byte 13,10
msg_cursor:
    .byte 13,10
    .ascii "Cursor position:"
msg_memory:
    .byte 13,10
    .ascii "Memory Size:"
msg_cyles:
    .byte 13,10
    .ascii "Cyls:"
msg_heads:
    .byte 13,10
    .ascii "Heads:"
msg_sectors:
    .byte 13,10
    .ascii "Sectors:"
msg_kb:
    .ascii "KB"

.org 510
boot_flag:
    .word 0xAA55

关于BIOS的int 0x10中断,网上有很多资料介绍了如何使用,感兴趣的可以自己去看看。之后,可以参考赵炯博士写的《Linux内核完全注释》里有关tools工具的介绍。在这里,我们注释掉下图中的部分。

然后在linux-0.11目录下使用make BootImage命令即可。然后在oslab目录下运行run,即可看到如下界面。

至此,实验1完成。