xref: /titanic_41/usr/src/grub/grub-0.97/stage2/nbloader.S (revision 1b8adde7ba7d5e04395c141c5400dc2cffd7d809)
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
48relocate:
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 */
74copy_rest:
75	/* Set %edx to the number of bytes */
76	movl	$(DISKLESS_SIZE + 0x200 - 0x8000), %edx
77
78copy_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
89copy:
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 */
116boot_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