• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2	Copyright (C) 2000, Entity Cyber, Inc.
3
4	Authors: Gary Byers (gb@thinguin.org)
5		 Marty Connor (mdc@thinguin.org)
6
7	This software may be used and distributed according to the terms
8	of the GNU Public License (GPL), incorporated herein by reference.
9
10	Description:
11
12	This is just a little bit of code and data that can get prepended
13	to a ROM image in order to allow bootloaders to load the result
14	as if it were a Linux kernel image.
15
16	A real Linux kernel image consists of a one-sector boot loader
17	(to load the image from a floppy disk), followed a few sectors
18	of setup code, followed by the kernel code itself.  There's
19	a table in the first sector (starting at offset 497) that indicates
20	how many sectors of setup code follow the first sector and which
21	contains some other parameters that aren't interesting in this
22	case.
23
24	When a bootloader loads the sectors that comprise a kernel image,
25	it doesn't execute the code in the first sector (since that code
26	would try to load the image from a floppy disk.)  The code in the
27	first sector below doesn't expect to get executed (and prints an
28	error message if it ever -is- executed.)
29
30	We don't require much in the way of setup code.  Historically, the
31	Linux kernel required at least 4 sectors of setup code.
32	Therefore, at least 4 sectors must be present even though we don't
33	use them.
34
35*/
36
37FILE_LICENCE ( GPL_ANY )
38
39#define	SETUPSECS 4		/* Minimal nr of setup-sectors */
40#define PREFIXSIZE ((SETUPSECS+1)*512)
41#define PREFIXPGH (PREFIXSIZE / 16 )
42#define	BOOTSEG  0x07C0		/* original address of boot-sector */
43#define	INITSEG  0x9000		/* we move boot here - out of the way */
44#define	SETUPSEG 0x9020		/* setup starts here */
45#define SYSSEG   0x1000		/* system loaded at 0x10000 (65536). */
46
47	.text
48	.code16
49	.arch i386
50	.org	0
51	.section ".prefix", "ax", @progbits
52/*
53	This is a minimal boot sector.	If anyone tries to execute it (e.g., if
54	a .lilo file is dd'ed to a floppy), print an error message.
55*/
56
57bootsector:
58	jmp	$BOOTSEG, $1f	/* reload cs:ip to match relocation addr */
591:
60	movw	$0x2000, %di		/*  0x2000 is arbitrary value >= length
61					    of bootsect + room for stack */
62
63	movw	$BOOTSEG, %ax
64	movw	%ax,%ds
65	movw	%ax,%es
66
67	cli
68	movw	%ax, %ss		/* put stack at BOOTSEG:0x2000. */
69	movw	%di,%sp
70	sti
71
72	movw	$why_end-why, %cx
73	movw	$why, %si
74
75	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
76	movb	$0x0e, %ah		/* write char, tty mode */
77prloop:
78	lodsb
79	int	$0x10
80	loop	prloop
81freeze: jmp	freeze
82
83why:	.ascii	"This image cannot be loaded from a floppy disk.\r\n"
84why_end:
85
86
87/*
88	The following header is documented in the Linux source code at
89	Documentation/i386/boot.txt
90*/
91	.org	497
92setup_sects:
93	.byte	SETUPSECS
94root_flags:
95	.word	0
96syssize:
97	.long	-PREFIXPGH
98
99	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
100	.ascii	"ADDL"
101	.long	syssize
102	.long	16
103	.long	0
104	.previous
105
106ram_size:
107	.word	0
108vid_mode:
109	.word	0
110root_dev:
111	.word	0
112boot_flag:
113	.word	0xAA55
114jump:
115	/* Manually specify a two-byte jmp instruction here rather
116	 * than leaving it up to the assembler. */
117	.byte	0xeb
118	.byte	setup_code - header
119header:
120	.byte	'H', 'd', 'r', 'S'
121version:
122	.word	0x0207 /* 2.07 */
123realmode_swtch:
124	.long	0
125start_sys:
126	.word	0
127kernel_version:
128	.word	0
129type_of_loader:
130	.byte	0
131loadflags:
132	.byte	0
133setup_move_size:
134	.word	0
135code32_start:
136	.long	0
137ramdisk_image:
138	.long	0
139ramdisk_size:
140	.long	0
141bootsect_kludge:
142	.long	0
143heap_end_ptr:
144	.word	0
145pad1:
146	.word	0
147cmd_line_ptr:
148	.long	0
149initrd_addr_max:
150	/* We don't use an initrd but some bootloaders (e.g. SYSLINUX) have
151	 * been known to require this field.  Set the value to 2 GB.  This
152	 * value is also used by the Linux kernel. */
153	.long	0x7fffffff
154kernel_alignment:
155	.long	0
156relocatable_kernel:
157	.byte	0
158pad2:
159	.byte	0, 0, 0
160cmdline_size:
161	.long	0
162hardware_subarch:
163	.long	0
164hardware_subarch_data:
165	.byte	0, 0, 0, 0, 0, 0, 0, 0
166
167/*
168	We don't need to do too much setup.
169
170	This code gets loaded at SETUPSEG:0.  It wants to start
171	executing the image that's loaded at SYSSEG:0 and
172	whose entry point is SYSSEG:0.
173*/
174setup_code:
175	/* We expect to be contiguous in memory once loaded.  The Linux image
176	 * boot process requires that setup code is loaded separately from
177	 * "non-real code".  Since we don't need any information that's left
178	 * in the prefix, it doesn't matter: we just have to ensure that
179	 * %cs:0000 is where the start of the image *would* be.
180	 */
181	ljmp	$(SYSSEG-(PREFIXSIZE/16)), $run_gpxe
182
183
184	.org	PREFIXSIZE
185/*
186	We're now at the beginning of the kernel proper.
187 */
188run_gpxe:
189	/* Set up stack just below 0x7c00 */
190	xorw	%ax, %ax
191	movw	%ax, %ss
192	movw	$0x7c00, %sp
193
194	/* Install gPXE */
195	call	install
196
197	/* Set up real-mode stack */
198	movw	%bx, %ss
199	movw	$_estack16, %sp
200
201	/* Jump to .text16 segment */
202	pushw	%ax
203	pushw	$1f
204	lret
205	.section ".text16", "awx", @progbits
2061:
207	pushl	$main
208	pushw	%cs
209	call	prot_call
210	popl	%ecx /* discard */
211
212	/* Uninstall gPXE */
213	call	uninstall
214
215	/* Boot next device */
216	int $0x18
217