| /* | 
 |  *  GRUB  --  GRand Unified Bootloader | 
 |  *  Copyright (C) 2000   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 <nbi.h> | 
 | #include <diskless_size.h> | 
 | 			 | 
 | 	.file	"nbloader.S" | 
 | 	.text | 
 | 	.code16 | 
 | 	 | 
 | 	/* Just a dummy entry */ | 
 | .globl _start; _start: | 
 |  | 
 | 	/* | 
 | 	 * netboot image header | 
 | 	 */ | 
 |  | 
 | 	.long	NBI_MAGIC | 
 | 	.long	0x00000004 | 
 | 	/* load address of the first block  */ | 
 | 	.word	NBI_DEST_OFF | 
 | 	.word	NBI_DEST_SEG | 
 | 	/* start addr of the relocation code */ | 
 | 	.word	NBI_DEST_OFF + (relocate - _start) | 
 | 	.word	NBI_DEST_SEG | 
 |  | 
 | 	.long	0x04000004 | 
 | 	.long	NBI_DEST_ADDR + 0x0200 | 
 | 	.long	DISKLESS_SIZE | 
 | 	.long	DISKLESS_SIZE | 
 |  | 
 | relocate: | 
 | 	/* | 
 | 	 * This code is for now located at 0x10000. | 
 | 	 * Relocate the code in two steps: | 
 | 	 * 1. Copy the first 32k to 0x8000 and jump to the relocated area. | 
 | 	 * 2. Copy the rest to 0x10000 (0x8000 + 32k). | 
 | 	 */ | 
 |  | 
 | 	/* Copy the first 32k  */ | 
 | 	movw	$NBI_DEST_SEG, %ax | 
 | 	movw	%ax, %ds | 
 | 	movw	$RELOCATED_SEG, %ax | 
 | 	movw	%ax, %es | 
 | 	xorw	%si, %si | 
 | 	xorw	%di, %di | 
 | 	/* Always copy 32k bytes */ | 
 | 	movw	$0x4000, %cx | 
 |  | 
 | 	cld | 
 | 	rep | 
 | 	movsw | 
 |  | 
 | 	/* Jump to the relocated address */ | 
 | 	ljmp	$0, $(RELOCATED_ADDR + copy_rest - _start) | 
 |  | 
 | 	/* Copy the rest */ | 
 | copy_rest: | 
 | 	/* Set %edx to the number of bytes */ | 
 | 	movl	$(DISKLESS_SIZE + 0x200 - 0x8000), %edx | 
 | 	 | 
 | copy_loop: | 
 | 	/* Check the rest */ | 
 | 	orl	%edx, %edx | 
 | 	jz	boot_stage2 | 
 |  | 
 | 	/* Copy by 32k, as that is easy to implement */ | 
 | 	movl	$0x8000, %ecx | 
 | 	cmpl	%ecx, %edx | 
 | 	jg	copy | 
 | 	movl	%edx, %ecx | 
 | 	 | 
 | copy: | 
 | 	/* Update the number of rest bytes */ | 
 | 	subl	%ecx, %edx | 
 |  | 
 | 	/* Add 0x0800 (32k >> 4) into %es and %ds */ | 
 | 	movw	%es, %ax | 
 | 	addw	$0x0800, %ax | 
 | 	movw	%ax, %es | 
 | 	movw	%ds, %ax | 
 | 	addw	$0x800, %ax | 
 | 	movw	%ax, %ds | 
 | 	 | 
 | 	/* Zero the offsets */ | 
 | 	xorw	%si, %si | 
 | 	xorw	%di, %di | 
 | 	 | 
 | 	/* Use word-size copy */ | 
 | 	addw	$1, %cx | 
 | 	shrw	$1, %cx | 
 |  | 
 | 	/* The direction is already correct */ | 
 | 	rep | 
 | 	movsw | 
 |  | 
 | 	jmp	copy_loop | 
 |  | 
 | 	/* Jump to the stage2 */ | 
 | boot_stage2: | 
 | 	ljmp	$0, $STAGE2_START_ADDR | 
 | 	 | 
 | 	/* This ensures that the length of this image will be 1 sector */ | 
 | 	. = _start + 0x200 - 1 | 
 | 	.byte	0 |