xref: /OK3568_Linux_fs/kernel/arch/x86/boot/header.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun/*
3*4882a593Smuzhiyun *	header.S
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun *	Copyright (C) 1991, 1992 Linus Torvalds
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun *	Based on bootsect.S and setup.S
8*4882a593Smuzhiyun *	modified by more people than can be counted
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun *	Rewritten as a common file by H. Peter Anvin (Apr 2007)
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
13*4882a593Smuzhiyun * addresses must be multiplied by 16 to obtain their respective linear
14*4882a593Smuzhiyun * addresses. To avoid confusion, linear addresses are written using leading
15*4882a593Smuzhiyun * hex while segment addresses are written as segment:offset.
16*4882a593Smuzhiyun *
17*4882a593Smuzhiyun */
18*4882a593Smuzhiyun#include <linux/pe.h>
19*4882a593Smuzhiyun#include <asm/segment.h>
20*4882a593Smuzhiyun#include <asm/boot.h>
21*4882a593Smuzhiyun#include <asm/page_types.h>
22*4882a593Smuzhiyun#include <asm/setup.h>
23*4882a593Smuzhiyun#include <asm/bootparam.h>
24*4882a593Smuzhiyun#include "boot.h"
25*4882a593Smuzhiyun#include "voffset.h"
26*4882a593Smuzhiyun#include "zoffset.h"
27*4882a593Smuzhiyun
28*4882a593SmuzhiyunBOOTSEG		= 0x07C0		/* original address of boot-sector */
29*4882a593SmuzhiyunSYSSEG		= 0x1000		/* historical load address >> 4 */
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun#ifndef SVGA_MODE
32*4882a593Smuzhiyun#define SVGA_MODE ASK_VGA
33*4882a593Smuzhiyun#endif
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun#ifndef ROOT_RDONLY
36*4882a593Smuzhiyun#define ROOT_RDONLY 1
37*4882a593Smuzhiyun#endif
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun	.code16
40*4882a593Smuzhiyun	.section ".bstext", "ax"
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun	.global bootsect_start
43*4882a593Smuzhiyunbootsect_start:
44*4882a593Smuzhiyun#ifdef CONFIG_EFI_STUB
45*4882a593Smuzhiyun	# "MZ", MS-DOS header
46*4882a593Smuzhiyun	.word	MZ_MAGIC
47*4882a593Smuzhiyun#endif
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun	# Normalize the start address
50*4882a593Smuzhiyun	ljmp	$BOOTSEG, $start2
51*4882a593Smuzhiyun
52*4882a593Smuzhiyunstart2:
53*4882a593Smuzhiyun	movw	%cs, %ax
54*4882a593Smuzhiyun	movw	%ax, %ds
55*4882a593Smuzhiyun	movw	%ax, %es
56*4882a593Smuzhiyun	movw	%ax, %ss
57*4882a593Smuzhiyun	xorw	%sp, %sp
58*4882a593Smuzhiyun	sti
59*4882a593Smuzhiyun	cld
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun	movw	$bugger_off_msg, %si
62*4882a593Smuzhiyun
63*4882a593Smuzhiyunmsg_loop:
64*4882a593Smuzhiyun	lodsb
65*4882a593Smuzhiyun	andb	%al, %al
66*4882a593Smuzhiyun	jz	bs_die
67*4882a593Smuzhiyun	movb	$0xe, %ah
68*4882a593Smuzhiyun	movw	$7, %bx
69*4882a593Smuzhiyun	int	$0x10
70*4882a593Smuzhiyun	jmp	msg_loop
71*4882a593Smuzhiyun
72*4882a593Smuzhiyunbs_die:
73*4882a593Smuzhiyun	# Allow the user to press a key, then reboot
74*4882a593Smuzhiyun	xorw	%ax, %ax
75*4882a593Smuzhiyun	int	$0x16
76*4882a593Smuzhiyun	int	$0x19
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun	# int 0x19 should never return.  In case it does anyway,
79*4882a593Smuzhiyun	# invoke the BIOS reset code...
80*4882a593Smuzhiyun	ljmp	$0xf000,$0xfff0
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun#ifdef CONFIG_EFI_STUB
83*4882a593Smuzhiyun	.org	0x3c
84*4882a593Smuzhiyun	#
85*4882a593Smuzhiyun	# Offset to the PE header.
86*4882a593Smuzhiyun	#
87*4882a593Smuzhiyun	.long	pe_header
88*4882a593Smuzhiyun#endif /* CONFIG_EFI_STUB */
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun	.section ".bsdata", "a"
91*4882a593Smuzhiyunbugger_off_msg:
92*4882a593Smuzhiyun	.ascii	"Use a boot loader.\r\n"
93*4882a593Smuzhiyun	.ascii	"\n"
94*4882a593Smuzhiyun	.ascii	"Remove disk and press any key to reboot...\r\n"
95*4882a593Smuzhiyun	.byte	0
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun#ifdef CONFIG_EFI_STUB
98*4882a593Smuzhiyunpe_header:
99*4882a593Smuzhiyun	.long	PE_MAGIC
100*4882a593Smuzhiyun
101*4882a593Smuzhiyuncoff_header:
102*4882a593Smuzhiyun#ifdef CONFIG_X86_32
103*4882a593Smuzhiyun	.set	image_file_add_flags, IMAGE_FILE_32BIT_MACHINE
104*4882a593Smuzhiyun	.set	pe_opt_magic, PE_OPT_MAGIC_PE32
105*4882a593Smuzhiyun	.word	IMAGE_FILE_MACHINE_I386
106*4882a593Smuzhiyun#else
107*4882a593Smuzhiyun	.set	image_file_add_flags, 0
108*4882a593Smuzhiyun	.set	pe_opt_magic, PE_OPT_MAGIC_PE32PLUS
109*4882a593Smuzhiyun	.word	IMAGE_FILE_MACHINE_AMD64
110*4882a593Smuzhiyun#endif
111*4882a593Smuzhiyun	.word	section_count			# nr_sections
112*4882a593Smuzhiyun	.long	0 				# TimeDateStamp
113*4882a593Smuzhiyun	.long	0				# PointerToSymbolTable
114*4882a593Smuzhiyun	.long	1				# NumberOfSymbols
115*4882a593Smuzhiyun	.word	section_table - optional_header	# SizeOfOptionalHeader
116*4882a593Smuzhiyun	.word	IMAGE_FILE_EXECUTABLE_IMAGE	| \
117*4882a593Smuzhiyun		image_file_add_flags		| \
118*4882a593Smuzhiyun		IMAGE_FILE_DEBUG_STRIPPED	| \
119*4882a593Smuzhiyun		IMAGE_FILE_LINE_NUMS_STRIPPED	# Characteristics
120*4882a593Smuzhiyun
121*4882a593Smuzhiyunoptional_header:
122*4882a593Smuzhiyun	.word	pe_opt_magic
123*4882a593Smuzhiyun	.byte	0x02				# MajorLinkerVersion
124*4882a593Smuzhiyun	.byte	0x14				# MinorLinkerVersion
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun	# Filled in by build.c
127*4882a593Smuzhiyun	.long	0				# SizeOfCode
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun	.long	0				# SizeOfInitializedData
130*4882a593Smuzhiyun	.long	0				# SizeOfUninitializedData
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun	# Filled in by build.c
133*4882a593Smuzhiyun	.long	0x0000				# AddressOfEntryPoint
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun	.long	0x0200				# BaseOfCode
136*4882a593Smuzhiyun#ifdef CONFIG_X86_32
137*4882a593Smuzhiyun	.long	0				# data
138*4882a593Smuzhiyun#endif
139*4882a593Smuzhiyun
140*4882a593Smuzhiyunextra_header_fields:
141*4882a593Smuzhiyun	# PE specification requires ImageBase to be 64k aligned
142*4882a593Smuzhiyun	.set	image_base, (LOAD_PHYSICAL_ADDR + 0xffff) & ~0xffff
143*4882a593Smuzhiyun#ifdef CONFIG_X86_32
144*4882a593Smuzhiyun	.long	image_base			# ImageBase
145*4882a593Smuzhiyun#else
146*4882a593Smuzhiyun	.quad	image_base			# ImageBase
147*4882a593Smuzhiyun#endif
148*4882a593Smuzhiyun	.long	0x20				# SectionAlignment
149*4882a593Smuzhiyun	.long	0x20				# FileAlignment
150*4882a593Smuzhiyun	.word	0				# MajorOperatingSystemVersion
151*4882a593Smuzhiyun	.word	0				# MinorOperatingSystemVersion
152*4882a593Smuzhiyun	.word	LINUX_EFISTUB_MAJOR_VERSION	# MajorImageVersion
153*4882a593Smuzhiyun	.word	LINUX_EFISTUB_MINOR_VERSION	# MinorImageVersion
154*4882a593Smuzhiyun	.word	0				# MajorSubsystemVersion
155*4882a593Smuzhiyun	.word	0				# MinorSubsystemVersion
156*4882a593Smuzhiyun	.long	0				# Win32VersionValue
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun	#
159*4882a593Smuzhiyun	# The size of the bzImage is written in tools/build.c
160*4882a593Smuzhiyun	#
161*4882a593Smuzhiyun	.long	0				# SizeOfImage
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun	.long	0x200				# SizeOfHeaders
164*4882a593Smuzhiyun	.long	0				# CheckSum
165*4882a593Smuzhiyun	.word	IMAGE_SUBSYSTEM_EFI_APPLICATION	# Subsystem (EFI application)
166*4882a593Smuzhiyun	.word	0				# DllCharacteristics
167*4882a593Smuzhiyun#ifdef CONFIG_X86_32
168*4882a593Smuzhiyun	.long	0				# SizeOfStackReserve
169*4882a593Smuzhiyun	.long	0				# SizeOfStackCommit
170*4882a593Smuzhiyun	.long	0				# SizeOfHeapReserve
171*4882a593Smuzhiyun	.long	0				# SizeOfHeapCommit
172*4882a593Smuzhiyun#else
173*4882a593Smuzhiyun	.quad	0				# SizeOfStackReserve
174*4882a593Smuzhiyun	.quad	0				# SizeOfStackCommit
175*4882a593Smuzhiyun	.quad	0				# SizeOfHeapReserve
176*4882a593Smuzhiyun	.quad	0				# SizeOfHeapCommit
177*4882a593Smuzhiyun#endif
178*4882a593Smuzhiyun	.long	0				# LoaderFlags
179*4882a593Smuzhiyun	.long	(section_table - .) / 8		# NumberOfRvaAndSizes
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun	.quad	0				# ExportTable
182*4882a593Smuzhiyun	.quad	0				# ImportTable
183*4882a593Smuzhiyun	.quad	0				# ResourceTable
184*4882a593Smuzhiyun	.quad	0				# ExceptionTable
185*4882a593Smuzhiyun	.quad	0				# CertificationTable
186*4882a593Smuzhiyun	.quad	0				# BaseRelocationTable
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun	# Section table
189*4882a593Smuzhiyunsection_table:
190*4882a593Smuzhiyun	#
191*4882a593Smuzhiyun	# The offset & size fields are filled in by build.c.
192*4882a593Smuzhiyun	#
193*4882a593Smuzhiyun	.ascii	".setup"
194*4882a593Smuzhiyun	.byte	0
195*4882a593Smuzhiyun	.byte	0
196*4882a593Smuzhiyun	.long	0
197*4882a593Smuzhiyun	.long	0x0				# startup_{32,64}
198*4882a593Smuzhiyun	.long	0				# Size of initialized data
199*4882a593Smuzhiyun						# on disk
200*4882a593Smuzhiyun	.long	0x0				# startup_{32,64}
201*4882a593Smuzhiyun	.long	0				# PointerToRelocations
202*4882a593Smuzhiyun	.long	0				# PointerToLineNumbers
203*4882a593Smuzhiyun	.word	0				# NumberOfRelocations
204*4882a593Smuzhiyun	.word	0				# NumberOfLineNumbers
205*4882a593Smuzhiyun	.long	IMAGE_SCN_CNT_CODE		| \
206*4882a593Smuzhiyun		IMAGE_SCN_MEM_READ		| \
207*4882a593Smuzhiyun		IMAGE_SCN_MEM_EXECUTE		| \
208*4882a593Smuzhiyun		IMAGE_SCN_ALIGN_16BYTES		# Characteristics
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun	#
211*4882a593Smuzhiyun	# The EFI application loader requires a relocation section
212*4882a593Smuzhiyun	# because EFI applications must be relocatable. The .reloc
213*4882a593Smuzhiyun	# offset & size fields are filled in by build.c.
214*4882a593Smuzhiyun	#
215*4882a593Smuzhiyun	.ascii	".reloc"
216*4882a593Smuzhiyun	.byte	0
217*4882a593Smuzhiyun	.byte	0
218*4882a593Smuzhiyun	.long	0
219*4882a593Smuzhiyun	.long	0
220*4882a593Smuzhiyun	.long	0				# SizeOfRawData
221*4882a593Smuzhiyun	.long	0				# PointerToRawData
222*4882a593Smuzhiyun	.long	0				# PointerToRelocations
223*4882a593Smuzhiyun	.long	0				# PointerToLineNumbers
224*4882a593Smuzhiyun	.word	0				# NumberOfRelocations
225*4882a593Smuzhiyun	.word	0				# NumberOfLineNumbers
226*4882a593Smuzhiyun	.long	IMAGE_SCN_CNT_INITIALIZED_DATA	| \
227*4882a593Smuzhiyun		IMAGE_SCN_MEM_READ		| \
228*4882a593Smuzhiyun		IMAGE_SCN_MEM_DISCARDABLE	| \
229*4882a593Smuzhiyun		IMAGE_SCN_ALIGN_1BYTES		# Characteristics
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun#ifdef CONFIG_EFI_MIXED
232*4882a593Smuzhiyun	#
233*4882a593Smuzhiyun	# The offset & size fields are filled in by build.c.
234*4882a593Smuzhiyun	#
235*4882a593Smuzhiyun	.asciz	".compat"
236*4882a593Smuzhiyun	.long	0
237*4882a593Smuzhiyun	.long	0x0
238*4882a593Smuzhiyun	.long	0				# Size of initialized data
239*4882a593Smuzhiyun						# on disk
240*4882a593Smuzhiyun	.long	0x0
241*4882a593Smuzhiyun	.long	0				# PointerToRelocations
242*4882a593Smuzhiyun	.long	0				# PointerToLineNumbers
243*4882a593Smuzhiyun	.word	0				# NumberOfRelocations
244*4882a593Smuzhiyun	.word	0				# NumberOfLineNumbers
245*4882a593Smuzhiyun	.long	IMAGE_SCN_CNT_INITIALIZED_DATA	| \
246*4882a593Smuzhiyun		IMAGE_SCN_MEM_READ		| \
247*4882a593Smuzhiyun		IMAGE_SCN_MEM_DISCARDABLE	| \
248*4882a593Smuzhiyun		IMAGE_SCN_ALIGN_1BYTES		# Characteristics
249*4882a593Smuzhiyun#endif
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun	#
252*4882a593Smuzhiyun	# The offset & size fields are filled in by build.c.
253*4882a593Smuzhiyun	#
254*4882a593Smuzhiyun	.ascii	".text"
255*4882a593Smuzhiyun	.byte	0
256*4882a593Smuzhiyun	.byte	0
257*4882a593Smuzhiyun	.byte	0
258*4882a593Smuzhiyun	.long	0
259*4882a593Smuzhiyun	.long	0x0				# startup_{32,64}
260*4882a593Smuzhiyun	.long	0				# Size of initialized data
261*4882a593Smuzhiyun						# on disk
262*4882a593Smuzhiyun	.long	0x0				# startup_{32,64}
263*4882a593Smuzhiyun	.long	0				# PointerToRelocations
264*4882a593Smuzhiyun	.long	0				# PointerToLineNumbers
265*4882a593Smuzhiyun	.word	0				# NumberOfRelocations
266*4882a593Smuzhiyun	.word	0				# NumberOfLineNumbers
267*4882a593Smuzhiyun	.long	IMAGE_SCN_CNT_CODE		| \
268*4882a593Smuzhiyun		IMAGE_SCN_MEM_READ		| \
269*4882a593Smuzhiyun		IMAGE_SCN_MEM_EXECUTE		| \
270*4882a593Smuzhiyun		IMAGE_SCN_ALIGN_16BYTES		# Characteristics
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun	.set	section_count, (. - section_table) / 40
273*4882a593Smuzhiyun#endif /* CONFIG_EFI_STUB */
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun	# Kernel attributes; used by setup.  This is part 1 of the
276*4882a593Smuzhiyun	# header, from the old boot sector.
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun	.section ".header", "a"
279*4882a593Smuzhiyun	.globl	sentinel
280*4882a593Smuzhiyunsentinel:	.byte 0xff, 0xff        /* Used to detect broken loaders */
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun	.globl	hdr
283*4882a593Smuzhiyunhdr:
284*4882a593Smuzhiyunsetup_sects:	.byte 0			/* Filled in by build.c */
285*4882a593Smuzhiyunroot_flags:	.word ROOT_RDONLY
286*4882a593Smuzhiyunsyssize:	.long 0			/* Filled in by build.c */
287*4882a593Smuzhiyunram_size:	.word 0			/* Obsolete */
288*4882a593Smuzhiyunvid_mode:	.word SVGA_MODE
289*4882a593Smuzhiyunroot_dev:	.word 0			/* Filled in by build.c */
290*4882a593Smuzhiyunboot_flag:	.word 0xAA55
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun	# offset 512, entry point
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun	.globl	_start
295*4882a593Smuzhiyun_start:
296*4882a593Smuzhiyun		# Explicitly enter this as bytes, or the assembler
297*4882a593Smuzhiyun		# tries to generate a 3-byte jump here, which causes
298*4882a593Smuzhiyun		# everything else to push off to the wrong offset.
299*4882a593Smuzhiyun		.byte	0xeb		# short (2-byte) jump
300*4882a593Smuzhiyun		.byte	start_of_setup-1f
301*4882a593Smuzhiyun1:
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun	# Part 2 of the header, from the old setup.S
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun		.ascii	"HdrS"		# header signature
306*4882a593Smuzhiyun		.word	0x020f		# header version number (>= 0x0105)
307*4882a593Smuzhiyun					# or else old loadlin-1.5 will fail)
308*4882a593Smuzhiyun		.globl realmode_swtch
309*4882a593Smuzhiyunrealmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
310*4882a593Smuzhiyunstart_sys_seg:	.word	SYSSEG		# obsolete and meaningless, but just
311*4882a593Smuzhiyun					# in case something decided to "use" it
312*4882a593Smuzhiyun		.word	kernel_version-512 # pointing to kernel version string
313*4882a593Smuzhiyun					# above section of header is compatible
314*4882a593Smuzhiyun					# with loadlin-1.5 (header v1.5). Don't
315*4882a593Smuzhiyun					# change it.
316*4882a593Smuzhiyun
317*4882a593Smuzhiyuntype_of_loader:	.byte	0		# 0 means ancient bootloader, newer
318*4882a593Smuzhiyun					# bootloaders know to change this.
319*4882a593Smuzhiyun					# See Documentation/x86/boot.rst for
320*4882a593Smuzhiyun					# assigned ids
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun# flags, unused bits must be zero (RFU) bit within loadflags
323*4882a593Smuzhiyunloadflags:
324*4882a593Smuzhiyun		.byte	LOADED_HIGH	# The kernel is to be loaded high
325*4882a593Smuzhiyun
326*4882a593Smuzhiyunsetup_move_size: .word  0x8000		# size to move, when setup is not
327*4882a593Smuzhiyun					# loaded at 0x90000. We will move setup
328*4882a593Smuzhiyun					# to 0x90000 then just before jumping
329*4882a593Smuzhiyun					# into the kernel. However, only the
330*4882a593Smuzhiyun					# loader knows how much data behind
331*4882a593Smuzhiyun					# us also needs to be loaded.
332*4882a593Smuzhiyun
333*4882a593Smuzhiyuncode32_start:				# here loaders can put a different
334*4882a593Smuzhiyun					# start address for 32-bit code.
335*4882a593Smuzhiyun		.long	0x100000	# 0x100000 = default for big kernel
336*4882a593Smuzhiyun
337*4882a593Smuzhiyunramdisk_image:	.long	0		# address of loaded ramdisk image
338*4882a593Smuzhiyun					# Here the loader puts the 32-bit
339*4882a593Smuzhiyun					# address where it loaded the image.
340*4882a593Smuzhiyun					# This only will be read by the kernel.
341*4882a593Smuzhiyun
342*4882a593Smuzhiyunramdisk_size:	.long	0		# its size in bytes
343*4882a593Smuzhiyun
344*4882a593Smuzhiyunbootsect_kludge:
345*4882a593Smuzhiyun		.long	0		# obsolete
346*4882a593Smuzhiyun
347*4882a593Smuzhiyunheap_end_ptr:	.word	_end+STACK_SIZE-512
348*4882a593Smuzhiyun					# (Header version 0x0201 or later)
349*4882a593Smuzhiyun					# space from here (exclusive) down to
350*4882a593Smuzhiyun					# end of setup code can be used by setup
351*4882a593Smuzhiyun					# for local heap purposes.
352*4882a593Smuzhiyun
353*4882a593Smuzhiyunext_loader_ver:
354*4882a593Smuzhiyun		.byte	0		# Extended boot loader version
355*4882a593Smuzhiyunext_loader_type:
356*4882a593Smuzhiyun		.byte	0		# Extended boot loader type
357*4882a593Smuzhiyun
358*4882a593Smuzhiyuncmd_line_ptr:	.long	0		# (Header version 0x0202 or later)
359*4882a593Smuzhiyun					# If nonzero, a 32-bit pointer
360*4882a593Smuzhiyun					# to the kernel command line.
361*4882a593Smuzhiyun					# The command line should be
362*4882a593Smuzhiyun					# located between the start of
363*4882a593Smuzhiyun					# setup and the end of low
364*4882a593Smuzhiyun					# memory (0xa0000), or it may
365*4882a593Smuzhiyun					# get overwritten before it
366*4882a593Smuzhiyun					# gets read.  If this field is
367*4882a593Smuzhiyun					# used, there is no longer
368*4882a593Smuzhiyun					# anything magical about the
369*4882a593Smuzhiyun					# 0x90000 segment; the setup
370*4882a593Smuzhiyun					# can be located anywhere in
371*4882a593Smuzhiyun					# low memory 0x10000 or higher.
372*4882a593Smuzhiyun
373*4882a593Smuzhiyuninitrd_addr_max: .long 0x7fffffff
374*4882a593Smuzhiyun					# (Header version 0x0203 or later)
375*4882a593Smuzhiyun					# The highest safe address for
376*4882a593Smuzhiyun					# the contents of an initrd
377*4882a593Smuzhiyun					# The current kernel allows up to 4 GB,
378*4882a593Smuzhiyun					# but leave it at 2 GB to avoid
379*4882a593Smuzhiyun					# possible bootloader bugs.
380*4882a593Smuzhiyun
381*4882a593Smuzhiyunkernel_alignment:  .long CONFIG_PHYSICAL_ALIGN	#physical addr alignment
382*4882a593Smuzhiyun						#required for protected mode
383*4882a593Smuzhiyun						#kernel
384*4882a593Smuzhiyun#ifdef CONFIG_RELOCATABLE
385*4882a593Smuzhiyunrelocatable_kernel:    .byte 1
386*4882a593Smuzhiyun#else
387*4882a593Smuzhiyunrelocatable_kernel:    .byte 0
388*4882a593Smuzhiyun#endif
389*4882a593Smuzhiyunmin_alignment:		.byte MIN_KERNEL_ALIGN_LG2	# minimum alignment
390*4882a593Smuzhiyun
391*4882a593Smuzhiyunxloadflags:
392*4882a593Smuzhiyun#ifdef CONFIG_X86_64
393*4882a593Smuzhiyun# define XLF0 XLF_KERNEL_64			/* 64-bit kernel */
394*4882a593Smuzhiyun#else
395*4882a593Smuzhiyun# define XLF0 0
396*4882a593Smuzhiyun#endif
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_X86_64)
399*4882a593Smuzhiyun   /* kernel/boot_param/ramdisk could be loaded above 4g */
400*4882a593Smuzhiyun# define XLF1 XLF_CAN_BE_LOADED_ABOVE_4G
401*4882a593Smuzhiyun#else
402*4882a593Smuzhiyun# define XLF1 0
403*4882a593Smuzhiyun#endif
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun#ifdef CONFIG_EFI_STUB
406*4882a593Smuzhiyun# ifdef CONFIG_EFI_MIXED
407*4882a593Smuzhiyun#  define XLF23 (XLF_EFI_HANDOVER_32|XLF_EFI_HANDOVER_64)
408*4882a593Smuzhiyun# else
409*4882a593Smuzhiyun#  ifdef CONFIG_X86_64
410*4882a593Smuzhiyun#   define XLF23 XLF_EFI_HANDOVER_64		/* 64-bit EFI handover ok */
411*4882a593Smuzhiyun#  else
412*4882a593Smuzhiyun#   define XLF23 XLF_EFI_HANDOVER_32		/* 32-bit EFI handover ok */
413*4882a593Smuzhiyun#  endif
414*4882a593Smuzhiyun# endif
415*4882a593Smuzhiyun#else
416*4882a593Smuzhiyun# define XLF23 0
417*4882a593Smuzhiyun#endif
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun#if defined(CONFIG_X86_64) && defined(CONFIG_EFI) && defined(CONFIG_KEXEC_CORE)
420*4882a593Smuzhiyun# define XLF4 XLF_EFI_KEXEC
421*4882a593Smuzhiyun#else
422*4882a593Smuzhiyun# define XLF4 0
423*4882a593Smuzhiyun#endif
424*4882a593Smuzhiyun
425*4882a593Smuzhiyun#ifdef CONFIG_X86_64
426*4882a593Smuzhiyun#ifdef CONFIG_X86_5LEVEL
427*4882a593Smuzhiyun#define XLF56 (XLF_5LEVEL|XLF_5LEVEL_ENABLED)
428*4882a593Smuzhiyun#else
429*4882a593Smuzhiyun#define XLF56 XLF_5LEVEL
430*4882a593Smuzhiyun#endif
431*4882a593Smuzhiyun#else
432*4882a593Smuzhiyun#define XLF56 0
433*4882a593Smuzhiyun#endif
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun			.word XLF0 | XLF1 | XLF23 | XLF4 | XLF56
436*4882a593Smuzhiyun
437*4882a593Smuzhiyuncmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
438*4882a593Smuzhiyun                                                #added with boot protocol
439*4882a593Smuzhiyun                                                #version 2.06
440*4882a593Smuzhiyun
441*4882a593Smuzhiyunhardware_subarch:	.long 0			# subarchitecture, added with 2.07
442*4882a593Smuzhiyun						# default to 0 for normal x86 PC
443*4882a593Smuzhiyun
444*4882a593Smuzhiyunhardware_subarch_data:	.quad 0
445*4882a593Smuzhiyun
446*4882a593Smuzhiyunpayload_offset:		.long ZO_input_data
447*4882a593Smuzhiyunpayload_length:		.long ZO_z_input_len
448*4882a593Smuzhiyun
449*4882a593Smuzhiyunsetup_data:		.quad 0			# 64-bit physical pointer to
450*4882a593Smuzhiyun						# single linked list of
451*4882a593Smuzhiyun						# struct setup_data
452*4882a593Smuzhiyun
453*4882a593Smuzhiyunpref_address:		.quad LOAD_PHYSICAL_ADDR	# preferred load addr
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun#
456*4882a593Smuzhiyun# Getting to provably safe in-place decompression is hard. Worst case
457*4882a593Smuzhiyun# behaviours need to be analyzed. Here let's take the decompression of
458*4882a593Smuzhiyun# a gzip-compressed kernel as example, to illustrate it:
459*4882a593Smuzhiyun#
460*4882a593Smuzhiyun# The file layout of gzip compressed kernel is:
461*4882a593Smuzhiyun#
462*4882a593Smuzhiyun#    magic[2]
463*4882a593Smuzhiyun#    method[1]
464*4882a593Smuzhiyun#    flags[1]
465*4882a593Smuzhiyun#    timestamp[4]
466*4882a593Smuzhiyun#    extraflags[1]
467*4882a593Smuzhiyun#    os[1]
468*4882a593Smuzhiyun#    compressed data blocks[N]
469*4882a593Smuzhiyun#    crc[4] orig_len[4]
470*4882a593Smuzhiyun#
471*4882a593Smuzhiyun# ... resulting in +18 bytes overhead of uncompressed data.
472*4882a593Smuzhiyun#
473*4882a593Smuzhiyun# (For more information, please refer to RFC 1951 and RFC 1952.)
474*4882a593Smuzhiyun#
475*4882a593Smuzhiyun# Files divided into blocks
476*4882a593Smuzhiyun# 1 bit (last block flag)
477*4882a593Smuzhiyun# 2 bits (block type)
478*4882a593Smuzhiyun#
479*4882a593Smuzhiyun# 1 block occurs every 32K -1 bytes or when there 50% compression
480*4882a593Smuzhiyun# has been achieved. The smallest block type encoding is always used.
481*4882a593Smuzhiyun#
482*4882a593Smuzhiyun# stored:
483*4882a593Smuzhiyun#    32 bits length in bytes.
484*4882a593Smuzhiyun#
485*4882a593Smuzhiyun# fixed:
486*4882a593Smuzhiyun#    magic fixed tree.
487*4882a593Smuzhiyun#    symbols.
488*4882a593Smuzhiyun#
489*4882a593Smuzhiyun# dynamic:
490*4882a593Smuzhiyun#    dynamic tree encoding.
491*4882a593Smuzhiyun#    symbols.
492*4882a593Smuzhiyun#
493*4882a593Smuzhiyun#
494*4882a593Smuzhiyun# The buffer for decompression in place is the length of the uncompressed
495*4882a593Smuzhiyun# data, plus a small amount extra to keep the algorithm safe. The
496*4882a593Smuzhiyun# compressed data is placed at the end of the buffer.  The output pointer
497*4882a593Smuzhiyun# is placed at the start of the buffer and the input pointer is placed
498*4882a593Smuzhiyun# where the compressed data starts. Problems will occur when the output
499*4882a593Smuzhiyun# pointer overruns the input pointer.
500*4882a593Smuzhiyun#
501*4882a593Smuzhiyun# The output pointer can only overrun the input pointer if the input
502*4882a593Smuzhiyun# pointer is moving faster than the output pointer.  A condition only
503*4882a593Smuzhiyun# triggered by data whose compressed form is larger than the uncompressed
504*4882a593Smuzhiyun# form.
505*4882a593Smuzhiyun#
506*4882a593Smuzhiyun# The worst case at the block level is a growth of the compressed data
507*4882a593Smuzhiyun# of 5 bytes per 32767 bytes.
508*4882a593Smuzhiyun#
509*4882a593Smuzhiyun# The worst case internal to a compressed block is very hard to figure.
510*4882a593Smuzhiyun# The worst case can at least be bounded by having one bit that represents
511*4882a593Smuzhiyun# 32764 bytes and then all of the rest of the bytes representing the very
512*4882a593Smuzhiyun# very last byte.
513*4882a593Smuzhiyun#
514*4882a593Smuzhiyun# All of which is enough to compute an amount of extra data that is required
515*4882a593Smuzhiyun# to be safe.  To avoid problems at the block level allocating 5 extra bytes
516*4882a593Smuzhiyun# per 32767 bytes of data is sufficient.  To avoid problems internal to a
517*4882a593Smuzhiyun# block adding an extra 32767 bytes (the worst case uncompressed block size)
518*4882a593Smuzhiyun# is sufficient, to ensure that in the worst case the decompressed data for
519*4882a593Smuzhiyun# block will stop the byte before the compressed data for a block begins.
520*4882a593Smuzhiyun# To avoid problems with the compressed data's meta information an extra 18
521*4882a593Smuzhiyun# bytes are needed.  Leading to the formula:
522*4882a593Smuzhiyun#
523*4882a593Smuzhiyun# extra_bytes = (uncompressed_size >> 12) + 32768 + 18
524*4882a593Smuzhiyun#
525*4882a593Smuzhiyun# Adding 8 bytes per 32K is a bit excessive but much easier to calculate.
526*4882a593Smuzhiyun# Adding 32768 instead of 32767 just makes for round numbers.
527*4882a593Smuzhiyun#
528*4882a593Smuzhiyun# Above analysis is for decompressing gzip compressed kernel only. Up to
529*4882a593Smuzhiyun# now 6 different decompressor are supported all together. And among them
530*4882a593Smuzhiyun# xz stores data in chunks and has maximum chunk of 64K. Hence safety
531*4882a593Smuzhiyun# margin should be updated to cover all decompressors so that we don't
532*4882a593Smuzhiyun# need to deal with each of them separately. Please check
533*4882a593Smuzhiyun# the description in lib/decompressor_xxx.c for specific information.
534*4882a593Smuzhiyun#
535*4882a593Smuzhiyun# extra_bytes = (uncompressed_size >> 12) + 65536 + 128
536*4882a593Smuzhiyun#
537*4882a593Smuzhiyun# LZ4 is even worse: data that cannot be further compressed grows by 0.4%,
538*4882a593Smuzhiyun# or one byte per 256 bytes. OTOH, we can safely get rid of the +128 as
539*4882a593Smuzhiyun# the size-dependent part now grows so fast.
540*4882a593Smuzhiyun#
541*4882a593Smuzhiyun# extra_bytes = (uncompressed_size >> 8) + 65536
542*4882a593Smuzhiyun#
543*4882a593Smuzhiyun# ZSTD compressed data grows by at most 3 bytes per 128K, and only has a 22
544*4882a593Smuzhiyun# byte fixed overhead but has a maximum block size of 128K, so it needs a
545*4882a593Smuzhiyun# larger margin.
546*4882a593Smuzhiyun#
547*4882a593Smuzhiyun# extra_bytes = (uncompressed_size >> 8) + 131072
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun#define ZO_z_extra_bytes	((ZO_z_output_len >> 8) + 131072)
550*4882a593Smuzhiyun#if ZO_z_output_len > ZO_z_input_len
551*4882a593Smuzhiyun# define ZO_z_extract_offset	(ZO_z_output_len + ZO_z_extra_bytes - \
552*4882a593Smuzhiyun				 ZO_z_input_len)
553*4882a593Smuzhiyun#else
554*4882a593Smuzhiyun# define ZO_z_extract_offset	ZO_z_extra_bytes
555*4882a593Smuzhiyun#endif
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun/*
558*4882a593Smuzhiyun * The extract_offset has to be bigger than ZO head section. Otherwise when
559*4882a593Smuzhiyun * the head code is running to move ZO to the end of the buffer, it will
560*4882a593Smuzhiyun * overwrite the head code itself.
561*4882a593Smuzhiyun */
562*4882a593Smuzhiyun#if (ZO__ehead - ZO_startup_32) > ZO_z_extract_offset
563*4882a593Smuzhiyun# define ZO_z_min_extract_offset ((ZO__ehead - ZO_startup_32 + 4095) & ~4095)
564*4882a593Smuzhiyun#else
565*4882a593Smuzhiyun# define ZO_z_min_extract_offset ((ZO_z_extract_offset + 4095) & ~4095)
566*4882a593Smuzhiyun#endif
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun#define ZO_INIT_SIZE	(ZO__end - ZO_startup_32 + ZO_z_min_extract_offset)
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun#define VO_INIT_SIZE	(VO__end - VO__text)
571*4882a593Smuzhiyun#if ZO_INIT_SIZE > VO_INIT_SIZE
572*4882a593Smuzhiyun# define INIT_SIZE ZO_INIT_SIZE
573*4882a593Smuzhiyun#else
574*4882a593Smuzhiyun# define INIT_SIZE VO_INIT_SIZE
575*4882a593Smuzhiyun#endif
576*4882a593Smuzhiyun
577*4882a593Smuzhiyuninit_size:		.long INIT_SIZE		# kernel initialization size
578*4882a593Smuzhiyunhandover_offset:	.long 0			# Filled in by build.c
579*4882a593Smuzhiyunkernel_info_offset:	.long 0			# Filled in by build.c
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun# End of setup header #####################################################
582*4882a593Smuzhiyun
583*4882a593Smuzhiyun	.section ".entrytext", "ax"
584*4882a593Smuzhiyunstart_of_setup:
585*4882a593Smuzhiyun# Force %es = %ds
586*4882a593Smuzhiyun	movw	%ds, %ax
587*4882a593Smuzhiyun	movw	%ax, %es
588*4882a593Smuzhiyun	cld
589*4882a593Smuzhiyun
590*4882a593Smuzhiyun# Apparently some ancient versions of LILO invoked the kernel with %ss != %ds,
591*4882a593Smuzhiyun# which happened to work by accident for the old code.  Recalculate the stack
592*4882a593Smuzhiyun# pointer if %ss is invalid.  Otherwise leave it alone, LOADLIN sets up the
593*4882a593Smuzhiyun# stack behind its own code, so we can't blindly put it directly past the heap.
594*4882a593Smuzhiyun
595*4882a593Smuzhiyun	movw	%ss, %dx
596*4882a593Smuzhiyun	cmpw	%ax, %dx	# %ds == %ss?
597*4882a593Smuzhiyun	movw	%sp, %dx
598*4882a593Smuzhiyun	je	2f		# -> assume %sp is reasonably set
599*4882a593Smuzhiyun
600*4882a593Smuzhiyun	# Invalid %ss, make up a new stack
601*4882a593Smuzhiyun	movw	$_end, %dx
602*4882a593Smuzhiyun	testb	$CAN_USE_HEAP, loadflags
603*4882a593Smuzhiyun	jz	1f
604*4882a593Smuzhiyun	movw	heap_end_ptr, %dx
605*4882a593Smuzhiyun1:	addw	$STACK_SIZE, %dx
606*4882a593Smuzhiyun	jnc	2f
607*4882a593Smuzhiyun	xorw	%dx, %dx	# Prevent wraparound
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun2:	# Now %dx should point to the end of our stack space
610*4882a593Smuzhiyun	andw	$~3, %dx	# dword align (might as well...)
611*4882a593Smuzhiyun	jnz	3f
612*4882a593Smuzhiyun	movw	$0xfffc, %dx	# Make sure we're not zero
613*4882a593Smuzhiyun3:	movw	%ax, %ss
614*4882a593Smuzhiyun	movzwl	%dx, %esp	# Clear upper half of %esp
615*4882a593Smuzhiyun	sti			# Now we should have a working stack
616*4882a593Smuzhiyun
617*4882a593Smuzhiyun# We will have entered with %cs = %ds+0x20, normalize %cs so
618*4882a593Smuzhiyun# it is on par with the other segments.
619*4882a593Smuzhiyun	pushw	%ds
620*4882a593Smuzhiyun	pushw	$6f
621*4882a593Smuzhiyun	lretw
622*4882a593Smuzhiyun6:
623*4882a593Smuzhiyun
624*4882a593Smuzhiyun# Check signature at end of setup
625*4882a593Smuzhiyun	cmpl	$0x5a5aaa55, setup_sig
626*4882a593Smuzhiyun	jne	setup_bad
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun# Zero the bss
629*4882a593Smuzhiyun	movw	$__bss_start, %di
630*4882a593Smuzhiyun	movw	$_end+3, %cx
631*4882a593Smuzhiyun	xorl	%eax, %eax
632*4882a593Smuzhiyun	subw	%di, %cx
633*4882a593Smuzhiyun	shrw	$2, %cx
634*4882a593Smuzhiyun	rep; stosl
635*4882a593Smuzhiyun
636*4882a593Smuzhiyun# Jump to C code (should not return)
637*4882a593Smuzhiyun	calll	main
638*4882a593Smuzhiyun
639*4882a593Smuzhiyun# Setup corrupt somehow...
640*4882a593Smuzhiyunsetup_bad:
641*4882a593Smuzhiyun	movl	$setup_corrupt, %eax
642*4882a593Smuzhiyun	calll	puts
643*4882a593Smuzhiyun	# Fall through...
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun	.globl	die
646*4882a593Smuzhiyun	.type	die, @function
647*4882a593Smuzhiyundie:
648*4882a593Smuzhiyun	hlt
649*4882a593Smuzhiyun	jmp	die
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun	.size	die, .-die
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun	.section ".initdata", "a"
654*4882a593Smuzhiyunsetup_corrupt:
655*4882a593Smuzhiyun	.byte	7
656*4882a593Smuzhiyun	.string	"No setup signature found...\n"
657