summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/arch/i386/prefix/exeprefix.S
blob: 5c648d51d0d5bdd691c68f7d8c6591e2159d89b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
 * Copyright (C) 2011 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * 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 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., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 *
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

/* Initial temporary stack size */
#define EXE_STACK_SIZE 0x400

/* Temporary decompression area (avoid DOS high memory area) */
#define EXE_DECOMPRESS_ADDRESS 0x110000

/* Fields within the Program Segment Prefix */
#define PSP_CMDLINE_LEN 0x80
#define PSP_CMDLINE_START 0x81

	.text
	.arch i386
	.org 0
	.code16
	.section ".prefix", "awx", @progbits

signature:
	/* "MZ" signature */
	.ascii	"MZ"

last_block:
	/* Number of bytes in last block that are really used */
	.word	0

blocks:
	/* Number of 512-byte blocks */
	.word	0
	.section ".zinfo.fixup", "a", @progbits /* Compressor fixups */
	.ascii	"ADDW"
	.long	blocks
	.long	512
	.long	0
	.previous

num_reloc:
	/* Number of relocation entries stored after the header */
	.word	0

header_pgh:
	/* Number of paragraphs in the header */
	.word	( ( _exe_start - signature ) / 16 )

min_bss_pgh:
	/* Minimum number of paragraphs of additional (BSS) memory */
	.word	( EXE_STACK_SIZE / 16 )

max_bss_pgh:
	/* Maximum number of paragraphs of additional (BSS) memory */
	.word	( EXE_STACK_SIZE / 16 )

init_ss:
	/* Initial stack segment (relative to start of executable) */
	.word	-( ( _exe_start - signature ) / 16 )
	.section ".zinfo.fixup", "a", @progbits /* Compressor fixups */
	.ascii	"ADDW"
	.long	init_ss
	.long	16
	.long	0
	.previous

init_sp:
	/* Initial stack pointer */
	.word	EXE_STACK_SIZE

checksum:
	/* Checksum (ignored) */
	.word	0

init_ip:
	/* Initial instruction pointer */
	.word	_exe_start

init_cs:
	/* Initial code segment (relative to start of executable) */
	.word	-( ( _exe_start - signature ) / 16 )

reloc_table:
	/* Relocation table offset */
	.word	0

overlay:
	/* Overlay number */
	.word	0

	.align 16, 0

	.globl	_exe_start
_exe_start:
	/* Install iPXE.  Use a fixed temporary decompression area to
	 * avoid trashing the DOS high memory area.
	 */
	call	alloc_basemem
	xorl	%esi, %esi
	movl	$EXE_DECOMPRESS_ADDRESS, %edi
	orl	$0xffffffff, %ebp	/* Allow arbitrary relocation */
	call	install_prealloc

	/* Set up real-mode stack */
	movw	%bx, %ss
	movw	$_estack16, %sp

	/* Jump to .text16 segment */
	pushw	%ax
	pushw	$1f
	lret
	.section ".text16", "awx", @progbits
1:
	/* Terminate command line with a NUL */
	movzbw	PSP_CMDLINE_LEN, %si
	movb	$0, PSP_CMDLINE_START(%si)

	/* Calculate command line physical address */
	xorl	%esi, %esi
	movw	%ds, %si
	shll	$4, %esi
	addl	$PSP_CMDLINE_START, %esi

	/* Set up %ds for access to .data16 */
	movw	%bx, %ds

	/* Record command line address */
	movl	%esi, cmdline_phys

	/* Run iPXE */
	pushl	$main
	pushw	%cs
	call	prot_call
	popl	%ecx /* discard */

	/* Uninstall iPXE */
	call	uninstall

	/* Exit back to DOS.  This is very unlikely to work */
	movw	$0x4c00, %ax
	int	$0x21