Harbin Institute of Technology Operating System Experimental Building Experiment 2 Operating System Guidance

Guidance of the operating system in Experiment 2 of the laboratory building

Original link

bootsec.s file

Write bootsec.s file

Rename the original in oslab/linux-0.11/bootthe directory , that is, execute the commandbootsect.sbootsect.s.bak

$ mv bootsect.s bootsect.s.bak

And create a new one and write bootsect.s, the command is as follows:

$ vim bootsect.s

code show as below:

entry _start
_start:
    !读入光标位置
    mov ah,#0x03
    xor bh,bh
    int 0x10

    !字符串msg1长度
    mov cx,#378 
    !第 0 页,属性 7(正常)
    mov bx,#0x0007
    !字符串msg1
    mov bp,#msg1 
    !es:bp 是显示字符串的地址
    !相比与 linux-0.11 中的代码,需要增加对 es 的处理,因为原代码中在输出之前已经处理了 es
    mov ax,#0x07c0
    mov es,ax 
    !写入字符串,移动光标
    mov ax,#0x1301
    int 0x10!BIOS中断
! 设置一个无限循环
inf_loop:
    jmp inf_loop
msg1:
    .byte   13,10
    .ascii "#     #"
    .byte   13,10
    .ascii "##   ##   #   #   ####    #####     #     ####     ##    #"
    .byte   13,10
    .ascii "# # # #    # #   #          #       #    #    #   #  #   #"
    .byte   13,10
    .ascii "#  #  #     #     ####      #       #    #       #    #  #"
    .byte   13,10
    .ascii "#     #     #         #     #       #    #       ######  #"
    .byte   13,10
    .ascii "#     #     #    #    #     #       #    #    #  #    #  #"
    .byte   13,10
    .ascii "#     #     #     ####      #       #     ####   #    #  ######"
    .byte   13,10,13,10
! boot_flag 必须在最后两个字节
.org 510
! 设置引导扇区标记 0xAA55
! 必须有它,才能引导
boot_flag:
    .word   0xAA55

compile

In bootthe directory, execute the following command:

  • compile

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

-0 (is the number '0') runs in 16-bit code segment, warns when instructions higher than 8086 instruction set are used

-a Make the assembler partially compatible with Minix asld. Exchange the usage of [] and (), and change the syntax of some 16-bit jumps and calls (“jmp @(bx)” becomes a legal instruction), Generate code partially compatible with GNU as and ld

  • Link

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

-0 (is the number zero) produces a header structure with a 16bit magic number and uses the i86 subdirectory for the -lx option

-s tells the linker ld86 to strip symbol information from the final executable

  • generate file
-rwxrwxr-x  1 root root   544 Aug  5 18:09 bootsect*
-rw-rw-r--  1 root root   511 Aug  5 18:08 bootsect.o
-rw-rw-r--  1 root root   862 Aug  5 18:08 bootsect.s

Among them, bootsect.o is an intermediate file; bootsect is the compiled and linked object file, that is, the executable file

run

Note that the size of the bootsect file is 544 bytes, and the bootloader must occupy exactly one disk sector, ie 512 bytes. The extra 32 bytes are the header of the Minix executable file. After removing these 32 bytes, it can be put into the boot sector. ddcan be processed using the command

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

Then copy the file to linux-0.11the directory, and run the system to view the display results

$ cp ./Image …/Image

Run
! Note that it is still /oslab/linux-0.11/bootunder

$ …/…/run

Run the screenshot:
insert image description here

setup.s file

Write setup.s file

exist

entry _start
_start:
    !读入光标位置
    mov ah,#0x03
    xor bh,bh
    int 0x10

    !字符串msg2长度
    mov cx,#25 
    !第 0 页,属性 7(正常)
    mov bx,#0x0007
    !字符串msg2
    mov bp,#msg2 
    !es:bp 是显示字符串的地址
    !使用cs的值修改es的值
    mov ax,cs
    mov es,ax 
    !写入字符串,移动光标
    mov ax,#0x1301
    !BIOS中断
    int 0x10
! 设置一个无限循环
inf_loop:
    jmp inf_loop
msg2:
    .byte   13,10
    .ascii "Now we are in SETUP"
    .byte   13,10,13,10
! boot_flag 必须在最后两个字节
.org 510
! 设置引导扇区标记 0xAA55
! 必须有它,才能引导
boot_flag:
    .word   0xAA55

Modify the bootsect.s written earlier

We need to write the key code for loading setup.s in bootsect.s

load_setup:
! 设置驱动器和磁头(drive 0, head 0): 软盘 0 磁头 0
    mov dx,#0x0000
! 设置扇区号和磁道(sector 2, track 0): 0 磁道、2 扇区
    mov cx,#0x0002
! 设置读入的内存地址:BOOTSEG+address = 512,偏移512字节
    mov bx,#0x0200
! 设置读入的扇区个数(service 2, nr of sectors),
! SETUPLEN是读入的扇区个数,Linux 0.11 设置的是 4,
! 我们不需要那么多,我们设置为 2(因此还需要添加变量 SETUPLEN=2)
    mov ax,#0x0200+SETUPLEN
! 应用 0x13 号 BIOS 中断读入 2 个 setup.s扇区
    int 0x13
! 读入成功,跳转到 ok_load_setup: ok - continue
    jnc ok_load_setup
! 软驱、软盘有问题才会执行到这里。我们的镜像文件比它们可靠多了
    mov dx,#0x0000
! 否则复位软驱 reset the diskette
    mov ax,#0x0000
    int 0x13
! 重新循环,再次尝试读取
    jmp load_setup
ok_load_setup:
! 接下来要干什么?当然是跳到 setup 执行。
! 要注意:我们没有将 bootsect 移到 0x9000,因此跳转后的段地址应该是 0x7e0
! 即我们要设置 SETUPSEG=0x07e0

Personal understanding:
load_setupIt mainly reads the specified location (track 0, sector 2) and the number of sectors (here SETUPLEN=2) into the memory (es:bx=07c0H:0200H is the address (07c0H✖10)+200H=07e00H) , and then (cs:ip points to 07e0:0000) to execute setupthe part of the code

Supplement:
Entry parameter:
AH=02H (function number: 02H means read sector)

AL = number of sector

CH = cylinder

CL = sector

DH = magnetic head

DL = drive, 00H ~ 7FH: floppy disk; 80H ~ 0FFH: hard disk

ES: BX=address of the buffer zone (buffer address for reading data)
exit parameters:
if there is an error, the CF flag will be set
; CF=0—the operation is successful, AH=00H, AL=the number of sectors transmitted, otherwise AH=status code, see the figure below:
insert image description here

Complete code after writing

SETUPLEN=2
SETUPSEG=0x07e0
entry _start
_start:
    !读入光标位置
    mov ah,#0x03
    xor bh,bh
    int 0x10

    !字符串msg1长度
    mov cx,#378 
    !第 0 页,属性 7(正常)
    mov bx,#0x0007
    !字符串msg1
    mov bp,#msg1 
    !es:bp 是显示字符串的地址
    !相比与 linux-0.11 中的代码,需要增加对 es 的处理,因为原代码中在输出之前已经处理了 es
    mov ax,#0x07c0
    mov es,ax 
    !写入字符串,移动光标
    mov ax,#0x1301
    int 0x10!BIOS中断
load_setup:
    mov dx,#0x0000
    mov cx,#0x0002
    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

msg1:
    .byte   13,10
    .ascii "#     #"
    .byte   13,10
    .ascii "##   ##   #   #   ####    #####     #     ####     ##    #"
    .byte   13,10
    .ascii "# # # #    # #   #          #       #    #    #   #  #   #"
    .byte   13,10
    .ascii "#  #  #     #     ####      #       #    #       #    #  #"
    .byte   13,10
    .ascii "#     #     #         #     #       #    #       ######  #"
    .byte   13,10
    .ascii "#     #     #    #    #     #       #    #    #  #    #  #"
    .byte   13,10
    .ascii "#     #     #     ####      #       #     ####   #    #  ######"
    .byte   13,10,13,10
! boot_flag 必须在最后两个字节
.org 510
! 设置引导扇区标记 0xAA55
! 必须有它,才能引导
boot_flag:
    .word   0xAA55

compile again

Compile and link bootsect.s and setup.s with Makefile

Before that, we need to modify it tools/build.c, because this is to generate the entire system image, we only need bootsect.sand setup.s.

Comment out build.cthe next few paragraphs of code, as shown in the figure below

insert image description here

Finally, switch to linux-0.11the directory and execute the following command:

$ make BootImage

Enter the following command to run:

$ …/run

run screenshot

insert image description here

setup.s Get basic hardware parameters

Take out the parameters of the hard disk and place them at 0x90000, and print them on the screen through hexadecimal

The complete code of setup.s:


INITSEG  = 0x9000
entry _start
_start:
! 打印 "NOW we are in SETUP"
    mov ah,#0x03
    xor bh,bh
    int 0x10
    mov cx,#25
    mov bx,#0x0007
    mov bp,#msg2
    mov ax,cs
    mov es,ax
    mov ax,#0x1301
    int 0x10

    mov ax,cs
    mov es,ax
! 初始化栈 ss:sp
    mov ax,#INITSEG
    mov ss,ax
    mov sp,#0xFF00

! 获取参数
    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
    !磁盘参数表,复制ds:si->es:di
    mov ax,#0x0000
    mov ds,ax
    lds si,[4*0x41]
    mov ax,#INITSEG
    mov es,ax
    mov di,#0x0004
    mov cx,#0x10
    !重复16次
    rep
    movsb

! 准备打印
    mov ax,cs
    mov es,ax
    mov ax,#INITSEG
    mov ds,ax 

! 光标位置
    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
! 内存大小
    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
! 添加 KB
    mov ah,#0x03
    xor bh,bh
    int 0x10
    mov cx,#2
    mov bx,#0x0007
    mov bp,#msg_kb
    mov ax,#0x1301
    int 0x10
! 柱面
    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
! 磁头
    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
! 扇区
    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
    .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 "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

Go back linux-0.11to the directory and execute the command:

$ make clean

$ make BootImage

$ …/run

run screenshot

insert image description here

Supplement:
hard disk basic parameter table:
insert image description here

Article reference:

INT 10H interrupt function detailed explanation
BIOS int 13H interrupt introduction
operating system principle and practice

Guess you like

Origin blog.csdn.net/m0_52440465/article/details/128264010