首页 > 代码库 > 《30天自制操作系统》读书笔记(2)hello, world

《30天自制操作系统》读书笔记(2)hello, world

 

  • 让系统跑起来

  要写一个操作系统,我们首先要有一个储存系统的介质,原版书似乎是06年出版的,可惜那时候没有电脑,没想到作者用的还是软盘,现在的电脑谁有软驱?不得已我使用一张128M的SD卡来代替,而事实上你用的是U盘还是软盘对我们的操作系统没有影响,缺点是你的U盘刷入系统后容量只能是1440 MB,即当年流行的3.5英寸软盘的大小,当然不用担心,再格式化一次(用DiskGeniu),就可以恢复。

  我做事情的话,总是怕自己的努力的结果白费了,害怕辛辛苦苦看完这本书但是发现做出来的东西现在根本没法用,比如你花了大力气造了一辆火车,发现轮子的间距和现行标准不符,没轨道可以跑,被标准抛弃的感觉太恐怖,所以我决定试试,作者的系统能不能真正地跑起来。

我选择了源码中projects\30_day\harib27f中的haribote.img文件,用ImgWriter写入到我的储存卡,

  写入后的大小和预期相符,1.x MB;

  重新启动,开机时狂按Delete,修改启动项;

  F10保存后重启,心中有些忐忑不安;

  … …

  但是结果还是如我所愿,看,It works!

  这是就是我们要完成的东西了,偷窥胜利果实的快感不言而喻,系统甚至支持USB键盘,但不支持USB鼠标确实是不能用。我试着输入了几个命令:

  Bad command. 我也不知道什么是作者指定的command,已知的是,exit能用。

 

 

  • 用Virtual Box 代替物理机

  频繁地开关电脑来调试我们的系统是不理想的,我们需要Virtual Box来搭把手。

打开VB的控制台,新建虚拟机,操作系统的类型选Other,版本选择Other\Unknown,

一直点下一步直到虚拟硬盘,选择不添加虚拟硬盘,我们的虚拟硬盘文件就是img。

  选择虚拟电脑的设置——储存——储存树,添加一个软盘控制器,原来的IDE控制器可以删掉了,在软盘控制器里新增软盘到控制器,当然选择刚才的haribote.img,然后大功告成,启动系统。

  启动系统后一切都显得那么完美,鼠标能用,键盘也是,而且非常方便,输入的蹩脚英文或许有错,见笑了。

  PS: 这里需要注意的是本来有另一种方案,使用VB安装目录下的VBoxManage.exe 执行 VBoxManage convertdd  file.img file.vdi

但不知为何,没办法转换上述的haribote.img,只能转换下面要写的hello, world。

 

  • 动手写操作系统

  电脑启动的步骤是简要部分步骤是:加电——读取BIOS——自检——控制权移交操作系统(或者说引导),如此看来,我们的任务就是编写一段符合规范的代码,在第四步的时候代码会被执行。

  首先我们需要一个标准的FAT12的启动扇区(Boot sector)的代码,我很希望有FAT32 的,无奈这本书给的就是FAT12的,代码如下:

 

  但是这段完全由数据组成的代码只是符合了一个软盘启动扇区的标准,还没有任何可执行的代码:

 1  ; OS 0.01 2 ; 标准FAT12软盘专用代码 3  4 DB 0xeb, 0x4e,0x90 5 DB "HELLOIPL"     ; 启动扇区(boot sector)的名字 6 DW 512            ; 每个扇区(sector)的大小:512B 7 DB 1        ; 簇(cluster)的大小:一个扇区 8 DW 1        ; FAT的起始位置 9 DB 2        ; FAT的个数10 DW 224        ; 根目录大小11 DW 2880        ; 磁盘大小 2880扇区12 DB 0xf0        ; 磁盘种类13 DW 9        ; FAT长度14 DW 18        ; 一个磁道(track)有18个扇区15 DW 2        ; 磁头数16 DD 0        ; 不使用分区17 DD 2880        ; 重写磁盘大小18 DB 0,0,,0x29    ; 固定19 DD 0xffffffff    ; 意义不明20 DB "HELLP_OS   "    ; 磁盘名称11字节21 DB "FAT12   "    ; 磁盘的格式名称8字节22 RESB 18        ; 空出18 Bit

 

  下面添加了可执行的代码,可以称作是IPL了。

 1 ; hello-os 2 ; TAB=4 3  4 ORG        0x7c00    ;为什么这两句可以代替前面的 0xeb 0x4e? 5 JMP        entry 6 DB        0x90 7 DB        "HELLOIPL"    8 DW        512     9 DB        110 DW        1    11 DB        212 DW        224    13 DW        2880        14 DB        0xf0    15 DW        916 DW        18                17 DW        2            18 DD        0        19 DD        2880    20 DB        0,0,0x29    21 DD        0xffffffff    22 DB        "HELLO-OS   "    23 DB        "FAT12   "    24 RESB    18            25 26 entry:27 MOV        AX,028 MOV        SS,AX    ;这里改为 SS,0会出错29 MOV        SP,0x7c0030 MOV        DS,AX   31 MOV        ES,AX32 MOV        SI,msg   ;储存字符串的首地址33 putloop:34 35 MOV        AL,[SI]36 ADD        SI,1            37 CMP        AL,038 JE         fin39 MOV        AH,0x0e    ; int 0x10 的 0x0e号功能 40 MOV        BX,0x15 41 INT        0x1042 JMP        putloop43 fin:44 HLT        45 JMP        fin46 47 msg:48 DB        0x0a, 0x0a    ; ‘\n‘ = #13 = 0x0a49 DB        "LastAvengers‘s OS"50 DB        0x0a    51 DB        0       ; 结束标志52 53 RESB    0x7dfe-$ ; 0x01fe+0x7c00 = 0x7dfe54 DB        0x55, 0xaa55 DB        0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0056 RESB    460057 DB        0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0058 RESB    1469432    

  使用作者提供的nask.exe,执行 nask.exe IPL.asm a.img 可以得到镜像文件,可以利用VB来启动了。

 

 

  • 简化操作流程:

  一开始作者为我们提供了install.bat,!cons_nt.bat,run.bat来安装和运行系统,后

来又介绍了make.exe,实在是神器,(之前还不解为什么在Linux下编译包需要make install,现在终于知道了),只需要构造一个不带扩展名的MakeFile文件,就可以集编译写入运行于一身,MakeFile 的基本格式如下:

 

 宏定义  源文件之间的相互依赖关系
         任意可执行的Shell命令

 

作者在这里贸贸然地给出了

1 helloos.img : ipl.bin Makefile2     ../z_tools/edimg.exe imgin:../z_tools/fdimg0at.tek 3         wbinimg src:ipl.bin len:512 from:0 to:0 imgout:helloos.img 

 

  先通过nask 生成bin文件再用edimg.exe 转为img文件,我不知道为什么要这么做,而且生成 .lst 文件的时候也失败了。

作者给出的makefile中地址都是斜杠,而系统用的是反斜杠,虽然效果一样,但是看着不爽,vim ":1,$/\//\\/g"可以将所有斜杠转化为反斜杠,注意这里的\有的是用来做转义的。

   

于是我没有照着他那样,我的MakeFile改写如下,同样正常工作:

 1 # nask.exe ipl.asm a.img ipl.lst ::fail NASK: LSTBUF is no enough 2  3 default : 4     tolset\z_tools\make.exe install 5     tolset\z_tools\make.exe    run 6     del *.*~ >nul ::删除临时文件 7     del *~ >nul 8  9   10 a.img : ipl.asm Makefile11     tolset\z_tools\nask.exe ipl.asm a.img::直接编译成img,不知作者的用意是什么12 13 install :14     tolset\z_tools\make.exe -r a.img15 16 run :17     echo Running...18     "D:\Program Files\Oracle\VirtualBox\VirtualBox.exe" --comment "OS1" --startvm "a5c4b0e6-e142-4720-98ee-056911204b29" ::虚拟机的快捷方式19     echo Finished.

 

另外改写了!cons_nt.bat,增加了环境变量。

1 @echo off2 color 0b3 set PATH=%PATH%;tolset\z_tools4 cmd.exe 

 

之后打开!cons_nt.bat, 输入make,效果如图:

 

  • 知识点:

  FAT12启动区的标准:第511个字节开始填充55AA,软盘大小是2880*512/1024 = 1440 KB;

  启动区的加载地址是 0x7c00—0x7dff;

  各种寄存器,只有SI,DI,BX为数不多的几个寄存器才能放地址;

  MakeFile 的用法;

  Vim的替换命令;

  int 0x10中断重点是AH=0EH:http://blog.csdn.net/thimin/article/details/2313390。

  唉,我真是话唠。