Home | History | Annotate | Download | only in stage2
      1 /*
      2  *  GRUB  --  GRand Unified Bootloader
      3  *  Copyright (C) 2000   Free Software Foundation, Inc.
      4  *
      5  *  This program is free software; you can redistribute it and/or modify
      6  *  it under the terms of the GNU General Public License as published by
      7  *  the Free Software Foundation; either version 2 of the License, or
      8  *  (at your option) any later version.
      9  *
     10  *  This program is distributed in the hope that it will be useful,
     11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  *  GNU General Public License for more details.
     14  *
     15  *  You should have received a copy of the GNU General Public License
     16  *  along with this program; if not, write to the Free Software
     17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     18  */
     19 
     20 #include <nbi.h>
     21 #include <diskless_size.h>
     22 
     23 	.file	"nbloader.S"
     24 	.text
     25 	.code16
     26 
     27 	/* Just a dummy entry */
     28 .globl _start; _start:
     29 
     30 	/*
     31 	 * netboot image header
     32 	 */
     33 
     34 	.long	NBI_MAGIC
     35 	.long	0x00000004
     36 	/* load address of the first block  */
     37 	.word	NBI_DEST_OFF
     38 	.word	NBI_DEST_SEG
     39 	/* start addr of the relocation code */
     40 	.word	NBI_DEST_OFF + (relocate - _start)
     41 	.word	NBI_DEST_SEG
     42 
     43 	.long	0x04000004
     44 	.long	NBI_DEST_ADDR + 0x0200
     45 	.long	DISKLESS_SIZE
     46 	.long	DISKLESS_SIZE
     47 
     48 relocate:
     49 	/*
     50 	 * This code is for now located at 0x10000.
     51 	 * Relocate the code in two steps:
     52 	 * 1. Copy the first 32k to 0x8000 and jump to the relocated area.
     53 	 * 2. Copy the rest to 0x10000 (0x8000 + 32k).
     54 	 */
     55 
     56 	/* Copy the first 32k  */
     57 	movw	$NBI_DEST_SEG, %ax
     58 	movw	%ax, %ds
     59 	movw	$RELOCATED_SEG, %ax
     60 	movw	%ax, %es
     61 	xorw	%si, %si
     62 	xorw	%di, %di
     63 	/* Always copy 32k bytes */
     64 	movw	$0x4000, %cx
     65 
     66 	cld
     67 	rep
     68 	movsw
     69 
     70 	/* Jump to the relocated address */
     71 	ljmp	$0, $(RELOCATED_ADDR + copy_rest - _start)
     72 
     73 	/* Copy the rest */
     74 copy_rest:
     75 	/* Set %edx to the number of bytes */
     76 	movl	$(DISKLESS_SIZE + 0x200 - 0x8000), %edx
     77 
     78 copy_loop:
     79 	/* Check the rest */
     80 	orl	%edx, %edx
     81 	jz	boot_stage2
     82 
     83 	/* Copy by 32k, as that is easy to implement */
     84 	movl	$0x8000, %ecx
     85 	cmpl	%ecx, %edx
     86 	jg	copy
     87 	movl	%edx, %ecx
     88 
     89 copy:
     90 	/* Update the number of rest bytes */
     91 	subl	%ecx, %edx
     92 
     93 	/* Add 0x0800 (32k >> 4) into %es and %ds */
     94 	movw	%es, %ax
     95 	addw	$0x0800, %ax
     96 	movw	%ax, %es
     97 	movw	%ds, %ax
     98 	addw	$0x800, %ax
     99 	movw	%ax, %ds
    100 
    101 	/* Zero the offsets */
    102 	xorw	%si, %si
    103 	xorw	%di, %di
    104 
    105 	/* Use word-size copy */
    106 	addw	$1, %cx
    107 	shrw	$1, %cx
    108 
    109 	/* The direction is already correct */
    110 	rep
    111 	movsw
    112 
    113 	jmp	copy_loop
    114 
    115 	/* Jump to the stage2 */
    116 boot_stage2:
    117 	ljmp	$0, $STAGE2_START_ADDR
    118 
    119 	/* This ensures that the length of this image will be 1 sector */
    120 	. = _start + 0x200 - 1
    121 	.byte	0
    122