⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootf.asm

📁 John Fine的OS模型// 源代码// C & ASM// 英文
💻 ASM
📖 第 1 页 / 共 2 页
字号:
; bootf.asm  FAT12 floppy bootstrap for protected mode image
; Version 2.0, May 1, 1999
; Sample code
; by John S. Fine  johnfine@erols.com
; I do not place any restrictions on your use of this source code
; I do not provide any warranty of the correctness of this source code
;_____________________________________________________________________________
;
; Documentation:
;
;   1)  Most of the documentation is in comments at the END of this file.
;   2)  Some is in the read.me file that came with this file.
;   3)  In the comments within the source code are several uses of {}, each
;       of these indicates a section of documentation at the end of this file
;       which applies to that part of the source code.
;   4)  The major way I reduced code size was to rely on left-over values in
;       registers and/or to initialize registers at points where doing so was
;       cheap.  To make that understandable, there are several lines beginning
;       with either ";>" or ";>>".  These lines describe the register contents
;       at that point in the code.  ";>" indicates that the value is required
;       by the next section of code.  ";>>" indicates that the value passes
;       through the next section unmodified and is needed later.
;    5) I made this code by modifying my bootp example.  If something doesn't
;       make sense here, maybe comparison to the other version will help.
;_____________________________________________________________________________
;
; Limitations:
;
;    For simplicity, I made several assumptions about the environment.  Some
; of those may need to be expanded in a future version.  Except for the first,
; they are all things that could be checked by a "SYS" program that installs
; this bootstrap.  In general it makes more sense (where possible) for a SYS
; program to check compatibility issues than for a bootstrap to check them
; itself.
;
;    If these limits are violated, this code simply bombs.  It does not check
; the limits nor display error messages.
;
; 1) Runs only on a 386+
; 2) The FAT structure must be the first thing on the drive (no partitions).
;    It just uses "reserved" sectors before the FAT, not "hidden" etc.
; 3) The sector size must be 512 bytes
; 4) There are less than 256 sectors per fat (safe, since FAT12 has less than
;    4096*1.5 bytes per FAT).
; 5) LBN of root directory less than 65536 (safe in unpartitioned FAT12)
;_____________________________________________________________________________

	%include "gdt.inc"

	struc	BB		;FAT Boot block
		resb	0xD	;Things we ignore
BB_clu		resb	1	;Sectors per cluster
BB_res		resw	1	;Reserved sectors
BB_fats		resb	1	;Number of FATs
BB_root		resw	1	;Root directory entries
		resb	3	;Things we ignore
BB_fat		resw	1	;Sectors per fat
BB_sec		resw	1	;Sectors per track
BB_head		resw	1	;Heads
	endstruc

SEGMENT	START USE16

;>   cs = 0
;>>  dl = drive we were booted from

boot:	jmp short start			;Standard start of boot sector
	nop
	resb	0x3B			;Skip over parameters (set by format)

start:	cli				;{0}
	lgdt	[cs:gdt]		;Load GDT
	mov	ecx, CR0		;Switch to protected mode
	inc	cx
	mov	CR0, ecx		;{5}
.5:	in	al, 0x64		;Enable A20 {4A}
	test	al, 2
	jnz	.5
	mov	al, 0xD1
	out	0x64, al
.6:	in	al, 0x64
	and	ax, byte 2
	jnz	.6
	mov	al, 0xDF
	out	0x60, al

;>   ah = 0
;>   dl = drive we were booted from

	mov	al, flat_data		;Selector for 4Gb data seg
	mov	ds, ax			;{2} Extend limit for ds
	mov	es, ax			;Extend limit for es
	dec	cx			;Switch back to real mode
	mov	CR0, ecx		;{5}

	mov	[boot], dl		;Save drive number we came from
	mov	sp, 0x800		;{1B}

	xor	eax, eax		;Segment
	mov	ds, ax			;
	mov	ss, ax
	mov	es, sp			;Read directory at 800:0 {1C}

;>   eax = 00000000

	mov	al, [boot+BB_fats]	;Number of FATs
	mul	byte [boot+BB_fat]	;Times size of FAT
	add	ax, [boot+BB_res]	;Plus Sectors before first FAT
					;eax = LBN of Root directory
	movzx	edi,word [boot+BB_root]	;Root directory entries
	push	di			; used again later
	dec	di			;Convert to number of sectors
	shr	di, 4			;  16 directory entries per sector
	inc	di
	call	read_sectors

;>  eax  = LBN of root directory
;>  edi  = length of root directory in sectors
;>  [sp] = length of root directory in entries
;>  esi  = 00000000

	lea	ebp, [eax+edi]		;ebp = LBN of cluster 2

	pop	bx			;Root directory entries
	xor	di, di			;Point at directory {1C}
.20:	mov	si, file_name		;Name of file we want
	xor	ecx, ecx
	mov	cl, 11
	a32 rep cmpsb			;Found the file?
	je	found			;Yes
	add	cl, 21			;Offset to next directory entry
	add	edi, ecx		;Advance to next entry
	dec	bx			;Loop through all entries
	jnz	.20

	;Couldn't find file in directory
boot_error:
disk_error:	
	mov	ax, 0xE07		;{3}
	int	10h
	jmp short $

;>> ecx   = 00000000
;> es     = 800
;> es:edi = Directory entry of file
;> ebp    = LBN of cluster 2
;> eax    = 0000????

found:	push	word [es:edi+0xF]	;Starting cluster of file
	mov	di, [boot+BB_fat]	;Size of FAT (in sectors)
	mov	ax, [boot+BB_res]	;LBN of FAT
	call	read_sectors

	mov	bx, 0x4000
	mov	es, bx			;es = 0x4000
	mov	edi, 0x100000-0x40000	;{1D}{4B} One megabyte minus ES base
.10:

;>>    ecx = 0000????
;>    [sp] = Next cluster of file
;>     esi = 0000????
;>>    edx = 0000????
;>  es:edi = Destination address
;>     ebp = LBN of cluster 2
;>      ds = 0

	xor	eax, eax
	pop	si			;Next cluster of file
	mov	bx, si
	cmp	si, 0xFF8		;Valid cluster?
	jae	eof			;No: assume end of file
					;Yes: (c-bit set)
	rcr	bx, 1			;bx = 0x8000 + cluster/2
	mov	bx, [bx+si]		;Get word containing FAT entry
	jnc	.11			;Entry is low 12 bits
	shr	bx, 4			;Entry was high 12 bits
.11:	and	bh, 0xF			;Mask to just 12 bits
	push	bx			;Save cluster after next
	push	di			;Save destination address {7}
	mov	al, [boot+BB_clu]	;Size of each cluster
	mov	di, ax			;  (in sectors)
	dec	si
	dec	si
	mul	esi			;Times cluster number minus 2
	add	eax, ebp		;Plus LBN of cluster 2	
	call	read_sectors		;Read that cluster

;>     ecx = 0000????
;>>    edx = 0000????
;>      di = Clustersize in sectors
;>     esi = 0
;>>    ebp = LBN of cluster 2
;>    [sp] = Bottom 16-bits of destination address {7}
;>> [sp+2] = Following cluster
;>      ds = 0
;>      es = 4000

	mov	cx, di			;Cluster size in sectors
	xchg	ch, cl			;Cluster size in words
	pop	di			;Restore destination address {7}
	es a32 rep movsw
	jmp short .10			;Loop until end of file

;>     eax = 0
;>     edx = 0000????
;>      bx = 0FF?

eof:
	mov	dx, 0x9C00
	mov	es, dx			;es = 9C00
	xor	di, di			;{1E} Address of page tables WRT es
	mov	dh, 4096/256		;edx = 4096
.10:	mov	cx, 1024
	mov	al, 7
.20:	stosd
	add	eax, edx
	int	8			;{8}
	loop	.20
	shr	eax, 2			;{4C} (first time only) 4Mb / 4 = 1Mb
	neg	bl			;Done just one page?
	jns	.10			;Yes: do one more

	cli				;{6}

	mov	eax, 0x9C007		;First page tbl pointer in page dir

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -