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