自制操作系统(二) 让bootsector开机启动打印一首诗

qq:992591601 欢迎交流

2016-03-31作

2016-06-01、2016-06-27改

 

我总结了些基本原理:

      1.软盘的第一个扇区为启动区

      2.计算机读软盘是以512字节为单位来读写,所以第一个扇区为512字节

      3.一张软盘1440KB,2880个扇区

      4.第一扇区为启动区,加载操作系统用

      5.启动区结束标志位55AA

 

一个简单的开机引导程序(这个算是很基本的了):

; hello-os
; TAB=4

        ORG        0x7c00            ; bios 将程序加载到0x7c00 + 偏移地址执行

;以下,FAT12格式引导程序专用代码

        JMP        entry
        DB        0x90
        DB        "HELLOIPL"        ; name
        DW        512                ; size of a sector(must be 512byte)
        DB        1                ; size of a cluster(must be a sector)
        DW        1                ; FAT begin from 1st sector 
        DB        2                ; FAT num 
        DW        224                ; size of root directory
        DW        2880            ; size of disk(2880 sectors)
        DB        0xf0            ; type of disk
        DW        9                ; length of FAT(must be 9 sectors)
        DW        18                ; how many sectors with a track 
        DW        2                ; head num
        DD        0                ; 不使用分区
        DD        2880            ; size of disk(2880 sectors)
        DB        0,0,0x29        
        DD        0xffffffff        
        DB        "HELLO-OS   "    
        DB        "FAT12   "        
        RESB    18                ; 先空出18字节

; the main part of the program

entry:
        MOV        AX,0            
        MOV        SS,AX
        MOV        SP,0x7c00
        MOV        DS,AX
        MOV        ES,AX

        MOV        SI,msg
putloop:
        MOV        AL,[SI]
        ADD        SI,1            
        CMP        AL,0
        JE        fin
        MOV        AH,0x0e            
        MOV        BX,15            
        INT        0x10            
        JMP        putloop
fin:
        HLT                        ; 让CPU停止,等待指令
        JMP        fin                ; 无限循环

msg:
        DB        0x0a, 0x0a        
        DB        "hello, world"
        DB        0x0a            
        DB        0

        RESB    0x7dfe-$        ; 填写0x00直到0x7dfe,0x7dfe – 0x7c00 = 510

        DB        0x55, 0xaa      ;bootsector end mark

 

解析:

org 0x7c00;

告诉nask,在开始执行的时候,将这些机器语言指令装载到内存哪一部分。

org是伪指令,是给编译器来读的,而不是给计算机执行的,

 

另外,操作系统的引导区域,是被固定分配在0x00007c00 - 0x00007dff

mov si,msg;

msg是标号,本质是一个数字。而标号的计算是依靠之前的org指令。

mov al,[si];

将si所指向地址存储单元中的数据送给al。

虽然我们可以用寄存器来指定内存地址,但可以用作此用途的寄存器只有bx,bx,di,si。

cmp al,0; je fin;

if(al == 0)

{

     goto fin;

}

int指令中断显示字符。不多说。

hlt指令,让cpu停止动作。

 

makefile的用法:

 

2016.06.01

我加入自己的思想写下这样代码

sonnos.asm

    org 07c00h
    CYLS EQU 10          

;以下,FAT12格式引导程序专用代码
    JMP       entry
    DB        0x90
    DB        "HELLOIPL"         ; name
    DW        512                ; size of a sector(must be 512byte)
    DB        1                  ; size of a cluster(must be a sector)
    DW        1                  ; FAT begin from 1st sector 
    DB        2                  ; FAT num 
    DW        224                ; size of root directory
    DW        2880               ; size of disk(2880 sectors)
    DB        0xf0               ; type of disk
    DW        9                  ; length of FAT(must be 9 sectors)
    DW        18                 ; how many sectors with a track 
    DW        2                  ; head num
    DD        0                  ; 不使用分区
    DD        2880               ; size of disk(2880 sectors)
    DB        0,0,0x29        
    DD        0xffffffff        
    DB        "HELLO-OS   "    
    DB        "FAT12   "        
    RESB    18                   ; 先空出18字节

entry:
    mov ax,0          
    mov ss,ax
    mov sp,0x7c00 
    mov ds,ax

;read disk
  
    mov ax,0x0820
    mov es,ax
    mov ch,0                     ;柱面0
    mov dh,0                     ;磁头0
    mov cl,2                     ;扇区2

readloop:
    mov si,0                     ;记录失败次数

retry:
    mov ah,0x02                  ;ah=0x02:读入磁盘
    mov al,1                     ;a sector
    mov bx,0  
    mov dl,0x00                  ;A驱动器
    int 0x13                     ;调用磁盘bios
    jnc next                     ;没出错跳转next
    add si,1
    cmp si,5                     ;大于则跳转
    jae error
    mov ah,0x00
    mov dl,0x00   
    int 0x13                     ;重置驱动器
    jmp retry

next:
    mov ax,es                 
    add ax,0x0020
    mov es,ax          
    add cl,1           
    cmp cl,18            
    jbe readloop                 ; if cl <= 18 readloopへ
    mov  cl,1
    add  dh,1
    cmp dh,2
    jb readloop                  ; if dh < 2 readloopへ
    mov dh,0
    add ch,1
    cmp ch,CYLS
    jb  readloop                 ; if ch < CYLS readloopへ

    mov ax,cs                   ; print poem
    mov ds,ax
    mov es,ax
    call PrintStr
    ;jmp $

; 读完软盘后从C language开始执行

    mov  [0x0ff0],ch             
    jmp   0xc200

error:
    mov  si,msg


PrintStr:
    mov ax,BootPoem
    mov bp,ax
    mov cx,300
    mov ax,01301h
    mov bx,00009h
    mov dh,10
    mov dl,0
    int 10h
    ret

msg:
    db  0x0a, 0x0a       
    db  "load error"
    db   0x0a          
    db   0
 
BootPoem:   
    db "Hold fast to dreams"
    db 0x0a
    db "For if dreams die"
    db 0x0a
    db "Life is a broken-winged bird "
    db 0x0a
    db "That can never fly"
    db 0x0a
    db "Hold fast to dreams"
    db 0x0a
    db "For when dreams go"
    db 0x0a
    db "Life is a barren field"
    db 0x0a
    db "Frozen only with snow"
    db 0x0a

    times 510-($-$$) db 0        ; 接下来510字节写0
    dw 0xaa55                    ; 最后一个字0xaa55是引导程序结束标志

1,实现开机引导后,屏幕蓝色字体打印一首英文诗歌

2,使用nasm编译器,不像书中使用自制的nask

 

default :
    ../z_tools/make.exe img

sonnos.bin : sonnos.asm Makefile
    ../z_tools/nasm.exe sonnos.asm -o sonnos.bin

helloos.img : sonnos.bin Makefile
    ../z_tools/edimg.exe   imgin:../z_tools/fdimg0at.tek \
        wbinimg src:sonnos.bin len:512 from:0 to:0   imgout:helloos.img

asm :
    ../z_tools/make.exe -r sonnos.bin

img :
    ../z_tools/make.exe -r helloos.img

run :
    ../z_tools/make.exe img
    copy helloos.img ..\z_tools\qemu\fdimage0.bin
    ../z_tools/make.exe -C ../z_tools/qemu

install :
    ../z_tools/make.exe img
    ../z_tools/imgtol.com w a: helloos.img

clean :
    -del sonnos.bin

src_only :
    ../z_tools/make.exe clean
    -del helloos.img

 

posted on 2016-03-31 09:15  J·Marcus  阅读(900)  评论(0编辑  收藏  举报

导航