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

📄 asm.s

📁 i386的bootloader源码grub
💻 S
📖 第 1 页 / 共 3 页
字号:
/* * int set_vbe_mode (int mode_number) * * Set VBE mode. Don't support user-specified CRTC information. */ENTRY(set_vbe_mode)	pushl	%ebp	movl	%esp, %ebp		pushl	%ebx	/* Save the mode number in %bx */	movl	0x8(%ebp), %ebx	/* Clear bit D11 */	andl	$0xF7FF, %ebx		call	EXT_C(prot_to_real)	.code16	movw	$0x4F02, %ax	int	$0x10	movw	%ax, %bx	DATA32	call	EXT_C(real_to_prot)	.code32	movzwl	%bx, %eax	popl	%ebx	popl	%ebp	ret		/* * gateA20(int linear) * * Gate address-line 20 for high memory. * * This routine is probably overconservative in what it does, but so what? * * It also eats any keystrokes in the keyboard buffer.  :-( */ENTRY(gateA20)	/* first, try a BIOS call */	pushl	%ebp	movl	8(%esp), %edx		call	EXT_C(prot_to_real)		.code16	movw	$0x2400, %ax	testw	%dx, %dx	jz	1f	incw	%ax1:	stc	int	$0x15	jnc	2f	/* set non-zero if failed */	movb	$1, %ah	/* save the status */2:	movb	%ah, %dl	DATA32	call	EXT_C(real_to_prot)	.code32	popl	%ebp	testb	%dl, %dl	jnz	3f	ret3:	/* use keyboard controller */	pushl	%eax	call    gloop1	movb	$KC_CMD_WOUT, %al	outb	$K_CMDgloopint1:	inb	$K_STATUS	andb	$K_IBUF_FUL, %al	jnz	gloopint1	movb	$KB_OUTPUT_MASK, %al	cmpb	$0, 0x8(%esp)	jz	gdoit	orb	$KB_A20_ENABLE, %algdoit:	outb	$K_RDWR	call	gloop1	/* output a dummy command (USB keyboard hack) */	movb	$0xff, %al	outb	$K_CMD	call	gloop1		popl	%eax	retgloop1:	inb	$K_STATUS	andb	$K_IBUF_FUL, %al	jnz	gloop1gloop2:	inb	$K_STATUS	andb	$K_OBUF_FUL, %al	jz	gloop2ret	inb	$K_RDWR	jmp	gloop2gloop2ret:	retENTRY(patch_code)	/* labels start with "pc_" */	.code16	mov	%cs, %ax	mov	%ax, %ds	mov	%ax, %es	mov	%ax, %fs	mov	%ax, %gs	ADDR32	movl	$0, 0pc_stop:	hlt	DATA32	jmp	pc_stopENTRY(patch_code_end)	.code32/* * linux_boot() * * Does some funky things (including on the stack!), then jumps to the * entry point of the Linux setup code. */VARIABLE(linux_text_len)	.long	0	VARIABLE(linux_data_tmp_addr)	.long	0	VARIABLE(linux_data_real_addr)	.long	0	ENTRY(linux_boot)	/* don't worry about saving anything, we're committed at this point */	cld	/* forward copying */	/* copy kernel */	movl	EXT_C(linux_text_len), %ecx	addl	$3, %ecx	shrl	$2, %ecx	movl	$LINUX_BZIMAGE_ADDR, %esi	movl	$LINUX_ZIMAGE_ADDR, %edi	rep	movslENTRY(big_linux_boot)	movl	EXT_C(linux_data_real_addr), %ebx		/* copy the real mode part */	movl	EXT_C(linux_data_tmp_addr), %esi	movl	%ebx, %edi	movl	$LINUX_SETUP_MOVE_SIZE, %ecx	cld	rep	movsb	/* change %ebx to the segment address */	shrl	$4, %ebx	movl	%ebx, %eax	addl	$0x20, %eax	movl	%eax, linux_setup_seg				/* XXX new stack pointer in safe area for calling functions */	movl	$0x4000, %esp	call	EXT_C(stop_floppy)	/* final setup for linux boot */	call	EXT_C(prot_to_real)	.code16	/* final setup for linux boot */	cli	movw	%bx, %ss	movw	$LINUX_SETUP_STACK, %sp		movw	%bx, %ds	movw	%bx, %es	movw	%bx, %fs	movw	%bx, %gs	/* jump to start */	/* ljmp */	.byte	0xea	.word	0linux_setup_seg:		.word	0	.code32/* * multi_boot(int start, int mb_info) * *  This starts a kernel in the manner expected of the multiboot standard. */ENTRY(multi_boot)	/* no need to save anything */	call	EXT_C(stop_floppy)	movl	$0x2BADB002, %eax	movl	0x8(%esp), %ebx	/* boot kernel here (absolute address call) */	call	*0x4(%esp)	/* error */	call	EXT_C(stop)#endif /* ! STAGE1_5 */	/* * void console_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. */ENTRY(console_putchar)	movl	0x4(%esp), %edx	pusha#ifdef STAGE1_5	movb	$0x07, %bl#else	movl	EXT_C(console_current_color), %ebx#endif		call	EXT_C(prot_to_real)	.code16	movb	%dl, %al	xorb	%bh, %bh#ifndef STAGE1_5	/* 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	3f#endif /* ! STAGE1_5 */	1:	movb	$0xe, %ah	int	$0x10	3:	DATA32	call	EXT_C(real_to_prot)	.code32		popa	ret#ifndef STAGE1_5/* this table is used in translate_keycode below */translation_table:	.word	KEY_LEFT, 2	.word	KEY_RIGHT, 6	.word	KEY_UP, 16	.word	KEY_DOWN, 14	.word	KEY_HOME, 1	.word	KEY_END, 5	.word	KEY_DC, 4	.word	KEY_BACKSPACE, 8	.word	KEY_PPAGE, 7	.word	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	/* * remap_ascii_char remaps the ascii code %dl to another if the code is * contained in ASCII_KEY_MAP. */	.code16	remap_ascii_char:	pushw	%si		movw	$ABS(EXT_C(ascii_key_map)), %si1:	lodsw	/* check if this is the end */	testw	%ax, %ax	jz	2f	/* check if this matches the ascii code */	cmpb	%al, %dl	jne	1b	/* if so, perform the mapping */	movb	%ah, %dl2:	/* restore %si */	popw	%si	ret	.code32	.align	4ENTRY(ascii_key_map)	.space	(KEY_MAP_SIZE + 1) * 2	/* * int 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 */ENTRY(console_getkey)	push	%ebp	call	EXT_C(prot_to_real)	.code16	int	$0x16	movw	%ax, %dx		/* real_to_prot uses %eax */	call	translate_keycode	call	remap_ascii_char		DATA32	call	EXT_C(real_to_prot)	.code32	movw	%dx, %ax	pop	%ebp	ret/* * int 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 */ENTRY(console_checkkey)	push	%ebp	xorl	%edx, %edx		call	EXT_C(prot_to_real)	/* enter real mode */	.code16	movb	$0x1, %ah	int	$0x16	DATA32	jz	notpending		movw	%ax, %dx	call	translate_keycode	call	remap_ascii_char	DATA32	jmp	pendingnotpending:	movl	$0xFFFFFFFF, %edxpending:	DATA32	call	EXT_C(real_to_prot)	.code32	mov	%edx, %eax	pop	%ebp	ret	/* * int 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) */ENTRY(console_getxy)	push	%ebp	push	%ebx                    /* save EBX */	call	EXT_C(prot_to_real)	.code16        xorb	%bh, %bh                /* set page to 0 */	movb	$0x3, %ah	int	$0x10			/* get cursor position */	DATA32	call	EXT_C(real_to_prot)	.code32	movb	%dl, %ah	movb	%dh, %al	pop	%ebx	pop	%ebp	ret/* * void console_gotoxy(int x, int 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) */ENTRY(console_gotoxy)	push	%ebp	push	%ebx                    /* save EBX */	movb	0xc(%esp), %dl           /* %dl = x */	movb	0x10(%esp), %dh          /* %dh = y */	call	EXT_C(prot_to_real)	.code16        xorb	%bh, %bh                /* set page to 0 */	movb	$0x2, %ah	int	$0x10			/* set cursor position */	DATA32	call	EXT_C(real_to_prot)	.code32	pop	%ebx	pop	%ebp	ret	/* * void console_cls (void) * BIOS call "INT 10H Function 09h" to write character and attribute *	Call with	%ah = 0x09 *                      %al = (character) *                      %bh = (page number) *                      %bl = (attribute) *                      %cx = (number of times) */ENTRY(console_cls)	push	%ebp	push	%ebx                    /* save EBX */	call	EXT_C(prot_to_real)	.code16	/* move the cursor to the beginning */	movb	$0x02, %ah	xorb	%bh, %bh	xorw	%dx, %dx	int	$0x10	/* write spaces to the entire screen */	movw	$0x0920, %ax	movw	$0x07, %bx	movw	$(80 * 25), %cx        int	$0x10	/* move back the cursor */	movb	$0x02, %ah	int	$0x10	DATA32	call	EXT_C(real_to_prot)	.code32	pop	%ebx	pop	%ebp	ret	/* * int console_setcursor (int on) * BIOS call "INT 10H Function 01h" to set cursor type *      Call with       %ah = 0x01 *                      %ch = cursor starting scanline *                      %cl = cursor ending scanline */console_cursor_state:	.byte	1console_cursor_shape:	.word	0	ENTRY(console_setcursor)	push	%ebp	push	%ebx	/* check if the standard cursor shape has already been saved */	movw	console_cursor_shape, %ax	testw	%ax, %ax	jne	1f	call	EXT_C(prot_to_real)	.code16	movb	$0x03, %ah	xorb	%bh, %bh	int	$0x10	DATA32	call	EXT_C(real_to_prot)	.code32	movw	%cx, console_cursor_shape1:	/* set %cx to the designated cursor shape */	movw	$0x2000, %cx	movl	0xc(%esp), %ebx	testl	%ebx, %ebx	jz	2f	movw	console_cursor_shape, %cx2:		call	EXT_C(prot_to_real)	.code16	movb    $0x1, %ah	int     $0x10 	DATA32	call	EXT_C(real_to_prot)	.code32	movzbl	console_cursor_state, %eax	movb	%bl, console_cursor_state		pop	%ebx	pop	%ebp	ret		/* * getrtsecs() *	if a seconds value can be read, read it and return it (BCD), *      otherwise return 0xFF * BIOS call "INT 1AH Function 02H" to check whether a character is pending *	Call with	%ah = 0x2 *	Return: *		If RT Clock can give correct values *			%ch = hour (BCD) *			%cl = minutes (BCD) *                      %dh = seconds (BCD) *                      %dl = daylight savings time (00h std, 01h daylight) *			Carry flag = clear *		else *			Carry flag = set *                         (this indicates that the clock is updating, or *                          that it isn't running) */ENTRY(getrtsecs)	push	%ebp	call	EXT_C(prot_to_real)	/* enter real mode */	.code16	movb	$0x2, %ah	int	$0x1a	DATA32	jnc	gottime	movb	$0xff, %dhgottime:	DATA32	call	EXT_C(real_to_prot)	.code32	movb	%dh, %al	pop	%ebp	ret	/* * currticks() *	return the real time in ticks, of which there are about *	18-20 per second */ENTRY(currticks)	pushl	%ebp	call	EXT_C(prot_to_real)	/* enter real mode */	.code16	/* %ax is already zero */        int	$0x1a	DATA32	call	EXT_C(real_to_prot)	.code32	movl	%ecx, %eax	shll	$16, %eax	movw	%dx, %ax	popl	%ebp	ret#endif /* STAGE1_5 *//* *  This is the area for all of the special variables. */	.p2align	2	/* force 4-byte alignment */protstack:	.long	PROTSTACKINITVARIABLE(boot_drive)#ifdef SUPPORT_DISKLESS	.long	NETWORK_DRIVE#else	.long	0#endifVARIABLE(install_second_sector)	.long	0		/* an address can only be long-jumped to if it is in memory, this	   is used by multiple routines */offset:	.long	0x8000segment:	.word	0VARIABLE(apm_bios_info)	.word	0	/* version */	.word	0	/* cseg */	.long	0	/* offset */	.word	0	/* cseg_16 */	.word	0	/* dseg_16 */	.word	0	/* cseg_len */	.word	0	/* cseg_16_len */	.word	0	/* dseg_16_len */	/* * This is the Global Descriptor Table * *  An entry, a "Segment Descriptor", looks like this: * * 31          24         19   16                 7           0 * ------------------------------------------------------------ * |             | |B| |A|       | |   |1|0|E|W|A|            | * | BASE 31..24 |G|/|0|V| LIMIT |P|DPL|  TYPE   | BASE 23:16 | * |             | |D| |L| 19..16| |   |1|1|C|R|A|            | * ------------------------------------------------------------ * |                             |                            | * |        BASE 15..0           |       LIMIT 15..0          | * |                             |                            | * ------------------------------------------------------------ * *  Note the ordering of the data items is reversed from the above *  description. */	.p2align	2	/* force 4-byte alignment */gdt:	.word	0, 0	.byte	0, 0, 0, 0	/* code segment */	.word	0xFFFF, 0	.byte	0, 0x9A, 0xCF, 0	/* data segment */	.word	0xFFFF, 0	.byte	0, 0x92, 0xCF, 0	/* 16 bit real mode CS */	.word	0xFFFF, 0	.byte	0, 0x9E, 0, 0	/* 16 bit real mode DS */	.word	0xFFFF, 0	.byte	0, 0x92, 0, 0/* this is the GDT descriptor */gdtdesc:	.word	0x27			/* limit */	.long	gdt			/* addr */

⌨️ 快捷键说明

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