从0开始编写操作系统(初级篇)

基础知识:

伪指令org用来规定目标程序存放单元的偏移量。比如,如果在源程序的第一条指令前用了如下指令:
org 200h
那么,汇编程序会把指令指针的ip的值设成200h,即目标程序的第一个字节放在200h处,后面的 内容则顺序存放,除非遇上另一个org 语句

 

若要转贴或使用本文章介绍的技术,请在你发布的文章或作品中注明出处。
 
    上篇文章我们实验了怎么用TC来编写无DOS调用的程序,那么接下来我们来看看怎么编写引导程序。
    我们知道在机器跑起来后,经BIOS系统的检测后便会去读取引导盘(当然可以是硬盘或软盘)的第一个扇区的数据。如果在读取的512个字节的数据中(一个扇区即512个字节)最后一个字为0Xaa55,那么BIOS即认为这是个引导程序,即将其运行并把控制权交给了此应用程序。OK,为了检验我们来写个这样的程序,看看是否成功。
    我们将上文中的 Jig.c 中的内嵌汇编的内容来做个演示。编写以下代码:
 
;shiyan.asm
org 07c00h
 
mov ah, 0x0e
mov al, 't'
mov bl, 7
int 0x10
 
times 510 - ($ - $$)  db 0  ; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw  0xaa55    ; 结束标志
 
然后将其编译 nasm shiyan.asm -o shiyan.bin
好的,这样我就有了一个很小很简单的引导程序,为了保证我们心爱的硬盘的安全我们还是先用软盘来做实验。OK,那我们再用WIN-TC写一个将此引导程序写了软盘的程序。其实很简单,使用biosdisk()函数就OK啦。(不熟悉此函数的朋友自己到网上去查)
 
/* writer.c */
#include <stdio.h>
#inlcude <bios.h>
 
void main(void)
{
    FILE *fp;
    char buffer[512];
    
    fp = fopen("shiyan.bin", "rb");
    fread(buffer, 512, 1, fp);     /* 将shiyan.bin的内容存入buffer数组中 */
    fclose(fp);
 
    biosdisk(3, 0, 0, 0, 0, 1, buffer); /* 将buffer写入第一扇区 */
}
 
OK,编译此程序。在软区插入一张软盘。运行程序就可以把shiyan.bin写入软盘的第一扇区。(程序没有做出错处理,不过一般是不会出错的)好的,关机重启,在BIOS中改为从软盘其中。等待一会你会看到屏幕上显示了一个字母 t。这说明我们写入软盘的程序跑起来了,一个简单的引导程序就写成。
 
好的,关机重启系统。OK,来到系统的 我的电脑 中查看软区,“什么?竟然提示无磁盘?”难道我们的软盘坏了?呵呵,不要着急,我们的软盘没有坏,而是我们上面的引导程序将磁盘中的一些信息覆盖了,而这些信息就是磁盘格式(当然也是我们硬盘的一种格式),我们以后将逐步详细介绍磁盘格式。要知道我们以后的文件系统就靠他了。(当然这个是我自己的猜想,自从我研究了FAT12磁盘格式,我就认定DOS,WINDOS的文件系统应该是靠他来建立的,所以当我们完全认识到这点后我们也许可以自己定义一个新的磁盘格式。当然我是不会这样做啦,呵呵,还是用前人研究出来的东西比较稳妥,呵呵)

<script type="text/javascript">function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>

开发操作系统一直被认为是高不可攀的事,的确,开发一个安全的,完整的,健全的OS是非常复杂的工作,不是一两个人能完成的。但是一个简易的操作系统是可以由一个人在很短的时间开发出来的。我将陆续发表开发简易操作系统的全过程,尽力提供完整的源代码,参考资料和文字说明,我也是OS开发的初学者,希望能得到各位读者的技术支持。该简易操作系统我称为Colimas Simple OS,它包括引导程序,图形界面,鼠标和键盘驱动,内存管理,计时器,多任务处理,控制台,Shell命令,API

 

1. 开发环境

本文使用Qemu虚拟机,可以在Windows XP内虚拟软盘镜像文件。Qemu是开源软件,可以在http://fabrice.bellard.free.fr/qemu/下载。C编译器使用Cygwin下的GCC,汇编编译器使用Nasm,可以在http://sources.redhat.com/cygwin/下载。

操作系统开发在FAT12文件系统的软盘里,FAT12文件系统格式参考http://en.wikipedia.org/wiki/FAT32#FAT12Design部分

 

2. 引导程序

;boot.s

;Colimas Simple OS

       org 0x 7c 00    ;程序始位置

;Fat12文件系格式参考 http://en.wikipedia.org/wiki/FAT32#FAT12

;                  |offset|Length|Descripton

       jmp entry       

       db  0x90         ; 0x00   3     Jump instruction(to skip over header on boot)

       db     "COLIMAS " ; 0X03   8     OEM Name

       db  512          ; 0x0b     2        Bytes per sector. The BIOS Parmeter Block starts here.

       db     1                ; 0x0d   1     Sectors per cluster

       db     1                ; 0x0e     2        Reserved sector count(including boot sector)

       db  2            ; 0x10   1     Number of file allocation tables

       db  224          ; 0x11   2     Maximum number o root directory entries

       db  2880       ; 0x13   2     Total sector:80 tracks * 18 sectors * 2 sides=2880

       db  0xf0       ; 0x15   1     Media descriptor

       db  9          ; 0x16   2     Sectors per File Allocation Table

       db  18         ; 0x18   2     Sectors per track

       db  2            ; 0x 1a    2     Number of heads

       db  0          ; 0x 1c    4     Hidden sectors

       db  2880       ; 0x20   4     Total sectors again

       db  0          ; 0x24   1     Physical drive number

       db  0          ; 0x25   1     Reserved("current head")

       db  0x29       ; 0x26   1     Signature

       db  0xffffffff ; 0x27   4     ID(serial number)

       db  "Colimas OS "; 0x2b 11    Volume Label

       db  "FAT12   " ; 0x36   8     FAT file system type, FAT12

       resb 18       ; 了安全添加18 bytes0

 

entry:

       mov  ax,0     ;寄存器初始化

       mov  ss,ax

       mov  sp,0x 7c 00 ;针赋为0x 7c 00,既引程序初始地址

       mov  ds,ax

       mov  es,ax

       mov  si,msg    ;source indexmsg第一个字符地址

 

putloop:

       mov  al,[si]   ;第一个字符->al

       add  si,1      ;si+1

       cmp  al,0      ;0找最后一个字符,msg之后的byte0

       je   fin       ;如果等于0fin

;video bios参考http://en.wikipedia.org/wiki/BIOS_interrupt_call

       mov  ah,0x0e   ;示字符

       mov  bx,15     ;黑色

       int  0x10      ;video bios中断

       jmp  putloop

fin:

       hlt            ;cpu停止

       jmp   fin      ;死循

      

msg:

       db   0x 0a ,0x 0a ;

       db   "Colimas Simple OS Initialize..."

       db   0x 0a       ;

       db   0

      

       resb 0x1fe-($-$$) ;510 bytes1止均设为0

       db   0x55,0xaa ;sector

 编译与运行:

$ nasm boot.s -o boot.bin

$ cp boot.bin ../qemu

$ ./qemu-win.bat

其中qemu-win.bat的内容是

@set SDL_VIDEODRIVER=windib

@set QEMU_AUDIO_DRV=none

@set QEMU_AUDIO_LOG_TO_MONITOR=0

qemu.exe -L . -m 32 -localtime -std-vga -fda boot.bin

运行结果

3引导程序2

       上文已经作了简单的引导程序,引导程序利用了软盘的第一个Sector作为引导sector,下面开始读取软盘第2Sector

       读取磁盘需要使用Disk Biosint 13中断,参考http://en.wikipedia.org/wiki/BIOS_interrupt_call#INT_13h_AH.3D02h:_Read_Sectors_From_Drive

 

;boot.s

;Colimas Simple OS

       org 0x 7c 00    ;程序始位置

;Fat12文件系格式参考 http://en.wikipedia.org/wiki/FAT32#FAT12

;                  |offset|Length|Descripton

       jmp entry       

       db  0x90         ; 0x00   3     Jump instruction(to skip over header on boot)

       db     "COLIMAS " ; 0X03   8     OEM Name

       db  512          ; 0x0b     2        Bytes per sector. The BIOS Parmeter Block starts here.

       db     1                ; 0x0d   1     Sectors per cluster

       db     1                ; 0x0e     2        Reserved sector count(including boot sector)

       db  2            ; 0x10   1     Number of file allocation tables

       db  224          ; 0x11   2     Maximum number o root directory entries

       db  2880       ; 0x13   2     Total sector:80 tracks * 18 sectors * 2 sides=2880

       db  0xf0       ; 0x15   1     Media descriptor

       db  9          ; 0x16   2     Sectors per File Allocation Table

       db  18         ; 0x18   2     Sectors per track

       db  2            ; 0x 1a    2     Number of heads

       db  0          ; 0x 1c    4     Hidden sectors

       db  2880       ; 0x20   4     Total sectors again

       db  0          ; 0x24   1     Physical drive number

       db  0          ; 0x25   1     Reserved("current head")

       db  0x29       ; 0x26   1     Signature

       db  0xffffffff ; 0x27   4     ID(serial number)

       db  "Colimas OS "; 0x2b 11    Volume Label

       db  "FAT12   " ; 0x36   8     FAT file system type, FAT12

       resb 18       ; 了安全添加18 bytes0

 

entry:

       mov    ax,0     ;寄存器初始化

       mov  ss,ax

       mov  sp,0x 7c 00 ;针赋为0x 7c 00,既引程序初始地址

       mov  ds,ax

       mov  es,ax

       mov    si,msg    ;source indexmsg第一个字符地址

 

putloop:

       mov    al,[si]   ;第一个字符->al

       add  si,1      ;si+1

       cmp  al,0      ;0找最后一个字符,msg之后的byte0

       je   fin       ;如果等于0fin

;video bios参考http://en.wikipedia.org/wiki/BIOS_interrupt_call

       mov  ah,0x0e   ;示字符

       mov  bx,15     ;灰色

       int  0x10      ;video bios中断

       jmp  putloop

;取磁2Sector数据

reading:

       mov  ax,0x0820

       mov  es,ax     ;0x0820(es) * 16=0x8200

       mov  ch,0      ;track/cylinder number

       mov  dh,0      ;head number

       mov  cl,2      ;sector number

       mov  ah,0x02   ;status of reading disk sector

       mov  al,1      ;number of sectors read

       mov  bx,0      ;0x0820(es) * 16 + 0(bx)=0x8200, 0x7e00~0x9fbff

       mov  dl,0x00   ;A drive

       int  0x13        ;Read

       jc   error     ;on error goto label error

      

       mov    si,msg2    ;source index msg2第一个字符地址

putloop2:

       mov    al,[si]   ;第一个字符->al

       add  si,1      ;si+1

       cmp  al,0      ;0找最后一个字符,msg之后的byte0

       je   fin       ;

       mov  ah,0x0e   ;示字符

       mov  bx,15     ;灰色

       int  0x10      ;video bios中断

       jmp  putloop2

error:

       mov    ax,0

       mov    es,ax

       mov    si,errmsg

putloop3:

       mov    al,[si]  

       add  si,1    

       cmp  al,0     

       je   fin      

       mov  ah,0x0e 

       mov  bx,15   

       int  0x10    

       jmp  putloop3

;完后,休眠

fin:

       hlt                     ;cpu停止

       jmp   fin      ;死循

msg:

       db     0x 0a ,0x 0a ;

       db   "Colimas Simple OS Initialize..."

       db   0x 0a       ;

       db   " Reading disk..."

       db   0x 0a       ;

       db   0

      

msg2:

       db   "1 sector was read."

       db   0x 0a

       db   0

errmsg:

       db   "load error"

       db   0x 0a

       db   0

      

       resb 0x1fe-($-$$)

       db   0x55,0xaa ;

编译与运行:

$ nasm boot.s -o boot.bin

$ cp boot.bin ../qemu

$ ./qemu-win.bat

(未完)-C语言的开始,编写图形显示程序。

开始 啦:    新一篇: 解读PE/COFF文件格式

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值