Guidance of the operating system in Experiment 2 of the laboratory building
bootsec.s file
Write bootsec.s file
Rename the original in oslab/linux-0.11/boot
the directory , that is, execute the commandbootsect.s
bootsect.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 boot
the 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. dd
can be processed using the command
$ dd -bs=1 if=bootsect of=Image skip=32
Then copy the file to linux-0.11
the directory, and run the system to view the display results
$ cp ./Image …/Image
Run
! Note that it is still /oslab/linux-0.11/boot
under
$ …/…/run
Run the screenshot:
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_setup
It 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 setup
the 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:
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.s
and setup.s
.
Comment out build.c
the next few paragraphs of code, as shown in the figure below
Finally, switch to linux-0.11
the directory and execute the following command:
$ make BootImage
Enter the following command to run:
$ …/run
run screenshot
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.11
to the directory and execute the command:
$ make clean
$ make BootImage
$ …/run
run screenshot
Supplement:
hard disk basic parameter table:
Article reference:
INT 10H interrupt function detailed explanation
BIOS int 13H interrupt introduction
operating system principle and practice