30天自制操作系统-3

发布时间:2019-08-06 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了30天自制操作系统-3脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

我依稀记得当初看到这一节标题的时候非常非常的兴奋,因为可以用c语言了。

首先是我们要来制作真正的IPL了,回顾一下,IPL就是那512个启动字节,让他来引导真正的操作系统,因为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

这里又调用了一个中断,上一个中断是向显示器上输出一个字符,这个中断的作用就是对磁盘进行操作的,如果把他当作C语言或者其他高级语言来讲会很方便,就是这是个对磁盘操作的函数,然后调用前,你给这些寄存器传一些参数,然后会通过标志位的方式返回读取结果,即CF标志位。

介绍一下软盘,这玩意儿淘宝上还能买到,我最开始学的时候买过,实体店早已看不到了,一点几MB的内存,我小仓老师的照片都放不了。。。要它何用。软盘分正反,叫磁头。柱面,可以理解在这个软盘上画了更多的圈,然后再分成扇形,也就有了,柱面和扇区。磁盘号是指那么多个软盘,你读哪个。
我们的IPL就会放在C0-H0-s1(也就是柱面0,磁头0,扇区1),本人不太理解,为啥柱面从0开始而扇区不是。
这里要介绍个新玩意儿了段寄存器,我记得我在学汇编时很经典的一句话,物理地址=段地址 x 10 + 偏移地址 (基于10进制,如果是16进制x16就好了)。如果指定用法就得把段寄存器与偏移地址写在一块儿,如果不写默认以DS作为默认段寄存器,昨天就用到了[],暂时还没讲这个东西次。记得和C语言保持一个习惯,变量初始化,这里的DS也记得初始化,不然会读到其他的内存地址去。
by the way Makefile里面的变量特别像PHP里的变量。

;多式几次

    MOV        AX,0x0820
    MOV        ES,AX
    MOV        CH,0            ; 柱面0
    MOV        DH,0            ; 磁头0
    MOV        CL,2            ; 扇区2

    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                ; 若OK则跳转至fin
    ADD        SI,1            ; 往SI加1
    CMP        SI,5            ; 比较SI是否大于5
    JAE        error            ; 若SI >= 5,则跳转到error
    MOV        AH,0x00
    MOV        DL,0x00            ; A驱动器
    INT        0x13            ; 重置驱动器
    JMP        retry

JNC会去判断CF标志位的状态若是0则会跳转。
JAE大于等于则跳转

    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        next            ; 若OK则跳转至next
    ADD        SI,1            ; 往SI加1
    CMP        SI,5            ; 比较SI是否大于5
    JAE        error            ; 若SI >= 5,则跳转到error
    MOV        AH,0x00
    MOV        DL,0x00            ; A驱动器
    INT        0x13            ; 重置驱动器
    JMP        retry

next:

    MOV        AX,ES            ; 把内存地址后移0x200(512字节)
    ADD        AX,0x0020
    MOV        ES,AX            ; ADD ES,0x020 因为没有这个指令所以只能找中介
    ADD        CL,1            ; 往CL里加1
    CMP        CL,18            ; 比较CL与18
    JBE        readloop        ; 如果CL <= 18 跳转至readloop

JBE只要是拿来控制读取到18扇区的,小于等于则跳转。
我们知道磁盘读出来后的内容都放到了ES:BX了,然而我们分别设置了ES与BX,所以程序也就装载到相应位置啦。
接下来是读取是个柱面,这里就不贴代码了。直接说说新指令把。
JB就是小于等于跳转。还有EQU 这个非常建议写一些经常要改的东西这样写,因为稍微做过项目就知道这种玩意儿不写成这样那是找骂呀。
现在磁盘上的180KB字节就存储在ES:BX这个地方啦。没什么太多难度,就是需要每句去理解。

着手开发操作系统啦。。。

这里作者给了一个非常简单的操作系统。。
but...这是历史的转折点,这毕竟是在启动区之外了,我们要读取IPL之外的代码了,从harib00e(光盘目录)看得出来多了一个文件haribote.nas,这个就是我们的操作系统啦,由刚才的main函数(IPL),调用到了这边来,然后作者通过二进制软件一顿分析,得出了如下结论 1.文件名会写在0x002600以后的地方 2.文件的内容会写在0x004200以后的地方 其实我在纠结一个问题,要是0x002600-0x004200之间都写了文件名咋办。不过他说的是0x002600以后,并非之间,嗯,那我就放心了。知道这个文件的内存地址后,现在我们就要来读取这个文件啦。

从启动区执行操作系统
如果我们是把程序装载在0的位置那么直接使用0x004200就行了,但问题是操作系统有它应该放的位置,所以前面我们放在了0x0820的位置,一开始作者说0x8000我小楞了一下,不是放在0x0820位置的吗?(我还是解释一下,怕有些出血朋友不能理解到)首先,这是个段地址会进行偏移,偏移为0x8200,然后200,一想是512个字节,所以这就是我们的启动区嘛,所以正确,就是0x8000。所以我们的程序需要从0x8000+0x4200 = 0xc200地址读取我们的hairbote.nas文件。

这里又新调用了一个“函数” int 0X10,配合上参数这个的作用是把屏幕弄成VGA图形模式,所以我们要开始做图形界面啦,而非一部份书是做命令行模式的(当然这并不代表我对那种书的差评,我直是觉得一上来做图形界面,会让初学者更又兴趣)

马上要进入32位模式啦
优点当然是更多的内存空间可以使用,与安全性。

; 有关BOOT_INFO
CYLS EQU 0x0ff0 ; 设定启动项
LEDS EQU 0x0fF1
VMODE EQU 0x0ff2 ; 关于颜色数目的信息。颜色的位数
SCRNX EQU 0x0ff4 ; 分辨率的X
SCRNY EQU 0x0ff6 ; 分辨率的Y
VRam EQU 0x0ff8 ; 图像缓冲区的开始地址

    org        0xc200            ; 将程序装载到0xc200处

    MOV        AL,0x13            ; VGA显卡,320*200*8位彩色
    MOV        AH,0x00
    INT        0x10
    MOV        BYTE [VMODE],8    ; 记录画面模式
    MOV        WORD [SCRNX],320
    MOV        WORD [SCRNY],200
    MOV        DWORD [VRAM],0x000a0000

; 用BIOS去得键盘上各种LED指示灯的状态

    MOV        AH,0x02
    INT        0x16             ; keyboard BIOS
    MOV        [LEDS],AL

这里呢,也没做啥实际的操作,就是把各种数据记录下来了,然后通过int 0x16取得了键盘上各种指示灯的状态

开始导入C语言
从一开始我就说要开始C语言了,结果到了今天快结束才开始说导入C语言
虽说导入吧,其实有很多原理性的东西,在这里不会讲,其实里面就是后面的GDT等内容,我也是看到后面的GDT开始有些卡主了,所以这里作者没有讲,而是直接来看bootpack.c吧。
void HariMain(void)
{
fin:

goto fin;

}

看到这种代码,我又重新找回了自信,毕竟我不是那个时代过来的人,没有天天写过汇编,所以汇编和C,当然是C更亲近些。我想这玩意儿C代码也不用解释太多。至于是如何调用到这里来的,后面再细谈。
关于对编译器的解释,也很简单。解释的那么清楚,然后与windows,mac上如此成熟的集成开发环境做了对比,意思是相对于那种,我们搞这么复杂,但是步奏是可控的。

最后作者一定要让计算机处于HALT那就来吧。

; naskfunc
; TAB=4

[FORMAT "WCOFF"] ; 制作目标文件的模式
[BITS 32] ; 制作32位模式用的机械语言

; 制作目标文件的信息

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

    GLOBAL    _io_hlt            ; 程序中包含的函数名

; 以下是实际的函数

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

_io_hlt: ; void io_hlt(void);

    HLT
    RET

然后回来在C语言声明一下,就可以调用啦,不过至于今天许多的细节问题,后面会又深入讲解的。
总的来说我们可以用C语言写代码啦。

脚本宝典总结

以上是脚本宝典为你收集整理的30天自制操作系统-3全部内容,希望文章能够帮你解决30天自制操作系统-3所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。