zoukankan      html  css  js  c++  java
  • 《30天自制操作系统》之——第3天

    第三天操作系统的开发才慢慢步入正轨,当然这一天的内容和难度较前两天明显增加,还有一些汇编语言中不好理解的知识点,所以第三天的学习内容要详细的记录一下。

    切入正题!

    ---------------------------------------------------------------------------------------------------------------

    今天的主要内容就是将磁盘中的程序装载到内存中。

    1.用INT指令调用BIOS中的0x13号函数(这个中断详见点击打开链接),代片段如下:

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
              MOV        AX,0x0820 
            MOV        ES,AX 
            MOV        CH,0        ; 柱面0 
            MOV        DH,0        ; 磁头0 
            MOV        CL,2        ; 扇区2 
            MOV        AH,0x02     ; 读盘 
            MOV        AL,1        ; 一个扇区 
            MOV        BX,0         
            MOV        DL,0x00     ; A驱动器 
            INT        0x13        ; 调用磁盘BIOS 
            JC         error 

    可以看到,在调用BIOS的0x13函数之前,要对对一些寄存器进行初始化,函数根据各个寄存器中不容的值,做出相应的操作。
    其中JC是汇编中的条件转移指令(如果发生进位,则转移)。调用这个函数时如果发生错误,则产生进位。

    2.物理地址=段地址*16+偏移地址

    在书中第49页简单介绍了这个知识点,不过这部分我感觉有点难理解,《汇编语言》(王爽)对这个问题的解释很形象,可以参考一下!后面的内容就是把磁盘0到10柱面的内容读进内存,这要理解了上面的这一点内容,这部分还是比较容易的。

    3.到目前为止,我们的IPL(启动程序装载器)算是基本成型了,接下来作者带我们做一些实质性的东西,而不仅仅是显示一个字符串。这个实质性的东西就是,执行磁盘上位于特定位置的程序。作者通过一个小例子让我们体会到了下面的两个特点:

    当我们向一张空软盘保存文件时,

    1)文件名会写在0x002600以后的地方;

    2)文件的内容会写在0x004200以后的地方;

    所以我们只需将磁盘内容所在内存中的首地址+0x004200便得到了某一程序的在内存中的地址,从而可以执行它。在书中的示例中,这个地址应该为0xc200

    (0x8000+0x4200=0c200)(在这我算的时候把磁盘内容在内存中的首地址当成了0x8200,别忘了前面还有512字节的启动区内容呢)。

    4.到了这里我们就可以写一段程序(haribote.nas),看能不能在启动完成后执行。代码如下

    haribote.nas(INT 0x10 详见 INT 0x10

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
      ; haribote-os 
    ; TAB=4 
            ORG            0xc200            ; 这个程序将要被装载的内从地址 
             
             
            MOV         AL,0x13            ; VAG显卡,320*200*8位彩色 
            MOV         AH,0x00             
            INT         0x10 
    fin: 
            HLT 
            JMP         fin 

    ipl10.nas

    001
    002
    003
    004
    005
    006
    007
    008
    009
    010
    011
    012
    013
    014
    015
    016
    017
    018
    019
    020
    021
    022
    023
    024
    025
    026
    027
    028
    029
    030
    031
    032
    033
    034
    035
    036
    037
    038
    039
    040
    041
    042
    043
    044
    045
    046
    047
    048
    049
    050
    051
    052
    053
    054
    055
    056
    057
    058
    059
    060
    061
    062
    063
    064
    065
    066
    067
    068
    069
    070
    071
    072
    073
    074
    075
    076
    077
    078
    079
    080
    081
    082
    083
    084
    085
    086
    087
    088
    089
    090
    091
    092
    093
    094
    095
    096
    097
    098
    099
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
      ;第3天加入读磁盘功能 
    ; duke-os 
    ; TAB=4 
     
    CYLS    EQU        10 
     
            ORG        0x7c00            ; 程序的装载地址 
     
    ; 以下的记述用于标准FAT12格式的软盘 
     
            JMP       entry 
             
            DB        0x90 
            DB        "HELLOIPL"        ; 启动区的名称可以是任意的字符(8字符) 
            DW        512               ; 每个扇区的大小 
            DB        1                 ; 簇(cluster)的大小(必须为1个扇区) 
            DW        1                 ; FAT的起始位置(一般从第一个扇区开始) 
            DB        2                 ; FAT的个数(必须为2) 
            DW        224               ; 根目录的大小(一般设成224项) 
            DW        2880              ; 该磁盘的大小(必须为2880扇区) 
            DB        0xf0              ; 磁盘的种类(必须是0xf0) 
            DW        9                 ; FAT的长度(必须是9扇区) 
            DW        18                ; 1个磁道(track)有几个扇区(必须是18) 
            DW        2                 ; 磁头数(必须是2) 
            DD        0                 ; 不使用分区,必须是0 
            DD        2880              ; 重写一次磁盘大小 
            DB        0,0,0x29          ; 意义不明,固定 
            DD        0xffffffff        ; (可能是)卷标号码 
            DB        "HELLO-OS   "     ; 磁盘的名称(11字节) 
            DB        "FAT12   "        ; 磁盘格式名称(8字节) 
            RESB      18                ; 先空出18字节 
             
    ; 程序核心 
     
    entry: 
            MOV        AX,0             ; 初始化寄存器 
            MOV        SS,AX 
            MOV        SP,0x7c00 
            MOV        DS,AX 
            MOV        ES,AX 
     
    ;读磁盘 
            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           ; 读盘 
            MOV        AL,1              ; 1个扇区 
            MOV        BX,0                 
            MOV        DL,0x00           ; A驱动器 
            INT        0x13              ; 调用磁盘BIOS 
            JNC        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 
            MOV        CL,1 
            ADD        DH,1 
            CMP        DH,2 
            JB         readloop 
            MOV        DH,0 
            ADD        CH,1 
            CMP        CH,CYLS 
            JB         readloop 
             
            MOV        [0x0ff0],CH 
            JMP        0xc200 
     
    error:     
            MOV        SI,msg 
     
    putloop: 
            MOV        AL,[SI] 
            ADD        SI,1              ; 给SI加1 
            CMP        AL,0 
            JE         fin 
            MOV        AH,0x0e           ; 显示一个文字 
            MOV        BX,15             ; 指定字符颜色 
            INT        0x10              ; 调用显卡BIOS 
            JMP        putloop 
    fin: 
            HLT                          ; 让CPU停止,等待指令 
            JMP        fin               ; 无限循环 
     
     
    msg: 
            DB         0x0a, 0x0a        ; 换行2次 
            DB         "DUKE OS" 
            DB         0x0a              ; 换行 
            DB         0 
     
            RESB       0x7dfe-$          ; 填写0x00,直到0x07dfe ($代表将要读入的内存地址) 
     
            DB         0x55, 0xaa 
     


    5.今天剩下的篇幅作者开始导入c语言,这部分详细看一下即可,由于其中添加的一些代码并没有在本节讲解,而是放在了第八天,所以这点内容这要能知道汇编程序和C语言程序的连接过程以及了解一下用汇编语言实现C语言函数的内容即可。

    6.第三天完成后,各个文件之间的依赖关系(这些关系你可以在第三天的makefile中看到,但我觉得还是图形比较直观一点),如下图:



    PS:

    1. 今天的内容对于没有接触过汇编的童鞋来说着实有点难度。汇编的内容早都还给老师了,只好找了本汇编书恶补了一下。

    2. 这一天的内容反反复复看了两三遍才搞清楚头绪,不过收获还是很大的。

    3.如果你想在linux上开发此操作系统,可以参照下面链接出的博文:

    h397916230的专栏



  • 相关阅读:
    phpstorm Failed to create JVM:error code -4
    php内置函数
    多少
    php 正则
    php 数组 array
    位运算题
    c标准库函数 strcat
    strcpy c标准库函数
    编写一个删除c语言程序文件中所有的注释语句
    杂记
  • 原文地址:https://www.cnblogs.com/pangblog/p/3357996.html
Copyright © 2011-2022 走看看