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

📄 grldrstart.s

📁 grub4dos-0.4.4-2008- 08-src.zip
💻 S
📖 第 1 页 / 共 5 页
字号:
	. = Entry_12_16 + 0x36	.ascii	"FAT12   "	/* filesystem ID *//*;       bp is initialized to 7c00h%define bsOemName       bp+0x03      ; OEM label%define bsBytesPerSec   bp+0x0b      ; bytes/sector%define bsSecPerClust   bp+0x0d      ; sectors/allocation unit%define bsResSectors    bp+0x0e      ; # reserved sectors%define bsFATs          bp+0x10      ; # of fats%define bsRootDirEnts   bp+0x11      ; # of root dir entries%define bsSectors       bp+0x13      ; # sectors total in image%define bsMedia         bp+0x15      ; media descrip: fd=2side9sec, etc...%define sectPerFat      bp+0x16      ; # sectors in a fat%define sectPerTrack    bp+0x18      ; # sectors/track%define nHeads          bp+0x1a      ; # heads%define nHidden         bp+0x1c      ; # hidden sectors%define nSectorHuge     bp+0x20      ; # sectors if > 65536%define drive           bp+0x24      ; drive number			bp+0x25      ; partition number for GRLDR%define extBoot         bp+0x26      ; extended boot signature%define volid           bp+0x27%define vollabel        bp+0x2b%define filesys         bp+0x36%define RootDirSecs     bp+0x26         ; # of sectors root dir uses					; (overwriting unused bytes)%define fat_start       bp+0x28         ; first FAT sector					; (overwriting unused bytes)%define root_dir_start  bp+0x2c         ; first root directory sector					; (overwriting unused bytes)%define data_start      bp+0x30         ; first data sector					; (overwriting unused bytes)%define data_clusters   bp+0x34         ; # of clusters in data area					; (overwriting unused bytes)			bp+0x36		; bytes per FAT( > 0x1800 means FAT16)					; (overwriting unused bytes)*/		/* not used: [0x26] = byte 0x29 (ext boot param flag)		 * [0x27] = dword serial		 * [0x2b] = label (padded with 00, 11 bytes)		 * [0x36] = "FAT12" or "FAT16",32,32,32 (not used by Windows)		 * ([0x3e] is where FreeDOS parts start)		 */	. = Entry_12_16 + 0x3e1:	cli	cld#ifdef	BOOTGRUB	. = Entry_12_16 + 0x40	/* the byte at offset 0x41 stores the real partition number for read.	 * the format program or the caller should set it to a correct value.	 * For floppies, it should be 0xff, which stands for whole drive.	 */	movb	$0xff, %dh	/* boot partition number */	cmpb	$0xff, %dh	/* is floppy? */	jne	1f	movb	$0, %dl		/* yes, let drive number = 0 */1:#endif	xorw	%ax, %ax	movw	$0x7c00, %bp#ifdef	BOOTGRUB	movw	%ax, %ss	/* stack and BP-relative moves up, too */	leaw	-0x20(%bp), %sp	sti			/* after stack setup, we can use stack */	movw	%dx, 0x24(%bp)	/* BIOS passes drive number in DL */	pushaw			/* AX=0 */	movb	$0x41, %ah	movw	$0x55AA, %bx	int	$0x13	pushw	%ss		/* SS=0 */	popw	%ds		/* DS=0 */	jc	1f		/* No EBIOS */	cmpw	$0xAA55, %bx	jne	1f		/* No EBIOS */	testb	$1, %cl	jz	1f		/* No EBIOS */	/* EBIOS supported */	movb	$0x42, (ebios_12_16 - 1 - Entry_12_16 + 0x7c00)1:	popaw			/* AX=0 */	movw	%ax, %es	/* ES=0 */	/* AX=SS=DS=ES=0, BP=0x7C00 */#else	movw	%ax, %ds	movw	%bp, %si	/* move from 0000:7c00 */	movw	%bp, %di	/* move to 1fe0:7c00 */	movb	%dl, 0x24(%si)	/* BIOS passes drive number in DL *///	xchgw	%ax, %dx	/* let DX = 0 */	movw	$0x1fe0, %ax	movw	%ax, %es	movw	$0x0100, %cx	/* one sector to move */	repz movsw				/* CX = 0 */	ljmp	$0x1fe0, $(1f - Entry_12_16 + 0x7c00)1:	movw	%ax, %ss	/* stack and BP-relative moves up, too */	leaw	-0x20(%bp), %sp	sti			/* after stack setup, we can use stack */	pushw	%ax		/* AX=0x1FE0 */	movb	$0x41, %ah	movw	$0x55AA, %bx	int	$0x13	popw	%ds		/* DS=0x1FE0 */	jc	1f		/* No EBIOS */	cmpw	$0xAA55, %bx	jne	1f		/* No EBIOS */	testb	$1, %cl	jz	1f		/* No EBIOS */	/* EBIOS supported */	movb	$0x42, (ebios_12_16 - 1 - Entry_12_16 + 0x7c00)1:	xorw	%ax, %ax	/* AX=0 */#endif	/* GET DRIVE PARMS: Calculate start of some disk areas */1:#if 0	.arch	i486, nojumps	movzwl	0x0e(%bp), %ebx	/* reserved sectors */	addl	0x1c(%bp), %ebx	/* hidden sectors */	movl	%ebx, 0x28(%bp)	/* ---- FAT start */	movzbl	0x10(%bp), %eax	/* number of FATs */	movzwl	0x16(%bp), %ecx	/* sectors per FAT */	mull	%ecx		/* EDX=0, EAX=total sectors for FAT */	addl	%eax, %ebx	movl	%ebx, 0x2c(%bp)	/* ---- RootDir start */	/* Calculate how many sectors the root directory occupies */	movzwl	0x0b(%bp), %ecx	/* bytes per sector, should be 512 */	movzwl	0x11(%bp), %eax	/* max number of RootDir entries */	shll	$5, %eax	/* total bytes RootDir occupies */	addl	%ecx, %eax	decl	%eax	/* xorl	%edx, %edx */	/* EDX=0 */	divl	%ecx		/* EAX=AX=sectors for RootDir */	movw	%ax, 0x26(%bp)	/* sectors for RootDir */	addl	%eax, %ebx	movl	%ebx, 0x30(%bp)	/* ---- DataArea start */	. = . - (. - 1b)/66	.arch	i186, nojumps#else	movw	0x1c(%bp), %si	/* number of hidden sectors(lo) */	movw	0x1e(%bp), %di	/* number of hidden sectors(hi) */	addw	0x0e(%bp), %si	/* number of reserved sectors */	adcw	%ax, %di	/* DI:SI = first FAT sector */				/* AX = 0 */	movw	%si, 0x28(%bp)	/* FAT start sector(lo) */	movw	%di, 0x2a(%bp)	/* FAT start sector(hi) */	//xchgw	%ax, %dx	/* let AX = 0 */	movb	0x10(%bp), %al	/* number of FATs */	/* cbw */	mulw	0x16(%bp)	/* sectors per FAT */				/* DX:AX = total number of FAT sectors */				/* DX = 0 since no too many FAT sectors */	addw	%ax, %si	adcw	%dx, %di	/* DI:SI = root directory start sector */	movw	%si, 0x2c(%bp)	/* root directory starting sector(lo) */	movw	%di, 0x2e(%bp)	/* root directory starting sector(hi) */	/* Calculate how many sectors the root directory occupies */	movw	0x0b(%bp), %bx	/* bytes per sector */	movb	$5, %cl		/* divide BX by 32 */	shrw	%cl, %bx	/* BX = directory entries per sector */	movw	0x11(%bp), %ax	/* max number of root dir entries */	addw	%bx, %ax	decw	%ax	/* xorw	%dx, %dx */	/* assuming DX = 0 */	divw	%bx		/* AX = sectors per root directory */	cwd			/* DX = 0 */	movw	%ax, 0x26(%bp)	/* number of sectors the root dir occupies */	addw	%ax, %si	/* DI:SI = first data sector */	adcw	%dx, %di	/* assuming DX = 0 */	movw	%si, 0x30(%bp)	/* data starting sector(lo) */	movw	%di, 0x32(%bp)	/* data starting sector(hi) */	. = . - (. - 1b)/63#endif#ifdef USE_TOTAL_CLUSTERS	movw	0x13(%bp), %cx	/* total sectors(small) */	jcxz	1f	movw	%cx, 0x20(%bp)	/* total sectors(large)(lo) */	movw	%dx, 0x22(%bp)	/* total sectors(large)(hi), assuming DX = 0 */1:		movw	0x20(%bp), %ax	/* total sectors(large) */	movw	0x22(%bp), %bx	addw	0x1c(%bp), %ax	/* number of hidden sectors */	adcw	0x1e(%bp), %bx	subw	%si, %ax	/* data starting sector */	sbbw	%di, %bx	/* BX:AX = total sectors in the data area */	movb	0x0d(%bp), %dl	/* sectors per cluster(DH=0) */	xchgw	%bx, %dx	/* DX:AX = total sectors in the data area */				/* BX = sectors per cluster */	divw	%bx		/* AX = total clusters in the data area */	movw	%ax, 0x34(%bp)	/* total clusters in the data area */#else	movw	$0xffff, 0x36(%bp)	/* bytes per FAT( > 0x1800 means FAT16) */	movw	0x16(%bp), %ax	/* sectors per FAT */	mulw	0x0b(%bp)	/* bytes per sector */	jc	1f	movw	%ax, 0x36(%bp)1:#endif	/* Searches for the file in the root directory	 *	 * Returns:	 *	AX = first cluster of file	 */	/* First, read the whole root directory into the temporary buffer */	movw	0x2c(%bp), %ax	/* root directory starting sector(lo) */	movw	0x2e(%bp), %dx	/* root directory starting sector(hi) */	movw	0x26(%bp), %cx	/* number of sectors the root dir occupies */	lesw	(loadseg_off_12_16 - Entry_12_16)(%bp), %bx				/* ES:BX = loadseg:0 *///	pushw	%es	call	readDisk_12_16	/* CX=0, AX,DX,ES changed *///	popw	%es	lesw	(loadseg_off_12_16 - Entry_12_16)(%bp), %di				/* ES:DI = loadseg:0 */	/* Search for kernel file name, and find start cluster */	/* BX=0, CX=0 *///	pushw	%cx//	popw	%di1:	movw	$(filename_12_16 - Entry_12_16 + 0x7c00), %si	/* filename */	movb	$11, %cl	/* length of kernel filename */	pushw	%di	repz cmpsb	popw	%di	jz	1f	addw	$0x20, %di	/* next entry */	jz	2f		/* or jc 2f, exceeding 64K */	/* if the entry begins in 0, this also ends the dir. */	cmpb	%ch, %es:(%di)	/* CH=0 */	jnz	1b2:	movw	$(msg_BootError_12_16 - Entry_12_16 + 0x7c00), %si	jmp	boot_error_12_16	/* fail if not found */#ifndef ALTERNATIVE_KERNELloadseg_off_12_16:	.word	0loadseg_seg_12_16:	.word	LOADSEG_12_16#endif1:/****************************************************************************/	/* BX=0, CX=0 */	######################################################################	# Reads the FAT chain and stores it in a temporary buffer in the	# first 64KB.  The FAT chain is stored an array of 16-bit cluster	# numbers, ending with 0.	#	# The file must fit in conventional memory, so it can't be larger	# than 640KB. The sector size must be at least 512 bytes, so the	# FAT chain can't be larger than around 3KB.	######################################################################	/********************************************************************/	/* First, load the complete FAT into memory. The FAT can't be       */	/* larger than 128KB, so it should fit in the temporary buffer.     */	/********************************************************************/	pushw	%es:0x1a(%di)	/* save first cluster number of file *///	lesw	(loadseg_off_12_16 - Entry_12_16)(%bp), %bx//				/* ES:BX = loadseg:0 */	movw	0x16(%bp), %cx	/* sectors per FAT */	movw	0x28(%bp), %ax	/* FAT start sector(lo) */	movw	0x2a(%bp), %dx	/* FAT start sector(hi) */	pushw	%es		/* ES=0x2000 */	call	readDisk_12_16	/* CX=0, AX,DX,ES changed */	popw	%ds		/* DS=0x2000 */	popw	%ax		/* restore first cluster number of file */	/********************************************************************/	/* Then, extract the clusters of the file from the FAT              */	/********************************************************************/	/* Set ES:DI to the temporary storage for the FAT chain */	pushw	%ds		/* ES=0x2000 */	pushw	%ss	popw	%es	movw	$FATBUF, %di	/* BX=0, CX=0 */2:	stosw			/* store cluster number */	movw	%ax, %si	/* SI = cluster number */	//////////////////////////////////////////////////////////////	//	// FAT16 can occupy 128KB, so the segment must be adjusted	//	//////////////////////////////////////////////////////////////	popw	%dx		/* DX=0x2000, segment for FAT16 */	pushw	%dx	addw	%si, %si	/* multiply cluster number by two */	jnc	1f	addb	$0x10, %dh	/* overflow. Add 0x1000 to segment value */1:#ifdef USE_TOTAL_CLUSTERS	cmpw	$0x0ff7, 0x34(%bp)	/* total clusters in the data area */#else	cmpw	$0x1801, 0x36(%bp)	/* bytes per FAT */#endif	jnb	3f	/******** FAT12 ********/	addw	%ax, %si	/* multiply cluster number by 3 ... */	shrw	$1, %si		/* ... and divide by 2 */	lodsw	/* If the cluster number was even, the cluster value is now in	 * bits 0-11 of AX. If the cluster number was odd, the cluster	 * value is in bits 4-15, and must be shifted right 4 bits. If	 * the number was odd, CF was set in the last shift instruction.	 */	jnc	1f	movb	$4, %cl		/* CL=4 */	shrw	%cl, %ax1:	andb	$0x0f, %ah	/* mask off the highest 4 bits */	cmpw	$0x0ff7, %ax	/* check for EOF */	jmp	4f3:	/******** FAT16 ********/	movw	%dx, %ds	/* DS:SI points to next cluster */	lodsw			/* AX = next cluster */	cmpw	$0xfff7, %ax	/* check for EOF */4:	jbe	2b		/* continue if not EOF */	/* Mark end of FAT chain with 0, so we have a single	 * EOF marker for both FAT12 and FAT16 systems.	 */	xorw	%ax, %ax	stosw/****************************************************************************/	/* Load the file into memory, one cluster at a time */	popw	%es		/* ES=0x2000 *///	lesw	(loadseg_off_12_16 - Entry_12_16)(%bp), %bx//				/* ES:BX = loadseg:0 */	pushw	%ss	popw	%ds		/* DS=SS */	movw	$FATBUF, %si	/* set DS:SI to the FAT chain */1:	/* CH=0 */	lodsw			/* AX = next cluster to read */	subw	$2, %ax		/* cluster numbers start with 2 */	jc	1f		/* the cluster should be 0 for EOC */	movb	0x0d(%bp), %cl	/* CH=0, CX=sectors per cluster */	mulw	%cx	addw	0x30(%bp), %ax	/* data starting sector(lo) */	adcw	0x32(%bp), %dx	/* data starting sector(hi) */				/* DX:AX = first sector to read */	call	readDisk_12_16	/* CX=0, AX,DX,ES changed */	jmp	1b		/* read next cluster */1:	/* EOC encountered - done */#ifdef	BOOTGRUB	movw	0x24(%bp), %dx	/* boot_drive and boot_partition */#else	movb	0x24(%bp), %bl	/* FreeDOS kernel uses BL, not DL, for drive */#endif	ljmp	*(loadseg_off_12_16 - Entry_12_16)(%bp)	/* boot it! *//****************************************************************************//* Read a number of sectors into memory. * * Call with:	DS=SS *		DX:AX = 32-bit DOS sector number *		   CX = number of sectors to read * 		ES:BX = destination buffer * * Returns:	CX=0 *		ES increased, BX untouched *		ES:BX points one byte after the last byte read. * 		DX:AX = next sector number after read *		All other registers preserved */ readDisk_12_16:2:	pushfw	pushaw	xorw	%cx, %cx	pushw	%cx		/* hi word of hi dword */	pushw	%cx		/* lo word of hi dword */	pushw	%dx		/* hi word of lo dword */	pushw	%ax		/* lo word of lo dword */	pushw	%es		/* buffer segment */	pushw	%bx		/* buffer offset */	incw	%cx	pushw	%cx		/* 1 sector to read */	movb	$16, %cl	pushw	%cx		/* size of this parameter block */	xchgw	%ax, %cx	/* save AX to CX */	/*	 * translate sector number to BIOS parameters	 *	 * LBA = sector-1			offset in track	 *     + head * sectPerTrack		offset in cylinder	 *     + cyl * sectPerTrack * nHeads	offset in platter	 *	 */#if 1	pushw	%bx	pushw	%dx	movw	0x18(%bp), %ax	/* sectors per track */	movw	%ax, %bx	mulw	0x1a(%bp)	/* nHeads */				/* DX=0, AX=sectors per cylinder */	xchgw	%ax, %cx	/* restore AX from CX, and save AX to CX */				/* CX=nHeads * sectPerTrack <= 256*63 */				/* AX=LBA lo word */	popw	%dx		/* DX:AX=LBA */#else	pushw	%bx	movw	0x18(%bp), %ax	/* sectors per track */	movw	%ax, %bx	mulb	0x1a(%bp)	/* nHeads, but maybe a word value 0x100 */	jnz	1f	movb	%bl, %ah	/* nHeads=0x100, so AX=sectPerTrack*0x100 */1:	xchgw	%ax, %cx	/* restore AX from CX, and save AX to CX */		/* DX:AX = LBA, CX = nHeads * sectPerTrack <= 256*63 */#endif	divw	%cx	 /* AX = cyl, DX = sector-1 + head * sectPerTrack */	xchgw	%ax, %dx /* DX = cyl, AX = sector-1 + head * sectPerTrack */	divb	%bl	/* sectors per track */			 /* DX = cyl, AL = head, AH = sector-1 */#if 1	xchgb	%al, %ah /* DX = cyl, AH = head, AL = sector-1 */	incw	%ax	 /* DX = cyl, AH = head, AL = sector */	xchgw	%ax, %dx /* AX = cyl, DH = head, DL = sector */	xchgw	%ax, %cx /* CX = cyl, DH = head, DL = sector */	xchgb	%cl, %ch	/* set cyl number low 8 bits in CH */	rorb	$1, %cl		/* move cyl high bits into bits 7-6 */	rorb	$1, %cl		/*	(assumes top = 0)             */	orb	%dl, %cl	/* merge sector into cylinder */#else	movw	%dx, %cx /* CX = cyl, AL = head, AH = sector-1 */	/*	 * the following manipulations are necessary in order to properly place	 * parameters into registers.	 * CH = cylinder number low 8 bits	 * CL<7-6> = cylinder high two bits	 * CL<5-0> = sector	 */	movb	%al, %dh	/* save head into DH for BIOS */	xchgb	%cl, %ch	/* set cyl number low 8 bits in CH */	rorb	$1, %cl		/* move cyl high bits into bits 7-6 */	rorb	$1, %cl		/*	(assumes top = 0)	*/	incb	%ah		/* AH = sector number */	orb	%ah, %cl	/* merge sector into cylinder */#endif	popw	%bx		movw	$0x0201, %ax	/* read 1 sector */ebios_12_16: /* ebios_12_16 - 1 points to 0x02 that can be c

⌨️ 快捷键说明

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