分享
 
 
 

关于16位的OS尝试(1)

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

首先我要申明的是我并不是个OS专家,关于OS的研究仅仅是出于自己的兴趣.

但是我认为仅仅是为了自己,也应该把这段时间自己在写OS的经验写出来.

我第一次做的这个OS是个16为实式模式下的OS.因为它比起保护模式要简单,而且容易上手.

首先要找到一张1.44MB的软盘.我的OS就是写到软盘上的.当然你也可以写到硬盘上,不过你得要有两个或更多的硬盘才行.否则硬盘数据被破坏,计算机就无法启动了.在这里我还得提到我曾经做的一件傻事.由于我的电脑上没有软驱,只有个USB移动硬盘,所以我拿USB盘来代替软盘.后来写上去的程序无论如何都有问题.经过一步一步细致测试,才发现原来的是USB盘根本不能用BIOS 13h来读.因为USB盘不是磁盘,居然我当时来拿它作磁盘来读写.现在想起来真是可笑.

我首先写的是Boot Loader,就是软盘上第一个扇区的程序.计算机启动的时候就会自动把这个程序放到0x0000:0x7c00(似乎是这样)去执行.但是只有一个扇区,你不可能把你的整个OS都放到这一个扇区里面.一个扇区才512字节.不过我可以通过这个扇区上的程序,把软盘上其它部分的数据调出来运行.所以老外叫它Boot Loader(引导装载程序).

关于这个Boot Loader是很简单的.特别是对于我要做的16位实式模式下的OS来说,几乎没有什么要求,你想怎么做就怎么做了.但是如果你要做保护模式下的OS,就需要设计到很多比如"A20开起"等麻烦的事情.现在网上到处都有关于OS编写的介绍,但是大多都是停留在这个Boot Loader的讲解中,而且绝大部分还都是讲解16位实式模式下的Boot Loader.比如到www.google.com去搜索一下"Write your own Operating System",可以找到好多这样的文章.当然,这些主要的都是英文的.看看也不错.国外的这些网站大多都是讲如何上手,将一些很实际的东西,而且都是不错.比如我知道的一个网站http://osdev.neopages.net/index.php,就是个很不错的.它关于OS的介绍可不是简单地停留在Boot Loader上哦.而且里面还有我们写OS需要的一切工具,和资料收集.

我喜欢的老师上课最爱讲费话,或许我也汲取了他的优点,讲了上面这么大段的费话,下面我就开始真正写我的Boot Loader了.

Boot Loader似乎只能用汇编写.而最好的汇编编译器是nasm.我开始写Boot Loader的时候,几乎100%的人都说应该使用nasm来作汇编编译器.或许是因为nasm是公开源代码的吧,也或许nasm支持很多格式的生成文件,所以这个东西向来是汇编高手们推荐的汇编编译器.这个东西你可以在http://sourceforge.net/找到下载的,连它的源代码都可以找得到呢.不过http://osdev.neopages.net/index.php里面也是提供了的.现在用了段时间nasm,我也确实觉得它是个好东西.而且关于它的文档也是很齐备的,查询很方便.

好,这就是我的Boot Loader的程序

;----------------------------------------------------------------------

; Hello World Operating System Boot Sector00 Program

;

; tangl_99 2003

;

; Disclaimer: I am not responsible for any results of the use of the contents

; of this file

;----------------------------------------------------------------------

BITS 16

org 0x7c00 ; This is where BIOS loads the bootloader

%define kernel_sectors 16 ; 8K大小的kernel

; Execution begins here

entry:

jmp short begin ; jump over the DOS boot record data

; ----------------------------------------------------------------------

; +-------------------------------------------------------------+

; | Data section of boot.asm bootstrap file |

; +-------------------------------------------------------------+

bsOEM DB 'DEVIATOR' ; OEM String

bsSectSize DW 512 ; Bytes per sector

bsClustSize DB 1 ; Sectors per cluster

bsRessect DW 1 ; # of reserved sectors

bsFatCnt DB 2 ; # of fat copies

bsRootSize DW 224 ; size of root directory

bsTotalSect DW 2880 ; total # of sectors if < 32 meg

bsMedia DB 0xF0 ; Media Descriptor

bsFatSize DW 9 ; Size of each FAT

bsTrackSect DW 18 ; Sectors per track

bsHeadCnt DW 2 ; number of read-write heads

bsHidenSect DD 0 ; number of hidden sectors

bsHugeSect DD 0 ; if bsTotalSect is 0 this value is

; the number of sectors

bsBootDrv DB 0 ; holds drive that the bs came from

bsReserv DB 0 ; not used for anything

bsBootSign DB 29h ; boot signature 29h

bsVolID DD 0 ; Disk volume ID also used for temp

; sector # / # sectors to load

bsVoLabel DB 'DeviatorOS ' ; Volume Label

bsFSType DB 'FAT12 ' ; File System type

;------------------------------------------------------------------------

; --------------------------------------------

; Boot program code begins here

; --------------------------------------------

; boot code begins at 0x0040

begin:

xor ax, ax ; zero out ax

mov ds, ax ; set data segment to base of RAM

mov si, WelcomeMsg ; load address of our welcome message

call putstr ; print the welcome message

mov si, newline

call putstr

mov si, loadMsg ; load address of loading message

call putstr ; print the loading message

mov si, newline

call putstr

xor ax,ax

int 13h

jc fail

;-------------------------------------------------

; 把下一个扇区01的数据读到0x500:0000,然后执行

;-------------------------------------------------

readsector01:

mov ax, 0x500 ; 先将扇区01的数据存放的缓冲段地址传递给AX

mov es, ax ; 通过AX,再缓冲段地址传递给ES

mov bx, 0 ; 缓冲偏移地址为0

mov dl, 0 ; 要读取的驱动器号为0h,为A软驱

mov dh, 0 ; 要读取的磁头号为0

mov ch, 0 ; 要读取的磁道号为0

mov cl, 2 ; 要读取的扇区号为2

mov al, kernel_sectors ; 要读取的扇区数为kernel_sectors

mov ah, 2 ; 调用读磁盘的中断程序

int 13h

cmp ah, 0 ; 查看是否读成功,ah为0表示读取成功

jz gotosector01 ; 如果成功,转到gotosector01

fail: mov si,readerrorMsg ; 将readerrorMsg的地址传给si,准备打印

call putstr ; 打印读磁盘错误的信息

mov si,newline

call putstr

hang:

jmp hang

gotosector01:

mov si, LoadSectorOKMsg ; 显示读取第二个扇区成功的信息

call putstr

mov ax, 0x500 ; 跳转指令到0x500:0000,并把es,ds都改到0x500,但是注意,在jmp指令前不能改cs

mov es, ax

mov ds, ax

jmp 0x0500:0x0000

; --------------------------------------------

; data for our program

;----------------------------------------------

WelcomeMsg db 'Welcome to Tangl Operating System',0

loadMsg db 'Operating System Boot Program is Loading......', 0

LoadSectorOKMsg db 'loaing next sector OK',0

readerrorMsg db 'Error: Can not read sector 01 !', 0

newline db 13,10,0

; ---------------------------------------------

; Print a null-terminated string on the screen

; ---------------------------------------------

putstr:

lodsb ; AL = [DS:SI]

or al, al ; Set zero flag if al=0

jz putstrd ; jump to putstrd if zero flag is set

mov ah, 0x0e ; video function 0Eh (print char)

mov bx, 0x0007 ; color

int 0x10

jmp putstr

putstrd:

retn

;---------------------------------------------

size equ $ - entry

%if size+2 > 512

%error "code is too large for boot sector"

%endif

times (512 - size - 2) db 0

db 0x55, 0xAA ;2 byte boot signature

这么长一篇,你不要觉得干了很多事情.简单地说,我只做了一件有用的事情.

就是把软盘后面16个扇区的数据读出来,并去执行.

代码开头有块叫"引导记录"数据的定义,就是记录一些关于这张磁盘有多少个扇区,多少个磁头,每个扇区多少字节等信息.其实1.44MB的磁盘这些信息都是不变的,只要是1.44MB的软盘,这些数据都是一样的,根本没有必要写出来.但是如果我不把它们写出来,那么当我这张磁盘插入软驱后,Windows或Dos会说它没有格式化,还要我重新格式话,那么我写在上面的boot loader程序就会没有.所以我还是讲究一下windows/dos,按照它们的标准,把这些信息写上去.

后面的代码主要就是显示些提示信息,然后就是一个调用BIOS 13h读磁盘的中断程序.通过它,把后面16个扇区的数据读出来,读到0x500:0x0000去,最后跳到0x500:0x0000去执行那些代码.那16个扇区的代码才是我真正的OS的kernel内核的代码.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有