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

📄 startup.s

📁 有助于了解操作系统如何启动之过程
💻 S
📖 第 1 页 / 共 3 页
字号:
	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 OUTPUT 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		call	prot_to_real	/* enter real mode */	.code16	movb	$0x1, %ah	int	$0x16	jz	notpending		movw	%ax, %dx	DATA32	jmp	pendingnotpending:	decl	%edxpending:	DATA32	call	real_to_prot	.code32	movl	%edx, %eax	popl	%ebp	ret	/* * grub_uint16_t grub_console_getxy (void) * BIOS call "INT 10H Function 03h" to get cursor position *	Call with	%ah = 0x03 *			%bh = page *      Returns         %ch = starting scan line *                      %cl = ending scan line *                      %dh = row (0 is top) *                      %dl = column (0 is left) */FUNCTION(grub_console_getxy)	pushl	%ebp	pushl	%ebx                    /* save EBX */	call	prot_to_real	.code16        xorb	%bh, %bh                /* set page to 0 */	movb	$0x3, %ah	int	$0x10			/* get cursor position */	DATA32	call	real_to_prot	.code32	movb	%dl, %ah	movb	%dh, %al	popl	%ebx	popl	%ebp	ret/* * void grub_console_gotoxy(grub_uint8_t x, grub_uint8_t y) * BIOS call "INT 10H Function 02h" to set cursor position *	Call with	%ah = 0x02 *			%bh = page *                      %dh = row (0 is top) *                      %dl = column (0 is left) */FUNCTION(grub_console_gotoxy)	pushl	%ebp	pushl	%ebx                    /* save EBX */	movb	%dl, %dh	/* %dh = y */	movb	%al, %dl	/* %dl = x */

⌨️ 快捷键说明

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