• 自制操作系统(二) 让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
  • 相关阅读:
    程序员常用资源工具集合(建议收藏)
    程序员常用资源工具集合(建议收藏)
    16个烧光你脑细胞的悖论
    2.2_模型的选择
    2.1_Scikit-learn数据集
    Sklearn数据集与机器学习
    1.4_数据的特征选择
    1.4_特征的选择
    1.3_数据的特征预处理
    1.2_数据的特征抽取
  • 原文地址:https://www.cnblogs.com/rixiang/p/5339889.html
Copyright © 2020-2023  润新知