• 30天自制操作系统读书笔记(三)


    来吧。第三天。

    制作真正的IPL:

            

    作者又是那样,一上来就甩一堆代码,用他的话猜测,下面这段代码应该是用来装载下一个512字节的内容的。

                       MOV                  AX,0x0820
    
                       MOV                  ES,AX
    
                       MOV                  CH,0                            ; 柱面0
    
                       MOV                  DH,0                            ; 磁头0
    
                       MOV                  CL,2                    ; 扇区2
    
     
    
                       MOV                  AH,0x02                     ; AH=0x02 : 读盘
    
                       MOV                  AL,1                    ; 1个扇区
    
                       MOV                  BX,0
    
                       MOV                  DL,0x00                      ; A驱动器
    
                       INT            0x13                   ; 调用磁盘bios
    
                       JC              error

    好吧,作者在代码后面稍微解释了一下:

    调用了13号中断,mov入ch,dh等寄存器的数据原来就是这个个断函数需要传递进入的参数。

    那么什么是扇区,什么是柱头呢? 看图吧!

     

    含有IPL的启动区,位于C0-H0-S1(柱面0,磁头0,扇区1),下一个扇区是C0-H0-S2

    所以上面那段程序就是装载这个扇区。

    既然读取了数据,那就要放到内存里啊,否则读取出来有什么用?但是我们怎么指定放入哪里呢?其实这个地址已经指明了。  ES:BX 就是要载入的地址。也就是0x8200-0x83ff

    但是为什么不放入0x8000呢,作者说是留给启动区的(启动区不是7c00-7dff吗?什么鬼!)

    作者又添加了循环写入的代码。

    利用bios程序错误时在flags里返回的数据。

    看注释吧。。

      

                     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                    ; 1个扇区
    
                       MOV                  BX,0
    
                       MOV                  DL,0x00                      ; A驱动器
    
                       INT            0x13                   ; 调用磁盘bios
    
                       JNC           fin                                 ;如果没有出错就跳转到next
    
                       ADD         SI,1                             ;错误次数加一
    
                       CMP        SI,5                     ;和5对比
    
                       JAE            error                            ;大于等于5就跳转
    
                       MOV        AH,0x00                   ;这一句不懂
    
                       MOV        DL,0X00
    
                       INT     0X13
    
                       JMP           retry                      

         

    Omg,这一章难道全是汇编代码了吗?

    作者一鼓作气读了10个柱头。

    总于开始着手操作系统的开发了吗?

    Fin:

             HTL

             JMP fin

    什么,,难道这只是一个只会待机的操作系统???

    但是怎么运行他呢?

    让我们来看看makefile里面的修改吧:

    haribote.img : ipl.bin haribote.sys Makefile

             $(EDIMG)   imgin:../z_tools/fdimg0at.tek

                       wbinimg src:ipl.bin len:512 from:0 to:0

                       copy from:haribote.sys to:@:

                       imgout:haribote.img

    其中haribote.sys就是 haribote.nas经过nask编译后的文件。

    虽然不是很懂makefile里面的这些代码,但应该就是将系统保存到了我们的img磁盘映像里了。

    或许这样太抽象那就理解为这样好了:

             我将磁盘映像写入到了硬盘了。然后将haribote.sys复制到硬盘里了,然后我又把硬盘做成了硬盘镜像。

    作者说 0x002600保存的是文件名

                0x002400保存的是文件内容。那就相信他吧。

    那么启动这个操作系统就简单了。

    我们根据计算,磁盘上的内容加载到0x8000那么磁盘0x4200处就对应着内存里的0xc200.

    但是我又不懂了。

    不是只需要在IPL里jmp一下就好了吗?

    为什么又来个ORG 0xc200??

    好吧,博主表示搞不懂这里。

    索性不管它了。

    作者自称现在程序的前半部分是用汇编写的,后半部分是C语言写的。

    所以啊,又来了一次大跳跃,扔给我们一个 asmhead.nas

    这到底是什么鬼。

    不管了,先来看看C语言这个部分吧。

    那么C语言怎么变成机器语言呢?

    好麻烦。。。。。还好他把一系列过程写到了makefile里面。

    体系结构好像有点复杂啊。博主盗了一张图:

     

    好像放着naskfunc不讲,有点过不去啊,其实就是有些东西C语言实现不了,使用汇编写,然后编译的时候,把naskfunc链接到一起。

    ;naskfunc

    ;TAB=4

    [FORMAT "WCOFF"] ;制作目标文件的模式

    [BITS 32]           ;制作32位模式用的机械语言

    ;制作目标文件的信息

    [FILE "naskfunc.nas"] ;源文件名信息

             GLOBAL _io_hlt;程序中包含的函数名   想在C语言中使用必须用global声明

    ;以下是实际的函数

    [SECTION .text]     ;目标文件中写了这些之后再写程序

    _io_hlt:    ;void io_hlt(void);  要用_开头

             HLT

             RET

  • 相关阅读:
    《日志文件保存》logging
    《火车站信息显示》
    我为什么相信“人造韩寒”?
    研究途径多样性的价值
    推荐一个“思想史上的失踪者”——张鹤慈
    观“方韩大战”
    如何理性的挺韩?从韩寒愚人节的微博说起
    “方韩大战”与独立思考
    《超越感觉:批判性思考指南》读书笔记
    推荐一个在线古典音乐频道
  • 原文地址:https://www.cnblogs.com/You0/p/4432252.html
Copyright © 2020-2023  润新知