zoukankan      html  css  js  c++  java
  • 自制操作系统(二) 让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_toolsqemufdimage0.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
  • 相关阅读:
    MVC3、如何应用EntityFramework 连接MySql 数据库 Kevin
    DEV EXPRESS Summary Footer 不显示 Kevin
    装饰模式 Kevin
    Dev 控件 GridControl 控件 二次绑定数据源的问题。 Kevin
    System.InvalidOperationException 异常 Kevin
    LINQ to XML Kevin
    代理模式——代码版“吊丝的故事” Kevin
    VS2012 中的设备 面板 Kevin
    maven 学习笔记(三)创建一个较复杂的 eclipse+android+maven 工程
    maven 学习笔记(一)eclipse+android+maven
  • 原文地址:https://www.cnblogs.com/rixiang/p/5339889.html
Copyright © 2011-2022 走看看