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

📄 startup.s

📁 最新的grub2源代码
💻 S
📖 第 1 页 / 共 3 页
字号:
VARIABLE(grub_linux_tmp_addr)	.long	0VARIABLE(grub_linux_real_addr)	.long	0	FUNCTION(grub_linux_boot_zimage)	/* copy the kernel */	movl	EXT_C(grub_linux_prot_size), %ecx	addl	$3, %ecx	shrl	$2, %ecx	movl	$GRUB_LINUX_BZIMAGE_ADDR, %esi	movl	$GRUB_LINUX_ZIMAGE_ADDR, %edi	cld	rep	movslFUNCTION(grub_linux_boot_bzimage)	call	EXT_C(grub_dl_unload_all)		movl	EXT_C(grub_linux_real_addr), %ebx	/* copy the real mode code */	movl	EXT_C(grub_linux_tmp_addr), %esi	movl	%ebx, %edi	movl	$GRUB_LINUX_SETUP_MOVE_SIZE, %ecx	cld	rep	movsb	/* change %ebx to the segment address */	shrl	$4, %ebx	movl	%ebx, %eax	addl	$0x20, %eax	movw	%ax, linux_setup_seg	/* XXX new stack pointer in safe area for calling functions */	movl	$0x4000, %esp	call	EXT_C(grub_stop_floppy)	/* final setup for linux boot */	call	prot_to_real	.code16	cli	movw	%bx, %ss	movw	$GRUB_LINUX_SETUP_STACK, %sp	movw	%bx, %ds	movw	%bx, %es	movw	%bx, %fs	movw	%bx, %gs	/* ljmp */	.byte	0xea	.word	0linux_setup_seg:	.word	0	.code32		/* * This starts the multiboot kernel. */FUNCTION(grub_multiboot_real_boot)	/* Push the entry address on the stack.  */	pushl	%eax	/* Move the address of the multiboot information structure to ebx.  */	movl	%edx,%ebx		/* Unload all modules and stop the floppy driver.  */	call	EXT_C(grub_dl_unload_all)	call	EXT_C(grub_stop_floppy)	/* Interrupts should be disabled.  */	cli		/* Move the magic value into eax and jump to the kernel.  */	movl	$GRUB_MB_MAGIC2,%eax	popl	%ecx	jmp 	*%ecx		/* *   int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap) * *   Call IBM/MS INT13 Extensions (int 13 %ah=AH) for DRIVE. DAP *   is passed for disk address packet. If an error occurs, return *   non-zero, otherwise zero. */FUNCTION(grub_biosdisk_rw_int13_extensions)	pushl	%ebp	pushl	%esi	/* compute the address of disk_address_packet */	movw	%cx, %si	xorw	%cx, %cx	shrl	$4, %ecx	/* save the segment to cx */	/* ah */	movb	%al, %dh	/* enter real mode */	call	prot_to_real		.code16	movb	%dh, %ah	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	real_to_prot	.code32	movb	%dl, %al	/* return value in %eax */	popl	%esi	popl	%ebp	ret	/* *   int grub_biosdisk_rw_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. */FUNCTION(grub_biosdisk_rw_standard)	pushl	%ebp	movl	%esp, %ebp	pushl	%ebx	pushl	%edi	pushl	%esi	/* set up CHS information */	/* set %ch to low eight bits of cylinder */	xchgb	%cl, %ch	/* set bits 6-7 of %cl to high two bits of cylinder */	shlb	$6, %cl	/* set bits 0-5 of %cl to sector */	addb	0xc(%ebp), %cl	/* set %dh to head */	movb	0x8(%ebp), %dh	/* set %ah to AH */	movb	%al, %ah	/* set %al to NSEC */	movb	0x10(%ebp), %al	/* save %ax in %di */	movw	%ax, %di	/* save SEGMENT in %bx */	movw	0x14(%ebp), %bx			/* enter real mode */	call	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	real_to_prot	.code32	movb	%bl, %al	/* return value in %eax */		popl	%esi	popl	%edi	popl	%ebx	popl	%ebp	ret	$(4 * 4)/* *   int grub_biosdisk_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. */FUNCTION(grub_biosdisk_check_int13_extensions)	pushl	%ebp	pushl	%ebx	/* drive */	movb	%al, %dl	/* enter real mode */	call	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 */	andw	$1, %cx	jnz	2f	1:	xorb	%bl, %bl2:	/* back to protected mode */	DATA32	call	real_to_prot	.code32	movb	%bl, %al	/* return value in %eax */	popl	%ebx	popl	%ebp	ret/* *   int grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp) * *   Return the geometry of DRIVE in a drive parameters, DRP. If an error *   occurs, then return non-zero, otherwise zero. */FUNCTION(grub_biosdisk_get_diskinfo_int13_extensions)	pushl	%ebp	pushl	%ebx	pushl	%esi	/* compute the address of drive parameters */	movw	%dx, %si	xorw	%dx, %dx	shrl	$4, %edx	movw	%dx, %bx	/* save the segment into %bx */	/* drive */	movb	%al, %dl	/* enter real mode */	call	prot_to_real	.code16	movb	$0x48, %ah	movw	%bx, %ds	int	$0x13		/* do the operation */	movb	%ah, %bl	/* save return value in %bl */	/* clear the data segment */	xorw	%ax, %ax	movw	%ax, %ds	/* back to protected mode */	DATA32	call	real_to_prot	.code32	movb	%bl, %al	/* return value in %eax */	popl	%esi	popl	%ebx	popl	%ebp		ret/* *   int grub_biosdisk_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. */FUNCTION(grub_biosdisk_get_diskinfo_standard)	pushl	%ebp	pushl	%ebx	pushl	%edi	/* push CYLINDERS */	pushl	%edx	/* push HEADS */	pushl	%ecx	/* SECTORS is on the stack */		/* drive */	movb	%al, %dl	/* enter real mode */	call	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	real_to_prot	.code32	/* pop HEADS */	popl	%edi	movb	%dh, %al	incl	%eax	/* the number of heads is counted from zero */	movl	%eax, (%edi)	/* pop CYLINDERS */	popl	%edi	movb	%ch, %al	movb	%cl, %ah	shrb	$6, %ah	/* the number of cylinders is counted from zero */	incl	%eax	movl	%eax, (%edi)	/* SECTORS */	movl	0x10(%esp), %edi	andb	$0x3f, %cl	movzbl	%cl, %eax	movl	%eax, (%edi)		xorl	%eax, %eax	movb	%bl, %al	/* return value in %eax */	popl	%edi	popl	%ebx	popl	%ebp	ret	$4/* * int grub_biosdisk_get_num_floppies (void) */FUNCTION(grub_biosdisk_get_num_floppies)	pushl	%ebp	xorl	%edx, %edx	call	prot_to_real		.code16	/* reset the disk system first */	int	$0x131:	stc		/* call GET DISK TYPE */	movb	$0x15, %ah	int	$0x13	jc	2f	/* check if this drive exists */		testb	$0x3, %ah	jz	2f	incb	%dl	cmpb	$2, %dl	jne	1b2:	DATA32	call	real_to_prot	.code32	movl	%edx, %eax	popl	%ebp	ret		/* * * grub_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. * */FUNCTION(grub_get_memsize)	pushl	%ebp	movl	%eax, %edx	call	prot_to_real	/* enter real mode */	.code16	testl	%edx, %edx	jnz	xext	int	$0x12	jmp	xdonexext:	movb	$0x88, %ah	int	$0x15xdone:	movw	%ax, %dx	DATA32	call	real_to_prot	.code32	movw	%dx, %ax	popl	%ebp	ret/* * * grub_get_eisa_mmap() :  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 zero. *	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. * */FUNCTION(grub_get_eisa_mmap)	pushl	%ebp	pushl	%ebx	call	prot_to_real	/* enter real mode */	.code16	movw	$0xe801, %ax	int	$0x15	shll	$16, %ebx	movw	%ax, %bx	DATA32	call	real_to_prot	.code32	cmpb	$0x86, %bh	je	xnoteisa	movl	%ebx, %eaxxnoteisa:	popl	%ebx	popl	%ebp	ret/* * * grub_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. */FUNCTION(grub_get_mmap_entry)	pushl	%ebp	pushl	%ebx	pushl	%edi	pushl	%esi	/* push ADDR */	pushl	%eax		/* place address (+4) in ES:DI */	addl	$4, %eax	movl	%eax, %edi	andl	$0xf, %edi	shrl	$4, %eax	movl	%eax, %esi	/* set continuation value */	movl	%edx, %ebx	/* set default maximum buffer size */	movl	$0x14, %ecx	/* set EDX to 'SMAP' */	movl	$0x534d4150, %edx	call	prot_to_real	/* enter real mode */	.code16	movw	%si, %es	movl	$0xe820, %eax	int	$0x15	DATA32	jc	xnosmap	cmpl	$0x534d4150, %eax	jne	xnosmap	cmpl	$0x14, %ecx	jl	xnosmap	cmpl	$0x400, %ecx	jg	xnosmap	jmp	xsmapxnosmap:	xorl	%ecx, %ecxxsmap:	DATA32	call	real_to_prot	.code32	/* write length of buffer (zero if error) into ADDR */	popl	%eax	movl	%ecx, (%eax)	/* set return value to continuation */	movl	%ebx, %eax	popl	%esi	popl	%edi	popl	%ebx	popl	%ebp	ret	/* * void grub_console_real_putchar (int c) * * Put the character C on the console. Because GRUB wants to write a * character with an attribute, this implementation is a bit tricky. * If C is a control character (CR, LF, BEL, BS), use INT 10, AH = 0Eh * (TELETYPE OUTPUT). Otherwise, save the original position, put a space, * save the current position, restore the original position, write the * character and the attribute, and restore the current position. * * The reason why this is so complicated is that there is no easy way to * get the height of the screen, and the TELETYPE OUPUT BIOS call doesn't * support setting a background attribute. */FUNCTION(grub_console_real_putchar)	movl	%eax, %edx	pusha	movb	EXT_C(grub_console_cur_color), %bl		call	prot_to_real	.code16	movb	%dl, %al	xorb	%bh, %bh	/* use teletype output if control character */	cmpb	$0x7, %al	je	1f	cmpb	$0x8, %al	je	1f	cmpb	$0xa, %al	je	1f	cmpb	$0xd, %al	je	1f	/* save the character and the attribute on the stack */	pushw	%ax	pushw	%bx		/* get the current position */	movb	$0x3, %ah	int	$0x10	/* check the column with the width */	cmpb	$79, %dl	jl	2f		/* print CR and LF, if next write will exceed the width */		movw	$0x0e0d, %ax	int	$0x10	movb	$0x0a, %al	int	$0x10		/* get the current position */	movb	$0x3, %ah	int	$0x102:		/* restore the character and the attribute */	popw	%bx	popw	%ax		/* write the character with the attribute */	movb	$0x9, %ah	movw	$1, %cx	int	$0x10	/* move the cursor forward */	incb	%dl	movb	$0x2, %ah	int	$0x10	jmp	3f1:	movw	$1, %bx	movb	$0xe, %ah	int	$0x10	3:	DATA32	call	real_to_prot	.code32		popa	ret	/* * int grub_console_getkey (void) * BIOS call "INT 16H Function 00H" to read character from keyboard *	Call with	%ah = 0x0 *	Return:		%ah = keyboard scan code *			%al = ASCII character *//* this table is used in translate_keycode below */translation_table:	.word	GRUB_CONSOLE_KEY_LEFT, 2	.word	GRUB_CONSOLE_KEY_RIGHT, 6	.word	GRUB_CONSOLE_KEY_UP, 16	.word	GRUB_CONSOLE_KEY_DOWN, 14	.word	GRUB_CONSOLE_KEY_HOME, 1	.word	GRUB_CONSOLE_KEY_END, 5	.word	GRUB_CONSOLE_KEY_DC, 4	.word	GRUB_CONSOLE_KEY_BACKSPACE, 8	.word	GRUB_CONSOLE_KEY_PPAGE, 7	.word	GRUB_CONSOLE_KEY_NPAGE, 3	.word	0	/* * translate_keycode translates the key code %dx to an ascii code. */	.code16translate_keycode:	pushw	%bx	pushw	%si		movw	$ABS(translation_table), %si	1:	lodsw	/* check if this is the end */	testw	%ax, %ax	jz	2f	/* load the ascii code into %ax */	movw	%ax, %bx	lodsw	/* check if this matches the key code */	cmpw	%bx, %dx	jne	1b	/* translate %dx, if successful */	movw	%ax, %dx2:	popw	%si	popw	%bx	ret	.code32	FUNCTION(grub_console_getkey)	pushl	%ebp	call	prot_to_real	.code16	int	$0x16	movw	%ax, %dx		/* real_to_prot uses %eax */	call	translate_keycode			DATA32	call	real_to_prot	.code32	movw	%dx, %ax	popl	%ebp	ret/* * int grub_console_checkkey (void) *	if there is a character pending, return it; otherwise return -1 * BIOS call "INT 16H Function 01H" to check whether a character is pending *	Call with	%ah = 0x1 *	Return: *		If key waiting to be input: *			%ah = keyboard scan code *			%al = ASCII character *			Zero flag = clear *		else *			Zero flag = set */FUNCTION(grub_console_checkkey)	pushl	%ebp	xorl	%edx, %edx

⌨️ 快捷键说明

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