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

📄 asm.s

📁 i386的bootloader源码grub
💻 S
📖 第 1 页 / 共 3 页
字号:
	/* store new segment */	movw	0x4(%esp), %ax	movw	%ax, segment	shll	$4, %eax	/* generate linear address */	addl	%eax, %ebx	/* set up to pass the partition where stage2 is located in */	movl	EXT_C(current_partition), %eax	movl	%eax, (EXT_C(install_partition)-EXT_C(main))(%ebx)	/* set up to pass the drive where stage2 is located in */	movb	EXT_C(current_drive), %dl	/* set up to pass the second sector of stage2 */	movl	0xc(%esp), %ecx	call	EXT_C(prot_to_real)	.code16	movl	%ecx, %ebp#ifdef ABSOLUTE_WITHOUT_ASTERISK	DATA32	ADDR32	ljmp	(offset)#else	DATA32	ADDR32	ljmp	*(offset)#endif	.code32#endif /* STAGE1_5 */	/* *  These next two routines, "real_to_prot" and "prot_to_real" are structured *  in a very specific way.  Be very careful when changing them. * *  NOTE:  Use of either one messes up %eax and %ebp. */ENTRY(real_to_prot)	.code16	cli	/* load the GDT register */	DATA32	ADDR32	lgdt	gdtdesc	/* turn on protected mode */	movl	%cr0, %eax	orl	$CR0_PE_ON, %eax	movl	%eax, %cr0	/* jump to relocation, flush prefetch queue, and reload %cs */	DATA32	ljmp	$PROT_MODE_CSEG, $protcseg	/*	 *  The ".code32" directive only works in GAS, the GNU assembler!	 *  This gets out of "16-bit" mode.	 */	.code32protcseg:	/* reload other segment registers */	movw	$PROT_MODE_DSEG, %ax	movw	%ax, %ds	movw	%ax, %es	movw	%ax, %fs	movw	%ax, %gs	movw	%ax, %ss	/* put the return address in a known safe location */	movl	(%esp), %eax	movl	%eax, STACKOFF	/* get protected mode stack */	movl	protstack, %eax	movl	%eax, %esp	movl	%eax, %ebp	/* get return address onto the right stack */	movl	STACKOFF, %eax	movl	%eax, (%esp)	/* zero %eax */	xorl	%eax, %eax	/* return on the old (or initialized) stack! */	retENTRY(prot_to_real)	/* just in case, set GDT */	lgdt	gdtdesc	/* save the protected mode stack */	movl	%esp, %eax	movl	%eax, protstack	/* get the return address */	movl	(%esp), %eax	movl	%eax, STACKOFF	/* set up new stack */	movl	$STACKOFF, %eax	movl	%eax, %esp	movl	%eax, %ebp	/* set up segment limits */	movw	$PSEUDO_RM_DSEG, %ax	movw	%ax, %ds	movw	%ax, %es	movw	%ax, %fs	movw	%ax, %gs	movw	%ax, %ss	/* this might be an extra step */	ljmp	$PSEUDO_RM_CSEG, $tmpcseg	/* jump to a 16 bit segment */tmpcseg:	.code16	/* clear the PE bit of CR0 */	movl	%cr0, %eax	andl 	$CR0_PE_OFF, %eax	movl	%eax, %cr0	/* flush prefetch queue, reload %cs */	DATA32	ljmp	$0, $realcsegrealcseg:	/* we are in real mode now	 * set up the real mode segment registers : DS, SS, ES	 */	/* zero %eax */	xorl	%eax, %eax	movw	%ax, %ds	movw	%ax, %es	movw	%ax, %fs	movw	%ax, %gs	movw	%ax, %ss	/* restore interrupts */	sti	/* return on new stack! */	DATA32	ret	.code32/* *   int biosdisk_int13_extensions (int ax, int drive, void *dap) * *   Call IBM/MS INT13 Extensions (int 13 %ax=AX) for DRIVE. DAP *   is passed for disk address packet. If an error occurs, return *   non-zero, otherwise zero. */ENTRY(biosdisk_int13_extensions)	pushl	%ebp	movl	%esp, %ebp	pushl	%esi	pushl	%ebx	/* compute the address of disk_address_packet */	movl	0x10(%ebp), %eax	movw	%ax, %si	xorw	%ax, %ax	shrl	$4, %eax	movw	%ax, %cx	/* save the segment to cx */	/* drive */	movb	0xc(%ebp), %dl	/* ax */	movw	0x8(%ebp), %bx	/* enter real mode */	call	EXT_C(prot_to_real)		.code16	movw	%bx, %ax	movw	%cx, %ds	int	$0x13		/* do the operation */	movb	%ah, %dl	/* save return value */	/* clear the data segment */	xorw	%ax, %ax	movw	%ax, %ds	/* back to protected mode */	DATA32	call	EXT_C(real_to_prot)	.code32	movb	%dl, %al	/* return value in %eax */	popl	%ebx	popl	%esi	popl	%ebp	ret	/* *   int biosdisk_standard (int ah, int drive, int coff, int hoff, int soff, *                          int nsec, int segment) * *   Call standard and old INT13 (int 13 %ah=AH) for DRIVE. Read/write *   NSEC sectors from COFF/HOFF/SOFF into SEGMENT. If an error occurs, *   return non-zero, otherwise zero. */ENTRY(biosdisk_standard)	pushl	%ebp	movl	%esp, %ebp	pushl	%ebx	pushl	%edi	pushl	%esi	/* set up CHS information */	movl	0x10(%ebp), %eax	movb	%al, %ch	movb	0x18(%ebp), %al	shlb	$2, %al	shrw	$2, %ax	movb	%al, %cl	movb	0x14(%ebp), %dh	/* drive */	movb	0xc(%ebp), %dl	/* segment */	movw	0x20(%ebp), %bx	/* save nsec and ah to %di */	movb	0x8(%ebp), %ah	movb	0x1c(%ebp), %al	movw	%ax, %di	/* enter real mode */	call	EXT_C(prot_to_real)	.code16	movw	%bx, %es	xorw	%bx, %bx	movw	$3, %si		/* attempt at least three times */1:		movw	%di, %ax	int	$0x13		/* do the operation */	jnc	2f		/* check if successful */	movb	%ah, %bl	/* save return value */	/* if fail, reset the disk system */	xorw	%ax, %ax	int	$0x13		decw	%si	cmpw	$0, %si	je	2f	xorb	%bl, %bl	jmp	1b		/* retry */2:		/* back to protected mode */	DATA32	call	EXT_C(real_to_prot)	.code32	movb	%bl, %al	/* return value in %eax */		popl	%esi	popl	%edi	popl	%ebx	popl	%ebp	ret/* *   int check_int13_extensions (int drive) * *   Check if LBA is supported for DRIVE. If it is supported, then return *   the major version of extensions, otherwise zero. */ENTRY(check_int13_extensions)	pushl	%ebp	movl	%esp, %ebp	pushl	%ebx	/* drive */	movb	0x8(%ebp), %dl	/* enter real mode */	call	EXT_C(prot_to_real)	.code16	movb	$0x41, %ah	movw	$0x55aa, %bx	int	$0x13		/* do the operation */		/* check the result */	jc	1f	cmpw	$0xaa55, %bx	jne	1f	movb	%ah, %bl	/* save the major version into %bl */	/* check if AH=0x42 is supported if FORCE_LBA is zero */	movb	EXT_C(force_lba), %al	testb	%al, %al	jnz	2f	andw	$1, %cx	jnz	2f	1:	xorb	%bl, %bl2:	/* back to protected mode */	DATA32	call	EXT_C(real_to_prot)	.code32	movb	%bl, %al	/* return value in %eax */	popl	%ebx	popl	%ebp	ret/* *   int get_diskinfo_standard (int drive, unsigned long *cylinders,  *                              unsigned long *heads, unsigned long *sectors) * *   Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an *   error occurs, then return non-zero, otherwise zero. */ENTRY(get_diskinfo_standard)	pushl	%ebp	movl	%esp, %ebp	pushl	%ebx	pushl	%edi	/* drive */	movb	0x8(%ebp), %dl	/* enter real mode */	call	EXT_C(prot_to_real)	.code16	movb	$0x8, %ah	int	$0x13		/* do the operation */	/* check if successful */	testb	%ah, %ah	jnz	1f	/* bogus BIOSes may not return an error number */	testb	$0x3f, %cl	/* 0 sectors means no disk */	jnz	1f		/* if non-zero, then succeed */	/* XXX 0x60 is one of the unused error numbers */	movb	$0x60, %ah1:	movb	%ah, %bl	/* save return value in %bl */	/* back to protected mode */	DATA32	call	EXT_C(real_to_prot)	.code32	/* restore %ebp */	leal	0x8(%esp), %ebp		/* heads */	movb	%dh, %al	incl	%eax		/* the number of heads is counted from zero */	movl	0x10(%ebp), %edi	movl	%eax, (%edi)	/* sectors */	xorl	%eax, %eax	movb	%cl, %al	andb	$0x3f, %al	movl	0x14(%ebp), %edi	movl	%eax, (%edi)	/* cylinders */	shrb	$6, %cl	movb	%cl, %ah	movb	%ch, %al	incl	%eax		/* the number of cylinders is 				   counted from zero */	movl	0xc(%ebp), %edi	movl	%eax, (%edi)	xorl	%eax, %eax	movb	%bl, %al	/* return value in %eax */	popl	%edi	popl	%ebx	popl	%ebp	ret#if 0		/* *   int get_diskinfo_floppy (int drive, unsigned long *cylinders,  *                            unsigned long *heads, unsigned long *sectors) * *   Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an *   error occurs, then return non-zero, otherwise zero. */ENTRY(get_diskinfo_floppy)	pushl	%ebp	movl	%esp, %ebp	pushl	%ebx	pushl	%esi	/* drive */	movb	0x8(%ebp), %dl	/* enter real mode */	call	EXT_C(prot_to_real)	.code16	/* init probe value */	movl	$probe_values-1, %esi1:	xorw	%ax, %ax	int	$0x13		/* reset floppy controller */	incw	%si	movb	(%si), %cl	cmpb	$0, %cl		/* probe failed if zero */	je	2f	/* perform read */	movw	$SCRATCHSEG, %ax	movw	%ax, %es	xorw	%bx, %bx	movw	$0x0201, %ax	movb	$0, %ch	movb	$0, %dh	int	$0x13	/* FIXME: Read from floppy may fail even if the geometry is correct.	   So should retry at least three times.  */	jc	1b		/* next value */		/* succeed */	jmp	2f	probe_values:	.byte	36, 18, 15, 9, 0	2:	/* back to protected mode */	DATA32	call	EXT_C(real_to_prot)	.code32	/* restore %ebp */	leal	0x8(%esp), %ebp		/* cylinders */	movl	0xc(%ebp), %eax	movl	$80, %ebx	movl	%ebx, (%eax)	/* heads */	movl	0x10(%ebp), %eax	movl	$2, %ebx	movl	%ebx, (%eax)	/* sectors */	movl	0x14(%ebp), %eax	movzbl	%cl, %ebx	movl	%ebx, (%eax)	/* return value in %eax */	xorl	%eax, %eax	cmpb	$0, %cl	jne	3f	incl	%eax		/* %eax = 1 (non-zero) */3:	popl	%esi	popl	%ebx	popl	%ebp	ret#endif	/* Source files are splitted, as they have different copyrights.  */#ifndef STAGE1_5# include "setjmp.S"# include "apm.S"#endif /* ! STAGE1_5 */			#ifndef STAGE1_5/* get_code_end() :  return the address of the end of the code * This is here so that it can be replaced by asmstub.c. */ENTRY(get_code_end)	/* will be the end of the bss */# if defined(HAVE_END_SYMBOL)	movl	$end, %eax# elif defined(HAVE_USCORE_END_SYMBOL)	movl	$_end, %eax# endif	shrl	$2, %eax		/* Round up to the next word. */	incl	%eax	shll	$2, %eax	ret#endif /* ! STAGE1_5 *//* * * get_memsize(i) :  return the memory size in KB. i == 0 for conventional *		memory, i == 1 for extended memory *	BIOS call "INT 12H" to get conventional memory size *	BIOS call "INT 15H, AH=88H" to get extended memory size *		Both have the return value in AX. * */ENTRY(get_memsize)	push	%ebp	push	%ebx	mov	0xc(%esp), %ebx	call	EXT_C(prot_to_real)	/* enter real mode */	.code16	cmpb	$0x1, %bl	DATA32	je	xext	int	$0x12	DATA32	jmp	xdonexext:	movb	$0x88, %ah	int	$0x15xdone:	movw	%ax, %bx	DATA32	call	EXT_C(real_to_prot)	.code32	movw	%bx, %ax	pop	%ebx	pop	%ebp	ret#ifndef STAGE1_5/* * * get_eisamemsize() :  return packed EISA memory map, lower 16 bits is *		memory between 1M and 16M in 1K parts, upper 16 bits is *		memory above 16M in 64K parts.  If error, return -1. *	BIOS call "INT 15H, AH=E801H" to get EISA memory map, *		AX = memory between 1M and 16M in 1K parts. *		BX = memory above 16M in 64K parts. * */ENTRY(get_eisamemsize)	push	%ebp	push	%ebx	call	EXT_C(prot_to_real)	/* enter real mode */	.code16	movw	$0xe801, %ax	int	$0x15	shll	$16, %ebx	movw	%ax, %bx	DATA32	call	EXT_C(real_to_prot)	.code32	movl	$0xFFFFFFFF, %eax	cmpb	$0x86, %bh	je	xnoteisa	movl	%ebx, %eaxxnoteisa:	pop	%ebx	pop	%ebp	ret/* * * get_mmap_entry(addr, cont) :  address and old continuation value (zero to *		start), for the Query System Address Map BIOS call. * *  Sets the first 4-byte int value of "addr" to the size returned by *  the call.  If the call fails, sets it to zero. * *	Returns:  new (non-zero) continuation value, 0 if done. * * NOTE: Currently hard-coded for a maximum buffer length of 1024. */ENTRY(get_mmap_entry)	push	%ebp	push	%ebx	push	%edi	push	%esi	/* place address (+4) in ES:DI */	movl	0x14(%esp), %eax	addl	$4, %eax	movl	%eax, %edi	andl	$0xf, %edi	shrl	$4, %eax	movl	%eax, %esi	/* set continuation value */	movl	0x18(%esp), %ebx	/* set default maximum buffer size */	movl	$0x14, %ecx	/* set EDX to 'SMAP' */	movl	$0x534d4150, %edx	call	EXT_C(prot_to_real)	/* enter real mode */	.code16	movw	%si, %es	movl	$0xe820, %eax	int	$0x15	DATA32	jc	xnosmap	cmpl	$0x534d4150, %eax	DATA32	jne	xnosmap	cmpl	$0x14, %ecx	DATA32	jl	xnosmap	cmpl	$0x400, %ecx	DATA32	jg	xnosmap	DATA32	jmp	xsmapxnosmap:	movl	$0, %ecxxsmap:	DATA32	call	EXT_C(real_to_prot)	.code32	/* write length of buffer (zero if error) into "addr" */	movl	0x14(%esp), %eax	movl	%ecx, (%eax)	/* set return value to continuation */	movl	%ebx, %eax	pop	%esi	pop	%edi	pop	%ebx	pop	%ebp	ret/* * get_rom_config_table() * * Get the linear address of a ROM configuration table. Return zero, * if fails. */	ENTRY(get_rom_config_table)	pushl	%ebp	pushl	%ebx	/* zero %ebx for simplicity */	xorl	%ebx, %ebx		call	EXT_C(prot_to_real)	.code16	movw	$0xc0, %ax	int	$0x15	jc	no_rom_table	testb	%ah, %ah	jnz	no_rom_table		movw	%es, %dx	jmp	found_rom_table	no_rom_table:	xorw	%dx, %dx	xorw	%bx, %bx	found_rom_table:	DATA32	call	EXT_C(real_to_prot)	.code32	/* compute the linear address */	movw	%dx, %ax	shll	$4, %eax	addl	%ebx, %eax	popl	%ebx	popl	%ebp	ret/* * int get_vbe_controller_info (struct vbe_controller *controller_ptr) * * Get VBE controller information. */ENTRY(get_vbe_controller_info)	pushl	%ebp	movl	%esp, %ebp		pushl	%edi	pushl	%ebx	/* Convert the linear address to segment:offset */	movl	8(%ebp), %eax	movl	%eax, %edi	andl	$0x0000000f, %edi	shrl	$4, %eax	movl	%eax, %ebx	call	EXT_C(prot_to_real)	.code16	movw	%bx, %es	movw	$0x4F00, %ax	int	$0x10	movw	%ax, %bx	DATA32	call	EXT_C(real_to_prot)	.code32	movzwl	%bx, %eax	popl	%ebx	popl	%edi	popl	%ebp	ret	/* * int get_vbe_mode_info (int mode_number, struct vbe_mode *mode_ptr) * * Get VBE mode information. */ENTRY(get_vbe_mode_info)	pushl	%ebp	movl	%esp, %ebp		pushl	%edi	pushl	%ebx	/* Convert the linear address to segment:offset */	movl	0xc(%ebp), %eax	movl	%eax, %edi	andl	$0x0000000f, %edi	shrl	$4, %eax	movl	%eax, %ebx	/* Save the mode number in %cx */	movl	0x8(%ebp), %ecx		call	EXT_C(prot_to_real)	.code16	movw	%bx, %es	movw	$0x4F01, %ax	int	$0x10	movw	%ax, %bx	DATA32	call	EXT_C(real_to_prot)	.code32	movzwl	%bx, %eax	popl	%ebx	popl	%edi	popl	%ebp	ret	

⌨️ 快捷键说明

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