读书笔记《30天自制操作系统》day03

原文地址:http://blog.csdn.net/ltbylc/article/details/8292922

0. 自己试着在win7下用NASM和minGW改写汇编和C混合编程,结果受挫了。还是先使用作者提供的工具构建吧。

1. 通过前2天的工作已经能使用NASM制作一个映像了,并且编写的汇编代码可以成为引导扇区代码。

2. 引导扇区代码中可以调用BIOS中断,读取软盘上其它扇区到内存中,根据FAT12文件系统格式得知,保存到软盘内的第一个文件的文件名一定从19逻辑扇区开始,且该文件的内容从逻辑扇区33开始。

3. 引导扇区可以将第一个保存的文件(kernel.sys=自己改的名字,功能是跳入保护模式并调用C语言编写的函数代码)读入内存并使之执行,找这个文件用到了一个技巧,不然通过文件系统结构分析出文件位置,并加载码就太复杂了。

4. 引导扇区代码如下ipl10.asm

; haribote-ipl
; TAB=4

CYLS	EQU		10				

		ORG		0x7c00			

		JMP		entry
		DB		0x90
		DB		"HARIBOTE"		
		DW		512				
		DB		1				
		DW		1				
		DB		2				
		DW		224				
		DW		2880			
		DB		0xf0			
		DW		9				
		DW		18				
		DW		2				
		DD		0				
		DD		2880			
		DB		0,0,0x29		
		DD		0xffffffff		
		DB		"HARIBOTEOS "	
		DB		"FAT12   "		
		RESB	18				



entry:
		MOV		AX,0			
		MOV		SS,AX
		MOV		SP,0x7c00
		MOV		DS,AX


		MOV		AX,0x0820
		MOV		ES,AX
		MOV		CH,0			
		MOV		DH,0			
		MOV		CL,2			
readloop:
		MOV		SI,0			
retry:
		MOV		AH,0x02			
		MOV		AL,1			
		MOV		BX,0
		MOV		DL,0x00			
		INT		0x13			
		JNC		next			
		ADD		SI,1			
		CMP		SI,5			
		JAE		error			
		MOV		AH,0x00
		MOV		DL,0x00			
		INT		0x13			
		JMP		retry
next:
		MOV		AX,ES			
		ADD		AX,0x0020
		MOV		ES,AX			
		ADD		CL,1			
		CMP		CL,18			
		JBE		readloop		
		MOV		CL,1
		ADD		DH,1
		CMP		DH,2
		JB		readloop		
		MOV		DH,0
		ADD		CH,1
		CMP		CH,CYLS
		JB		readloop		


		MOV		[0x0ff0],CH		
		JMP		0xc200

error:
		MOV		SI,msg
putloop:
		MOV		AL,[SI]
		ADD		SI,1			
		CMP		AL,0
		JE		fin
		MOV		AH,0x0e			
		MOV		BX,15			
		INT		0x10			
		JMP		putloop
fin:
		HLT						
		JMP		fin				
msg:
		DB		0x0a, 0x0a		
		DB		"load error"
		DB		0x0a			
		DB		0

		;RESB	0x7dfe-$		
		times 510-($-$$) db 0

		DB		0x55, 0xaa


 

5. 跳入保护模式代码如下asmhead.nas

(1)准备GDT

(2)用LGDT加载gdtr

(3)打开A20

(4)设置CR0的PE位

(5)跳转进入保护模式

; haribote-os boot asm
; TAB=4

BOTPAK	EQU		0x00280000		
DSKCAC	EQU		0x00100000		
DSKCAC0	EQU		0x00008000		


CYLS	EQU		0x0ff0			
LEDS	EQU		0x0ff1
VMODE	EQU		0x0ff2			
SCRNX	EQU		0x0ff4			
SCRNY	EQU		0x0ff6			
VRAM	EQU		0x0ff8			

		ORG		0xc200	 ;让引导扇区加载后从这里开始运行		



		MOV		AL,0x13		;保存信息	
		MOV		AH,0x00
		INT		0x10
		MOV		BYTE [VMODE],8	
		MOV		WORD [SCRNX],320
		MOV		WORD [SCRNY],200
		MOV		DWORD [VRAM],0x000a0000


		MOV		AH,0x02
		INT		0x16 			; keyboard BIOS
		MOV		[LEDS],AL


		MOV		AL,0xff
    		OUT		0x21,AL
		NOP						
		OUT		0xa1,AL

		CLI						



		CALL	waitkbdout
		MOV		AL,0xd1
		OUT		0x64,AL
		CALL	waitkbdout
		MOV		AL,0xdf			; enable A20
		OUT		0x60,AL
		CALL	waitkbdout


[INSTRSET "i486p"]				

		LGDT	[GDTR0]			
		MOV		EAX,CR0
		AND		EAX,0x7fffffff	
		OR		EAX,0x00000001	
		MOV		CR0,EAX
		JMP		pipelineflush
pipelineflush:
		MOV		AX,1*8			
		MOV		DS,AX
		MOV		ES,AX
		MOV		FS,AX
		MOV		GS,AX
		MOV		SS,AX



		MOV		ESI,bootpack	
		MOV		EDI,BOTPAK		
		MOV		ECX,512*1024/4
		CALL	memcpy



		MOV		ESI,0x7c00		
		MOV		EDI,DSKCAC		
		MOV		ECX,512/4
		CALL	memcpy


		MOV		ESI,DSKCAC0+512	
		MOV		EDI,DSKCAC+512	
		MOV		ECX,0
		MOV		CL,BYTE [CYLS]
		IMUL	ECX,512*18*2/4	
		SUB		ECX,512/4		
		CALL	memcpy


		MOV		EBX,BOTPAK
		MOV		ECX,[EBX+16]
		ADD		ECX,3			
		SHR		ECX,2			
		JZ		skip			
		MOV		ESI,[EBX+20]	
		ADD		ESI,EBX
		MOV		EDI,[EBX+12]	
		CALL	memcpy
skip:
		MOV		ESP,[EBX+12]	
		JMP		DWORD 2*8:0x0000001b

waitkbdout:
		IN		 AL,0x64
		AND		 AL,0x02
		JNZ		waitkbdout		
		RET

memcpy:
		MOV		EAX,[ESI]
		ADD		ESI,4
		MOV		[EDI],EAX
		ADD		EDI,4
		SUB		ECX,1
		JNZ		memcpy			
		RET


		ALIGNB	16
GDT0:
		RESB	8				
		DW		0xffff,0x0000,0x9200,0x00cf	
		DW		0xffff,0x0000,0x9a28,0x0047	

		DW		0
GDTR0:
		DW		8*3-1
		DD		GDT0

		ALIGNB	16
bootpack:

6. C语言代码如下bootpack.c

void io_hlt(void);
void write_mem8(int addr,int data);
void HariMain(void)
{
	int i;
	for(i=0xa0000;i<=0xaffff;i++)
	{
		write_mem8(i,15);
	}
	for(;;)
	{
		io_hlt();
	}

}


7. C语言中调用的io_hlt和write_mem8函数放到了如下代码中func.asm

[FORMAT "WCOFF"]				
[INSTRSET "i486p"]			
[BITS 32]						
[FILE "naskfunc.nas"]			
global _io_hlt,_write_mem8
[section .text]
;void io_hlt(void);
_io_hlt:
	HLT
	RET
	
;void write_mem8(int addr,int data);
_write_mem8:
	MOV ECX,[ESP+4]
	MOV AL,[ESP+8]
	MOV [ECX],AL
	RET

8. 在toolset文件夹内建立一个新文件夹,将上面所有的文件放在里边,编译链接接上面的文件,写个bat文件如下

nasm -o ipl10.bin ipl10.asm
nasm -o img.img img.asm
..\z_tools\nask.exe asmhead.nas asmhead.bin
..\z_tools\cc1.exe -I..\z_tools\haribote\ -Os -Wall -quiet -o bootpack.gas bootpack.c
..\z_tools\gas2nask.exe -a bootpack.gas bootpack.nas
..\z_tools\nask.exe bootpack.nas bootpack.obj
..\z_tools\nask.exe func.asm func.obj
..\z_tools\obj2bim.exe @..\z_tools\haribote\haribote.rul out:bootpack.bim stack:3136k map:bootpack.map bootpack.obj func.obj
..\z_tools\bim2hrb.exe bootpack.bim bootpack.hrb 0
copy /B asmhead.bin+bootpack.hrb kernel.sys


9.这样除了中间文件外,生成img.img文件和kernel.sys文件。使用winImage打开img.img文件将kernel.sys文件加入到该img文件中。

10. 启动Bochs,呵呵看见屏幕白了,这可是从C代码里控制的啊!

11. asmhead中跳入保护模式的代码慢慢在深入掌握,不然会掉入细节里不能自拔了。

12. asmhead和C代码是通过copy /B进行链接的其中asmhead代码最后留了个标号bootpack,在这个标号后面C的目标代码被砍去文件头直接将代码链接到了这里,所以能实现从汇编跳转到C语言的目的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值