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

📄 diskboot.s

📁 最新的grub2源代码
💻 S
字号:
/* *  GRUB  --  GRand Unified Bootloader *  Copyright (C) 1999,2000,2001,2002   Free Software Foundation, Inc. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <grub/machine/boot.h>	/* *  defines for the code go here */	/* Absolute addresses	   This makes the assembler generate the address without support	   from the linker. (ELF can't relocate 16-bit addresses!) */#define ABS(x) (x-_start+GRUB_BOOT_MACHINE_KERNEL_ADDR)		/* Print message string */#define MSG(x)	movw $ABS(x), %si; call message	.file	"diskboot.S"	.text	/* Tell GAS to generate 16-bit instructions so that this code works	   in real mode. */	.code16	.globl	start, _startstart:_start:		/*	 * _start is loaded at 0x2000 and is jumped to with	 * CS:IP 0:0x2000 in kernel.	 */	/* 	 * we continue to use the stack for boot.img and assume that	 * some registers are set to correct values. See boot.S	 * for more information.	 */		/* save drive reference first thing! */	pushw	%dx	/* print a notification message on the screen */	pushw	%si	MSG(notification_string)	popw	%si		/* this sets up for the first run through "bootloop" */	movw	$ABS(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE), %di	/* save the sector number of the second sector in %ebp */	movl	(%di), %ebp        /* this is the loop for reading the rest of the kernel in */bootloop:	/* check the number of sectors to read */	cmpw	$0, 4(%di)	/* if zero, go to the start function */	je	bootitsetup_sectors:		/* check if we use LBA or CHS */	cmpb	$0, -1(%si)	/* jump to chs_mode if zero */	je	chs_modelba_mode:		/* load logical sector start */	movl	(%di), %ebx	/* the maximum is limited to 0x7f because of Phoenix EDD */	xorl	%eax, %eax	movb	$0x7f, %al	/* how many do we really want to read? */	cmpw	%ax, 4(%di)	/* compare against total number of sectors */	/* which is greater? */	jg	1f	/* if less than, set to total */	movw	4(%di), %ax1:		/* subtract from total */	subw	%ax, 4(%di)	/* add into logical sector start */	addl	%eax, (%di)	/* set up disk address packet */	/* the size and the reserved byte */	movw	$0x0010, (%si)	/* the number of sectors */	movw	%ax, 2(%si)	/* the absolute address (low 32 bits) */	movl	%ebx, 8(%si)	/* the segment of buffer address */	movw	$GRUB_BOOT_MACHINE_BUFFER_SEG, 6(%si)	/* save %ax from destruction! */	pushw	%ax	/* zero %eax */	xorl	%eax, %eax	/* the offset of buffer address */	movw	%ax, 4(%si)	/* the absolute address (high 32 bits) */	movl	%eax, 12(%si)/* * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory *	Call with	%ah = 0x42 *			%dl = drive number *			%ds:%si = segment:offset of disk address packet *	Return: *			%al = 0x0 on success; err code on failure */	movb	$0x42, %ah	int	$0x13	jc	read_error	movw	$GRUB_BOOT_MACHINE_BUFFER_SEG, %bx	jmp	copy_buffer			chs_mode:		/* load logical sector start (bottom half) */	movl	(%di), %eax	/* zero %edx */	xorl	%edx, %edx	/* divide by number of sectors */	divl	(%si)	/* save sector start */	movb	%dl, 10(%si)	xorl	%edx, %edx	/* zero %edx */	divl	4(%si)		/* divide by number of heads */	/* save head start */	movb	%dl, 11(%si)	/* save cylinder start */	movw	%ax, 12(%si)	/* do we need too many cylinders? */	cmpw	8(%si), %ax	jge	geometry_error	/* determine the maximum sector length of this read */	movw	(%si), %ax	/* get number of sectors per track/head */	/* subtract sector start */	subb	10(%si), %al	/* how many do we really want to read? */	cmpw	%ax, 4(%di)	/* compare against total number of sectors */	/* which is greater? */	jg	2f	/* if less than, set to total */	movw	4(%di), %ax2:		/* subtract from total */	subw	%ax, 4(%di)	/* add into logical sector start */	addl	%eax, (%di)/* *  This is the loop for taking care of BIOS geometry translation (ugh!) */	/* get high bits of cylinder */	movb	13(%si), %dl	shlb	$6, %dl		/* shift left by 6 bits */	movb	10(%si), %cl	/* get sector */	incb	%cl		/* normalize sector (sectors go					from 1-N, not 0-(N-1) ) */	orb	%dl, %cl	/* composite together */	movb	12(%si), %ch	/* sector+hcyl in cl, cylinder in ch */	/* restore %dx */	popw	%dx	pushw	%dx	/* head number */	movb	11(%si), %dh	pushw	%ax	/* save %ax from destruction! *//* * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory *	Call with	%ah = 0x2 *			%al = number of sectors *			%ch = cylinder *			%cl = sector (bits 6-7 are high bits of "cylinder") *			%dh = head *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk) *			%es:%bx = segment:offset of buffer *	Return: *			%al = 0x0 on success; err code on failure */	movw	$GRUB_BOOT_MACHINE_BUFFER_SEG, %bx	movw	%bx, %es	/* load %es segment with disk buffer */	xorw	%bx, %bx	/* %bx = 0, put it at 0 in the segment */	movb	$0x2, %ah	/* function 2 */	int	$0x13	jc	read_error	/* save source segment */	movw	%es, %bx	copy_buffer:		/* load addresses for copy from disk buffer to destination */	movw	6(%di), %es	/* load destination segment */	/* restore %ax */	popw	%ax	/* determine the next possible destination address (presuming		512 byte sectors!) */	shlw	$5, %ax		/* shift %ax five bits to the left */	addw	%ax, 6(%di)	/* add the corrected value to the destination				   address for next time */	/* save addressing regs */	pusha	pushw	%ds	/* get the copy length */	shlw	$3, %ax	movw	%ax, %cx	xorw	%di, %di	/* zero offset of destination addresses */	xorw	%si, %si	/* zero offset of source addresses */	movw	%bx, %ds	/* restore the source segment */	cld		/* sets the copy direction to forward */	/* perform copy */	rep		/* sets a repeat */	movsw		/* this runs the actual copy */	/* restore addressing regs and print a dot with correct DS 	   (MSG modifies SI, which is saved, and unused AX and BX) */	popw	%ds	MSG(notification_step)	popa	/* check if finished with this dataset */	cmpw	$0, 4(%di)	jne	setup_sectors	/* update position to load from */	subw	$GRUB_BOOT_MACHINE_LIST_SIZE, %di	/* jump to bootloop */	jmp	bootloop/* END OF MAIN LOOP */bootit:	/* print a newline */	MSG(notification_done)	popw	%dx	/* this makes sure %dl is our "boot" drive */	ljmp	$0, $(GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200)/* * BIOS Geometry translation error (past the end of the disk geometry!). */geometry_error:	MSG(geometry_error_string)	jmp	general_error/* * Read error on the disk. */read_error:	MSG(read_error_string)general_error:	MSG(general_error_string)/* go here when you need to stop the machine hard after an error condition */stop:	jmp	stopnotification_string:	.string "Loading kernel"notification_step:	.string "."notification_done:	.string "\r\n"	geometry_error_string:	.string "Geom"read_error_string:	.string "Read"general_error_string:	.string " Error"/* * message: write the string pointed to by %si * *   WARNING: trashes %si, %ax, and %bx */	/*	 * Use BIOS "int 10H Function 0Eh" to write character in teletype mode	 *	%ah = 0xe	%al = character	 *	%bh = page	%bl = foreground color (graphics modes)	 */1:	movw	$0x0001, %bx	movb	$0xe, %ah	int	$0x10		/* display a byte */	incw	%simessage:	movb	(%si), %al	cmpb	$0, %al	jne	1b	/* if not end of string, jmp to display */	retlastlist:/* *  This area is an empty space between the main body of code below which *  grows up (fixed after compilation, but between releases it may change *  in size easily), and the lists of sectors to read, which grows down *  from a fixed top location. */	.word 0	.word 0	. = _start + 0x200 - GRUB_BOOT_MACHINE_LIST_SIZE	        /* fill the first data listing with the default */blocklist_default_start:	/* this is the sector start parameter, in logical sectors from	   the start of the disk, sector 0 */	.long 2blocklist_default_len:	/* this is the number of sectors to read the command "install"	   will fill this up */	.word 0blocklist_default_seg:	/* this is the segment of the starting address to load the data into */	.word (GRUB_BOOT_MACHINE_KERNEL_SEG + 0x20)	firstlist:	/* this label has to be after the list data!!! */

⌨️ 快捷键说明

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