分享
 
 
 

操作系统入门(三)痛并学习中

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

之前的boot启动镜像文件在需要改变后继文件(kernel.img)时要用partcopy,并且要计算文件的长度,使用起来不方便,现在我们可以引入微软的软盘FAT格式,如果我们使用软盘来作为测试的介质,那么在使用起来会很方便。

;; 文件:boot.asm

;; 作用:从7c00h处启动,显示载入系统信息"Loading System..."

;; 没有文件系统,1.44M 512bits/80sec 软盘启动,

;; 创建日期:2004/01/30 flyback

;; fly-back@163.com

;; ===================================

%define loadpoint 9000h ; 载入点,初始化程序载入到9000h的地方

%define loadoffset 0000h

bits 16

ORG 0x0 ; 启动入口地址

main:

jmp short start ; 跳转到开始程序入口

nop ;

; 引导区文件系统数据

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

brOEM DB ' -My-0S.' ; 0003h - 引导程序的名字

brBPS DW 0x200 ; 000Bh - 每扇区的字节数 512

brSPC DB 0x01 ; 000Dh - 每簇扇区数

brResCount DW 0x0001 ; 000Eh - 保留扇区数

brFATs DB 0x02 ; 0010h - FAT 备份数

brRootEntries DW 0x00e0 ; 0011h - 根目录入口数

brSectorCount

DW 2880 ; 0013h - 磁盘容量扇区数< 32MB

brMedia DB 240 ; 0015h - 媒体描述符

brSPF DW 9 ; 0016h - 每FAT扇区数

brSPH DW 18 ; 0018h - 每磁道扇区数

brHPC DW 2 ; 001Ah - 盘面数

brHidden DD 0 ; 001Ch - 隐藏扇区数

brSectors DD 0 ; 0020h - 如果大于32m的扇区总数

DB 0 ; 0024h - 物理驱动器号

DB 0 ; 0025h - 系统保留

DB 29H ; 0026h - 扩展扇区标记(包含29h)

brSerialNum DD 00000006H ; 0027h - 卷ID

brLabel DB 'teachosdisk' ; 002Bh - 卷标

brFSID DB 'FAT12 ' ; 0036h - 系统保留

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

start:

cli ; 关中断,防止意外中断打断程序执行

mov ax, 0x7c0 ;

mov ds, ax ; 设置数据段

mov es, ax ;

mov ax, 0x0000; 设置堆栈段

mov ss, ax

mov sp, 0ffffh ; 堆栈入口

sti ; 开中断

mov si, brOEM ; system info

call pntchr

mov si, CRLF

call pntchr

mov si, loadmsg ; 调用显示载入信息

call pntchr

; 把磁盘目录信息载入到7c00:0200的地方

loadroot:

mov cx, 0

mov dx, 0

mov ax, 0x0020 ; 32个字节/文件

mul WORD [brRootEntries] ; 32*224(文件数) = 7168 (最多所有文件所占的字节数)

div WORD [brBPS] ; 7168/512 = 14 (Root dir) 文件的目录描述字节占用的扇区数14

xchg ax, cx ; CX = 14

mov al, [brFATs] ; 2

mul word [brSPF] ; 9 * 2 = 18

add ax, word [brResCount] ; 18 + 1 now AX = 19

mov WORD[datasector], ax ; 目录起始的扇区 19

add WORD[datasector], cx ; 数据区起始扇区 33

; 目录放入0x0200内存

mov bx, 0x0200

call ReadSec

; 比较目录中是否有init.img文件存在

mov cx, WORD [brRootEntries] ; CX:224 在目录的所有文件中寻找

mov di, 0x0200 ; 从目录入口处开始 0x200

.LOOP:

push cx ; 保护 CX = 224

mov cx, kernellen ; 8个文件名称和3个扩展名称

mov si, kernelname ;

push di

repe cmpsb ; stop compare if cx >0 or the

; first unequal is met(zf=1)!

pop di

je loadfiledec ;if zf = 1, jmp LOAD_FAT!(Seek OK!)

pop cx

add di, 0x0020 ; 跳到下一个目录入口

loop .LOOP ; cx 自动减

jmp failure

; 载入文件描述子节

loadfiledec:

; 把启动的镜像文件*.img文件的起始单元保存起来

mov si, CRLF

call pntchr

mov si, loadfat

call pntchr

mov si, CRLF

call pntchr

mov dx, WORD [di + 0x001A] ;the file's first cluster

mov WORD [cluster], dx ; store the first cluster

; 计算fat的大小并保存到07c00:0x0200(ds:bx)

xor ax, ax

mov al, BYTE [brFATs] ; al:2

mul WORD [brSPF] ; AH:18 = 9*2

mov cx, ax ; CX:18

; 读取数据放入到0x7c00:0x0200 ds:bx

mov ax, WORD [brResCount] ; AX:1

mov bx, 0x0200 ;

call ReadSec ; AX:1 CX:18 BX:0200

; 读取img 放入 9000:0x0000处

mov ax, loadpoint ; destination of image CS

mov es, ax

mov bx, loadoffset ; destination for image IP

push bx

LOAD_IMAGE:

mov ax, WORD [cluster] ; cluster to read

pop bx ; buffer to read into

call ClusterLBA ; convert cluster to LBA

; AX:[cluster] ES:BX[9000:0000](dest)

xor cx, cx

mov cl, BYTE [brSPC] ; CL:1

call ReadSec ; AX:LBA CX:1 BX:0000 ES:0100

push bx

; 计算下一个单元

mov ax, WORD [cluster] ; identify current cluster

mov cx, ax ; copy current cluster

mov dx, ax ; copy current cluster

shr dx, 0x0001 ; divide by two

add cx, dx ; sum for (3/2)

mov bx, 0x200 ; location of FAT in memory

add bx, cx ; index into FAT

mov dx, WORD [bx] ; read two bytes from FAT

test ax, 0x0001

jnz .ODD_CLUSTER

.EVEN_CLUSTER:

and dx, 0000111111111111b ; take low twelve bits

jmp .DONE

.ODD_CLUSTER:

shr dx, 0x0004 ; take high twelve bits

.DONE:

mov WORD [cluster], dx ; store new cluster

cmp dx, 0x0FF0 ; test for end of file,>=0x0FF0: end or bad!

jb LOAD_IMAGE ; if dx<0x0ff0 (CF=1), jmp Load_image

DONE: ; this Label is not used!

; push WORD loadpoint ;--->pop CS (second)

; push WORD loadoffset ;--->pop IP (first)

; retf

mov si, CRLF

call pntchr

jmp word loadpoint:loadoffset

failure:

mov si, CRLF

call pntchr

mov si, loadfail

call pntchr

hlt

jmp $

;-------------------- 数据区-------------------------------

loadmsg db 'Loading System:',0 ; 要显示的字符窜以0结尾

loadfail db 'Load init Failure!',0 ; 载入失败信息

Sector db 0x00

Head db 0x00

Track db 0x00

datasector dw 0x0000 ; 33 数据区起始扇区号

rootaccess equ 0x0200 ; 存放目录数据的偏移地址

cluster dw 0x0000

kernelname db "KERNEL IMG" ; 11 chars

kernellen equ $ - kernelname ; 长度

CRLF db 13,10,0

Progress db ".", 0

; msgFailure db "ERROR!", 0x00

; loaddir db 'Load Dir:', 0 ;字符串,回车,换行,0

loadfat db 'Load FAT:', 0 ;字符串,回车,换行,0

;readsec db 'read sec', 13,10,0

; ----------------子程序区-------------------------

;*********************显示字符串**************

pntchr:

pusha

.pnt:

lodsb ; 从DS:SI装载一个字符到AL

or al,al ;

jz endpntchr ; 如果 al = 0, 返回

;

mov ah,0x0E ;

mov bx,0x004a ;

int 0x10 ; 调用bios中断显示字符

jmp .pnt ;

;

endpntchr: ;

popa

ret ; 返回

;*************************************************************************

; PROCEDURE ReadSec

; 从ax+1的地方把cx个扇区载入到es:bx的内存

; 注意扇区是从2开始,1扇区已经读入了

;*************************************************************************

ReadSec:

.Main:

;mov si, readsec

;call pntchr

;mov di, 0x0005

.secloop:

push ax

push bx

push cx ;protect ax, bx, cx

call LBACHS ; 调用转换

mov ah, 0x02 ; BIOS 读取扇区命令

mov al, 0x01 ; 一个扇区

mov ch, BYTE [Track] ; track

mov cl, BYTE [Sector] ; sector

mov dh, BYTE [Head] ; head

mov dl, 0 ; 因为是a:所以为0

int 0x13 ; 调用中断

jnc .SUCCESS ; test for read error

xor ax, ax

;int 0x13

;dec di

pop cx

pop bx

pop ax

jnz .secloop

jmp failure ; 错误则显示出错信息并停止

hlt

.SUCCESS

mov si, Progress

call pntchr

pop cx

pop bx

pop ax

add bx, WORD [brBPS] ; 读取下一个扇区的内容

inc ax

loop .Main ; cx -= 1, if cx != 0, jmp .main

ret

;*************************************************************************

; PROCEDURE LBACHS

; 转换逻辑块访问为读取磁盘所使用的磁道,盘面,扇区

; 相对扇区 = (逻辑扇区 / 每磁道扇区数) + 1

; 相对盘面 = (逻辑扇区 / 每磁道扇区数) MOD 盘面数

; 相对磁道 = 逻辑扇区 / (每磁道扇区数 * 盘面数)

;*************************************************************************

LBACHS:

xor dx, dx ; dx = 0

div WORD [brSPH] ; div m16: ax/18 -> 商:ax 余数:dx

inc dl ;

mov BYTE [Sector], dl ;sector No relative to the Track

xor dx, dx ; dx = 0

div WORD [brHPC] ; ax/2 -> 商:ax 余数:dx

mov BYTE [Head], dl ;

mov BYTE [Track], al ;

ret

;*************************************************************************

; PROCEDURE ClusterLBA

; 转换单元访问到直接扇区访问

; LBA = (cluster - 2) * sectors per cluster

;*************************************************************************

ClusterLBA:

sub ax, 0x0002 ; zero base cluster number

xor cx, cx

mov cl, BYTE [brSPC] ; convert byte to word

mul cx

add ax, WORD [datasector] ; base data sector

ret

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

times 510 - ($ - $$) db 0 ; 保证boot区有512个字节

dw 0AA55h ; boot区标记

上面是改进后的boot.asm编译后用partcopy 放入软盘开始的512字节

这时,我们只要把我们的其它程序编译成独立的镜像文件命名为KERNEL.IMG拷贝到软盘(软盘文件)就可以了

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

;; 文件:显示初始化信息

;; KERNEL.ASM

;; 作用:显示初始化信息

;; fly-back@163.com

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

start:

mov ax, cs

mov ds, ax

mov es, ax

lea si, [prompt] ; press a key to clear screen

call pntchr

; 等待按下键盘

;mov ah, 0x10

;int 0x16

; cls

mov ah, 0x06

mov al, 0x00

mov bh,0x07

mov cx, 0x0

mov dx,0x184f

int 0x10

lea si, [start2msg]

call pntchr

; 显示图形功能

; 保存原来的显示方式

mov ah, 0x0f

int 0x10

mov [gmode], ax

; 设置图形模式640X480

mov ah,0x0

mov al, 0x12

int 0x10

; 设置调色板

mov ah, 0x0b

mov bh, 0x0

mov bl, 0x11

int 0x10

; 显示字符串

lea bp, [start2msg] ; es:bp

mov ah, 0x13

mov al, 0x1

mov bh, 0

mov bl, 0x71

mov dx, 0x00

mov cx, msgsize

int 0x10

; 划线

mov bx, 0x0

mov cx, 64

mov dx,70

.pix:

mov ah,0x0c

mov al, bl

int 0x10

inc cx

cmp cx,576

jne .pix

mov cx,64

inc bl

inc dx

cmp dx, 280

jne .pix

; 等待键盘

mov ah, 0x10

int 0x16

; 恢复原来的图形

mov ax, [gmode]

mov ah, 0x0

int 0x10

mov si, retmode

call pntchr

jmp $

nop

;----------------显示字符串----------------------

pntchr:

lodsb ; 从DS:SI装载一个字符到AL

or al,al ;

jz endpntchr ; 如果 al = 0, 返回

;

mov ah,0x0E ;

mov bx,0x0007 ;

int 0x10 ; 调用bios中断显示字符

jmp pntchr ;

;

endpntchr: ;

ret ; 返回

start2msg db 'Display 640X480 Video mode:',13,10,0

msgsize equ ($-start2msg)

prompt db 'Press any key...',13,10,0

prosize equ ($ - prompt)

retmode db 'Return to Text Mode.', 13,10,0

gmode dw 0

把上面文件编译成KERNEL.IMG(大写)拷贝到做好的软盘里,然后用它启动。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有