30天自制操作系统笔记(三)

时间:2022-11-26 05:54:49

今天学习了第三天的内容,相比较前两天的内容有点难,但是还好成果出来啦。本次主要的改进之处是修改了主函数的名字,是我们可以不拘泥作者的要求。

我们先看一下运行结果截图:

30天自制操作系统笔记(三)

此图为正常的运行结果,到现在操作系统采用了汇编+C语言的方式。我们看一下操作系统的主函数:

/*告诉C编译器,有一个函数在别的文件里*/
void io_hlt(void);

void UcanMain(void)
{
fin:
io_hlt(); /*执行nashfunc.nas里的_io_hlt*/
goto fin;
}
注:原来的代码中的主函数只能为HariMain,不能修改,但是我发现在其调用的库中可以修改,故将其修改为自己想要的函数名字,需要修改下面的部分:

30天自制操作系统笔记(三)

如果需要,需要修改haribote.rul文件上面黄色的部分,除此之外还要修改文件:

30天自制操作系统笔记(三)

需要将harilibc.lib文件上面圈起来的部分修改为自己想要的名字,但注意大小写,大小写一定要跟源文件中的一样。

下面是函数_io_hlt所在的文件源码:

; naskfunc
; TAB=4

[FORMAT "WCOFF"]
[BITS 32]


[FILE "naskfunc.nas"]

GLOBAL _io_hlt

[SECTION .text]

_io_hlt:
HLT
RET
下面是ucan23.nas文件的源码

; ucan23-os
; TAB=4

BOTPAKEQU0x00280000
DSKCACEQU0x00100000
DSKCAC0EQU0x00008000

; 有关BOOT_INFO
CYLSEQU0x0ff0
LEDSEQU0x0ff1
VMODEEQU0x0ff2
SCRNXEQU0x0ff4
SCRNYEQU0x0ff6
VRAMEQU 0x0ff8

ORG0xc200
MOVAL, 0x13
MOVAH, 0x00
INT0x10
MOV BYTE[VMODE], 8
MOVWORD[SCRNX], 320
MOVWORD[SCRNY], 200
MOVDWORD [VRAM], 0x000a0000

; 用BIOS获取LED指示灯的状态
MOVAH, 0x02
INT0x16 ; keyboard BIOS
MOV[LEDS], AL

MOVAL, 0Xff
OUT0x21, AL
NOP
OUT0xa1, AL

CLI

CALLwaitkbdout
MOVAL, 0xd1
OUT0x64, AL
CALLwaitkbdout
MOVAL, 0xdf
OUT0x60, AL
CALLwaitkbdout

[INSTREST "i486p"]

LGDT[GDTR0]
MOVEAX,CR0
ANDEAX, 0x7fffffff
OREAX, 0x00000001
MOVCR0, EAX
JMPpipelineflush
pipelineflush:
MOVAX, 1*8
MOVDS, AX
MOV ES, AX
MOVFS, AX
MOVGS, AX
MOV SS, AX


MOVESI, bootpack
MOVEDI, BOTPAK
MOVECX, 512*1024/4
CALLmemcpy


MOVESI, 0x7c00
MOVEDI, DSKCAC
MOVECX, 512/4
CALLmemcpy


MOVESI, DSKCAC0+512
MOVEDI, DSKCAC+512
MOVECX, 0
MOVCL, BYTE [CYLS]
IMULECX, 512*18*2/4
SUBECX, 512/4
CALLmemcpy

MOVEBX, BOTPAK
MOVECX, [EBX+16]
ADDECX, 3
SHRECX, 2
JZskip
MOVESI, [EBX+20]
ADDESI, EBX
MOVEDI, [EBX+12]
CALLmemcpy

ship:
MOVESP, [EBX+12]
JMPDWORD 2*8:0X0000001B

waitkdbout:
INAL, 0x64
ANDAL, 0x02
JNZwaitkdbout
RET

memcpy:
MOVEAX, [ESI]
ADDESI, 4
MOV[EDI], EAX
ADDEDI, 4
SUBECX, 1
JNZmemcpy
RET

ALIGNB16
GDT0:
RESB 8
DW0xffff,0x0000,0x9200,0x00cf
DW0xffff,0x0000,0x9a28,0x0047

DW0

GDTR0:
DW8*3-1
DDGDT0

ALIGNB16

bootpack:

;fin:
;HLT
;JMPfin

接下来是引导文件ucan23ipl.nas的源码:

; ucan23-os
; TAB-4

CYLSEQU10
ORG0x7c00;指明程序的装载地址
; 以下这段是标准FAT12格式软盘专用的代码
JMPentry
DB0x90
DB"UCAN23LD";启动区的名称可以是任意的字符串(8字节)
DW512;每个扇区的大小
DB1;簇的大小
DW1
DB2
DW224
DW2880
DB0xf0
DW9
DW18
DW2
DD0
DD2880
DB0,0,0x29
DD0xffffffff
DB"UCAN23-OS "
DB"FAT12 "
RESB18
;程序主体
entry:
MOVAX, 0;初始化寄存器
MOVSS, AX
MOVSP, 0x7c00
MOVDS, AX
;读磁盘
MOVAX, 0x0820
MOV ES, AX
MOVCH, 0
MOVDH, 0
MOVCL, 2
readloop:
MOVSI, 0 ;记录失败次数的寄存器
retry:
MOVAH, 0x02
MOVAL, 1
MOVBX, 0
MOVDL, 0x00
INT0x13
JNCnext
ADDSI, 1
CMPSI, 5
JAEerror
MOVAH, 0x00
MOVDL, 0x00
INT0x13
JMPretry
;JMPerror

next:
MOVAX, ES
ADDAX, 0x0020
MOVES, AX
ADDCL, 1
CMPCL, 18
JBEreadloop
MOVCL, 1
ADD DH, 1
CMPDH, 2
JBreadloop
MOVDH, 0
ADDDH, 1
CMPCH, CYLS
JBreadloop

MOV[0x0ff0], CH
JMP0xc200

error:
MOVSI, msg
putloop:
MOVAL, [SI]
ADDSI, 1
CMPAL, 0
JEfin
MOVAH, 0x0e
MOVBX, 15
INT0x10
JMPputloop
fin:
HLT
JMPfin

;信息显示部分
msg:
DB0x0a, 0x0a;2个换行
DB"Hello, world(ucan23)"
DB0x0a
DB"This is my first OS"
DB0x0a
DB"Copyright GPL"
DB0x0a
DB"Author: ucan23(Howard)"
DB0x0a
DB"Blog:http://blog.sina.com/rjxx007"
DB0x0a
DB"Blog:http://blog.csdn.net/ucan23"
DB0x0a
DB0

RESB0x7dfe-$
DB0x55, 0xaa

最后是Makefile文件:

TOOLPATH = ../tolset/z_tools/
INCPATH = ../tolset/z_tools/haribote/

MAKE = $(TOOLPATH)make.exe -r
NASK = $(TOOLPATH)nask.exe
CC1 = $(TOOLPATH)cc1.exe -I$(INCPATH) -Os -Wall -quiet
GAS2NASK = $(TOOLPATH)gas2nask.exe -a
OBJ2BIM = $(TOOLPATH)obj2bim.exe
BIM2HRB = $(TOOLPATH)bim2hrb.exe
RULEFILE = $(TOOLPATH)haribote/haribote.rul
EDIMG = $(TOOLPATH)edimg.exe
IMGTOL = $(TOOLPATH)imgtol.com
COPY = copy
DEL = del

default:
$(MAKE) img
ucan23ipl.bin: ucan23ipl.nas Makefile
$(NASK) ucan23ipl.nas ucan23ipl.bin ucan23ipl.lst

ucan23.bin: ucan23.nas Makefile
$(NASK) ucan23.nas ucan23.bin ucan23.lst
bootpack.gas: bootpack.c Makefile
$(CC1) -o bootpack.gas bootpack.c

bootpack.nas: bootpack.gas Makefile
$(GAS2NASK) bootpack.gas bootpack.nas

bootpack.obj: bootpack.nas Makefile
$(NASK) bootpack.nas bootpack.obj bookpack.lst

naskfunc.obj: naskfunc.nas Makefile
$(NASK) naskfunc.nas naskfunc.obj naskfunc.lst

bootpack.bim: bootpack.obj naskfunc.obj Makefile
$(OBJ2BIM) @$(RULEFILE) out:bootpack.bim stack:3136k map:bootpack.map \
bootpack.obj naskfunc.obj

bootpack.hrb: bootpack.bim Makefile
$(BIM2HRB) bootpack.bim bootpack.hrb 0

ucan23.sys: ucan23ipl.bin bootpack.hrb Makefile
copy /B ucan23ipl.bin+bootpack.hrb ucan23.sys

ucan23.img: ucan23ipl.bin ucan23.sys Makefile
$(EDIMG) imgin:../tolset/z_tools/fdimg0at.tek \
wbinimg src:ucan23ipl.bin len:512 from:0 to:0 \
copy from:ucan23.sys to:@: \
imgout:ucan23.img

asm:
$(MAKE) ucan23ipl.bin

img:
$(MAKE) ucan23.img

run:
$(MAKE) img
$(COPY) ucan23.img ..\tolset\z_tools\qemu\fdimage0.bin
$(MAKE) -C ../tolset/z_tools/qemu

install:
$(MAKE) img
$(IMGTOL) w a: ucan23.img

clean:
-$(DEL) *.bin
-$(DEL) *.lst
-$(DEL) *.gas
-$(DEL) *.obj
-$(DEL) bootpack.nas
-$(DEL) bootpack.map
-$(DEL) bootpack.bim
-$(DEL) bootpack.hrb
-$(DEL) ucan23.sys

src_only:
$(MAKE) clean
-$(DEL) ucan23.img