xref: /openbmc/linux/Documentation/arch/x86/boot.rst (revision ff61f079)
1*ff61f079SJonathan Corbet.. SPDX-License-Identifier: GPL-2.0
2*ff61f079SJonathan Corbet
3*ff61f079SJonathan Corbet===========================
4*ff61f079SJonathan CorbetThe Linux/x86 Boot Protocol
5*ff61f079SJonathan Corbet===========================
6*ff61f079SJonathan Corbet
7*ff61f079SJonathan CorbetOn the x86 platform, the Linux kernel uses a rather complicated boot
8*ff61f079SJonathan Corbetconvention.  This has evolved partially due to historical aspects, as
9*ff61f079SJonathan Corbetwell as the desire in the early days to have the kernel itself be a
10*ff61f079SJonathan Corbetbootable image, the complicated PC memory model and due to changed
11*ff61f079SJonathan Corbetexpectations in the PC industry caused by the effective demise of
12*ff61f079SJonathan Corbetreal-mode DOS as a mainstream operating system.
13*ff61f079SJonathan Corbet
14*ff61f079SJonathan CorbetCurrently, the following versions of the Linux/x86 boot protocol exist.
15*ff61f079SJonathan Corbet
16*ff61f079SJonathan Corbet=============	============================================================
17*ff61f079SJonathan CorbetOld kernels	zImage/Image support only.  Some very early kernels
18*ff61f079SJonathan Corbet		may not even support a command line.
19*ff61f079SJonathan Corbet
20*ff61f079SJonathan CorbetProtocol 2.00	(Kernel 1.3.73) Added bzImage and initrd support, as
21*ff61f079SJonathan Corbet		well as a formalized way to communicate between the
22*ff61f079SJonathan Corbet		boot loader and the kernel.  setup.S made relocatable,
23*ff61f079SJonathan Corbet		although the traditional setup area still assumed
24*ff61f079SJonathan Corbet		writable.
25*ff61f079SJonathan Corbet
26*ff61f079SJonathan CorbetProtocol 2.01	(Kernel 1.3.76) Added a heap overrun warning.
27*ff61f079SJonathan Corbet
28*ff61f079SJonathan CorbetProtocol 2.02	(Kernel 2.4.0-test3-pre3) New command line protocol.
29*ff61f079SJonathan Corbet		Lower the conventional memory ceiling.	No overwrite
30*ff61f079SJonathan Corbet		of the traditional setup area, thus making booting
31*ff61f079SJonathan Corbet		safe for systems which use the EBDA from SMM or 32-bit
32*ff61f079SJonathan Corbet		BIOS entry points.  zImage deprecated but still
33*ff61f079SJonathan Corbet		supported.
34*ff61f079SJonathan Corbet
35*ff61f079SJonathan CorbetProtocol 2.03	(Kernel 2.4.18-pre1) Explicitly makes the highest possible
36*ff61f079SJonathan Corbet		initrd address available to the bootloader.
37*ff61f079SJonathan Corbet
38*ff61f079SJonathan CorbetProtocol 2.04	(Kernel 2.6.14) Extend the syssize field to four bytes.
39*ff61f079SJonathan Corbet
40*ff61f079SJonathan CorbetProtocol 2.05	(Kernel 2.6.20) Make protected mode kernel relocatable.
41*ff61f079SJonathan Corbet		Introduce relocatable_kernel and kernel_alignment fields.
42*ff61f079SJonathan Corbet
43*ff61f079SJonathan CorbetProtocol 2.06	(Kernel 2.6.22) Added a field that contains the size of
44*ff61f079SJonathan Corbet		the boot command line.
45*ff61f079SJonathan Corbet
46*ff61f079SJonathan CorbetProtocol 2.07	(Kernel 2.6.24) Added paravirtualised boot protocol.
47*ff61f079SJonathan Corbet		Introduced hardware_subarch and hardware_subarch_data
48*ff61f079SJonathan Corbet		and KEEP_SEGMENTS flag in load_flags.
49*ff61f079SJonathan Corbet
50*ff61f079SJonathan CorbetProtocol 2.08	(Kernel 2.6.26) Added crc32 checksum and ELF format
51*ff61f079SJonathan Corbet		payload. Introduced payload_offset and payload_length
52*ff61f079SJonathan Corbet		fields to aid in locating the payload.
53*ff61f079SJonathan Corbet
54*ff61f079SJonathan CorbetProtocol 2.09	(Kernel 2.6.26) Added a field of 64-bit physical
55*ff61f079SJonathan Corbet		pointer to single linked list of struct	setup_data.
56*ff61f079SJonathan Corbet
57*ff61f079SJonathan CorbetProtocol 2.10	(Kernel 2.6.31) Added a protocol for relaxed alignment
58*ff61f079SJonathan Corbet		beyond the kernel_alignment added, new init_size and
59*ff61f079SJonathan Corbet		pref_address fields.  Added extended boot loader IDs.
60*ff61f079SJonathan Corbet
61*ff61f079SJonathan CorbetProtocol 2.11	(Kernel 3.6) Added a field for offset of EFI handover
62*ff61f079SJonathan Corbet		protocol entry point.
63*ff61f079SJonathan Corbet
64*ff61f079SJonathan CorbetProtocol 2.12	(Kernel 3.8) Added the xloadflags field and extension fields
65*ff61f079SJonathan Corbet		to struct boot_params for loading bzImage and ramdisk
66*ff61f079SJonathan Corbet		above 4G in 64bit.
67*ff61f079SJonathan Corbet
68*ff61f079SJonathan CorbetProtocol 2.13	(Kernel 3.14) Support 32- and 64-bit flags being set in
69*ff61f079SJonathan Corbet		xloadflags to support booting a 64-bit kernel from 32-bit
70*ff61f079SJonathan Corbet		EFI
71*ff61f079SJonathan Corbet
72*ff61f079SJonathan CorbetProtocol 2.14	BURNT BY INCORRECT COMMIT
73*ff61f079SJonathan Corbet                ae7e1238e68f2a472a125673ab506d49158c1889
74*ff61f079SJonathan Corbet		(x86/boot: Add ACPI RSDP address to setup_header)
75*ff61f079SJonathan Corbet		DO NOT USE!!! ASSUME SAME AS 2.13.
76*ff61f079SJonathan Corbet
77*ff61f079SJonathan CorbetProtocol 2.15	(Kernel 5.5) Added the kernel_info and kernel_info.setup_type_max.
78*ff61f079SJonathan Corbet=============	============================================================
79*ff61f079SJonathan Corbet
80*ff61f079SJonathan Corbet.. note::
81*ff61f079SJonathan Corbet     The protocol version number should be changed only if the setup header
82*ff61f079SJonathan Corbet     is changed. There is no need to update the version number if boot_params
83*ff61f079SJonathan Corbet     or kernel_info are changed. Additionally, it is recommended to use
84*ff61f079SJonathan Corbet     xloadflags (in this case the protocol version number should not be
85*ff61f079SJonathan Corbet     updated either) or kernel_info to communicate supported Linux kernel
86*ff61f079SJonathan Corbet     features to the boot loader. Due to very limited space available in
87*ff61f079SJonathan Corbet     the original setup header every update to it should be considered
88*ff61f079SJonathan Corbet     with great care. Starting from the protocol 2.15 the primary way to
89*ff61f079SJonathan Corbet     communicate things to the boot loader is the kernel_info.
90*ff61f079SJonathan Corbet
91*ff61f079SJonathan Corbet
92*ff61f079SJonathan CorbetMemory Layout
93*ff61f079SJonathan Corbet=============
94*ff61f079SJonathan Corbet
95*ff61f079SJonathan CorbetThe traditional memory map for the kernel loader, used for Image or
96*ff61f079SJonathan CorbetzImage kernels, typically looks like::
97*ff61f079SJonathan Corbet
98*ff61f079SJonathan Corbet		|			 |
99*ff61f079SJonathan Corbet	0A0000	+------------------------+
100*ff61f079SJonathan Corbet		|  Reserved for BIOS	 |	Do not use.  Reserved for BIOS EBDA.
101*ff61f079SJonathan Corbet	09A000	+------------------------+
102*ff61f079SJonathan Corbet		|  Command line		 |
103*ff61f079SJonathan Corbet		|  Stack/heap		 |	For use by the kernel real-mode code.
104*ff61f079SJonathan Corbet	098000	+------------------------+
105*ff61f079SJonathan Corbet		|  Kernel setup		 |	The kernel real-mode code.
106*ff61f079SJonathan Corbet	090200	+------------------------+
107*ff61f079SJonathan Corbet		|  Kernel boot sector	 |	The kernel legacy boot sector.
108*ff61f079SJonathan Corbet	090000	+------------------------+
109*ff61f079SJonathan Corbet		|  Protected-mode kernel |	The bulk of the kernel image.
110*ff61f079SJonathan Corbet	010000	+------------------------+
111*ff61f079SJonathan Corbet		|  Boot loader		 |	<- Boot sector entry point 0000:7C00
112*ff61f079SJonathan Corbet	001000	+------------------------+
113*ff61f079SJonathan Corbet		|  Reserved for MBR/BIOS |
114*ff61f079SJonathan Corbet	000800	+------------------------+
115*ff61f079SJonathan Corbet		|  Typically used by MBR |
116*ff61f079SJonathan Corbet	000600	+------------------------+
117*ff61f079SJonathan Corbet		|  BIOS use only	 |
118*ff61f079SJonathan Corbet	000000	+------------------------+
119*ff61f079SJonathan Corbet
120*ff61f079SJonathan CorbetWhen using bzImage, the protected-mode kernel was relocated to
121*ff61f079SJonathan Corbet0x100000 ("high memory"), and the kernel real-mode block (boot sector,
122*ff61f079SJonathan Corbetsetup, and stack/heap) was made relocatable to any address between
123*ff61f079SJonathan Corbet0x10000 and end of low memory. Unfortunately, in protocols 2.00 and
124*ff61f079SJonathan Corbet2.01 the 0x90000+ memory range is still used internally by the kernel;
125*ff61f079SJonathan Corbetthe 2.02 protocol resolves that problem.
126*ff61f079SJonathan Corbet
127*ff61f079SJonathan CorbetIt is desirable to keep the "memory ceiling" -- the highest point in
128*ff61f079SJonathan Corbetlow memory touched by the boot loader -- as low as possible, since
129*ff61f079SJonathan Corbetsome newer BIOSes have begun to allocate some rather large amounts of
130*ff61f079SJonathan Corbetmemory, called the Extended BIOS Data Area, near the top of low
131*ff61f079SJonathan Corbetmemory.	 The boot loader should use the "INT 12h" BIOS call to verify
132*ff61f079SJonathan Corbethow much low memory is available.
133*ff61f079SJonathan Corbet
134*ff61f079SJonathan CorbetUnfortunately, if INT 12h reports that the amount of memory is too
135*ff61f079SJonathan Corbetlow, there is usually nothing the boot loader can do but to report an
136*ff61f079SJonathan Corbeterror to the user.  The boot loader should therefore be designed to
137*ff61f079SJonathan Corbettake up as little space in low memory as it reasonably can.  For
138*ff61f079SJonathan CorbetzImage or old bzImage kernels, which need data written into the
139*ff61f079SJonathan Corbet0x90000 segment, the boot loader should make sure not to use memory
140*ff61f079SJonathan Corbetabove the 0x9A000 point; too many BIOSes will break above that point.
141*ff61f079SJonathan Corbet
142*ff61f079SJonathan CorbetFor a modern bzImage kernel with boot protocol version >= 2.02, a
143*ff61f079SJonathan Corbetmemory layout like the following is suggested::
144*ff61f079SJonathan Corbet
145*ff61f079SJonathan Corbet		~                        ~
146*ff61f079SJonathan Corbet		|  Protected-mode kernel |
147*ff61f079SJonathan Corbet	100000  +------------------------+
148*ff61f079SJonathan Corbet		|  I/O memory hole	 |
149*ff61f079SJonathan Corbet	0A0000	+------------------------+
150*ff61f079SJonathan Corbet		|  Reserved for BIOS	 |	Leave as much as possible unused
151*ff61f079SJonathan Corbet		~                        ~
152*ff61f079SJonathan Corbet		|  Command line		 |	(Can also be below the X+10000 mark)
153*ff61f079SJonathan Corbet	X+10000	+------------------------+
154*ff61f079SJonathan Corbet		|  Stack/heap		 |	For use by the kernel real-mode code.
155*ff61f079SJonathan Corbet	X+08000	+------------------------+
156*ff61f079SJonathan Corbet		|  Kernel setup		 |	The kernel real-mode code.
157*ff61f079SJonathan Corbet		|  Kernel boot sector	 |	The kernel legacy boot sector.
158*ff61f079SJonathan Corbet	X       +------------------------+
159*ff61f079SJonathan Corbet		|  Boot loader		 |	<- Boot sector entry point 0000:7C00
160*ff61f079SJonathan Corbet	001000	+------------------------+
161*ff61f079SJonathan Corbet		|  Reserved for MBR/BIOS |
162*ff61f079SJonathan Corbet	000800	+------------------------+
163*ff61f079SJonathan Corbet		|  Typically used by MBR |
164*ff61f079SJonathan Corbet	000600	+------------------------+
165*ff61f079SJonathan Corbet		|  BIOS use only	 |
166*ff61f079SJonathan Corbet	000000	+------------------------+
167*ff61f079SJonathan Corbet
168*ff61f079SJonathan Corbet  ... where the address X is as low as the design of the boot loader permits.
169*ff61f079SJonathan Corbet
170*ff61f079SJonathan Corbet
171*ff61f079SJonathan CorbetThe Real-Mode Kernel Header
172*ff61f079SJonathan Corbet===========================
173*ff61f079SJonathan Corbet
174*ff61f079SJonathan CorbetIn the following text, and anywhere in the kernel boot sequence, "a
175*ff61f079SJonathan Corbetsector" refers to 512 bytes.  It is independent of the actual sector
176*ff61f079SJonathan Corbetsize of the underlying medium.
177*ff61f079SJonathan Corbet
178*ff61f079SJonathan CorbetThe first step in loading a Linux kernel should be to load the
179*ff61f079SJonathan Corbetreal-mode code (boot sector and setup code) and then examine the
180*ff61f079SJonathan Corbetfollowing header at offset 0x01f1.  The real-mode code can total up to
181*ff61f079SJonathan Corbet32K, although the boot loader may choose to load only the first two
182*ff61f079SJonathan Corbetsectors (1K) and then examine the bootup sector size.
183*ff61f079SJonathan Corbet
184*ff61f079SJonathan CorbetThe header looks like:
185*ff61f079SJonathan Corbet
186*ff61f079SJonathan Corbet===========	========	=====================	============================================
187*ff61f079SJonathan CorbetOffset/Size	Proto		Name			Meaning
188*ff61f079SJonathan Corbet===========	========	=====================	============================================
189*ff61f079SJonathan Corbet01F1/1		ALL(1)		setup_sects		The size of the setup in sectors
190*ff61f079SJonathan Corbet01F2/2		ALL		root_flags		If set, the root is mounted readonly
191*ff61f079SJonathan Corbet01F4/4		2.04+(2)	syssize			The size of the 32-bit code in 16-byte paras
192*ff61f079SJonathan Corbet01F8/2		ALL		ram_size		DO NOT USE - for bootsect.S use only
193*ff61f079SJonathan Corbet01FA/2		ALL		vid_mode		Video mode control
194*ff61f079SJonathan Corbet01FC/2		ALL		root_dev		Default root device number
195*ff61f079SJonathan Corbet01FE/2		ALL		boot_flag		0xAA55 magic number
196*ff61f079SJonathan Corbet0200/2		2.00+		jump			Jump instruction
197*ff61f079SJonathan Corbet0202/4		2.00+		header			Magic signature "HdrS"
198*ff61f079SJonathan Corbet0206/2		2.00+		version			Boot protocol version supported
199*ff61f079SJonathan Corbet0208/4		2.00+		realmode_swtch		Boot loader hook (see below)
200*ff61f079SJonathan Corbet020C/2		2.00+		start_sys_seg		The load-low segment (0x1000) (obsolete)
201*ff61f079SJonathan Corbet020E/2		2.00+		kernel_version		Pointer to kernel version string
202*ff61f079SJonathan Corbet0210/1		2.00+		type_of_loader		Boot loader identifier
203*ff61f079SJonathan Corbet0211/1		2.00+		loadflags		Boot protocol option flags
204*ff61f079SJonathan Corbet0212/2		2.00+		setup_move_size		Move to high memory size (used with hooks)
205*ff61f079SJonathan Corbet0214/4		2.00+		code32_start		Boot loader hook (see below)
206*ff61f079SJonathan Corbet0218/4		2.00+		ramdisk_image		initrd load address (set by boot loader)
207*ff61f079SJonathan Corbet021C/4		2.00+		ramdisk_size		initrd size (set by boot loader)
208*ff61f079SJonathan Corbet0220/4		2.00+		bootsect_kludge		DO NOT USE - for bootsect.S use only
209*ff61f079SJonathan Corbet0224/2		2.01+		heap_end_ptr		Free memory after setup end
210*ff61f079SJonathan Corbet0226/1		2.02+(3)	ext_loader_ver		Extended boot loader version
211*ff61f079SJonathan Corbet0227/1		2.02+(3)	ext_loader_type		Extended boot loader ID
212*ff61f079SJonathan Corbet0228/4		2.02+		cmd_line_ptr		32-bit pointer to the kernel command line
213*ff61f079SJonathan Corbet022C/4		2.03+		initrd_addr_max		Highest legal initrd address
214*ff61f079SJonathan Corbet0230/4		2.05+		kernel_alignment	Physical addr alignment required for kernel
215*ff61f079SJonathan Corbet0234/1		2.05+		relocatable_kernel	Whether kernel is relocatable or not
216*ff61f079SJonathan Corbet0235/1		2.10+		min_alignment		Minimum alignment, as a power of two
217*ff61f079SJonathan Corbet0236/2		2.12+		xloadflags		Boot protocol option flags
218*ff61f079SJonathan Corbet0238/4		2.06+		cmdline_size		Maximum size of the kernel command line
219*ff61f079SJonathan Corbet023C/4		2.07+		hardware_subarch	Hardware subarchitecture
220*ff61f079SJonathan Corbet0240/8		2.07+		hardware_subarch_data	Subarchitecture-specific data
221*ff61f079SJonathan Corbet0248/4		2.08+		payload_offset		Offset of kernel payload
222*ff61f079SJonathan Corbet024C/4		2.08+		payload_length		Length of kernel payload
223*ff61f079SJonathan Corbet0250/8		2.09+		setup_data		64-bit physical pointer to linked list
224*ff61f079SJonathan Corbet							of struct setup_data
225*ff61f079SJonathan Corbet0258/8		2.10+		pref_address		Preferred loading address
226*ff61f079SJonathan Corbet0260/4		2.10+		init_size		Linear memory required during initialization
227*ff61f079SJonathan Corbet0264/4		2.11+		handover_offset		Offset of handover entry point
228*ff61f079SJonathan Corbet0268/4		2.15+		kernel_info_offset	Offset of the kernel_info
229*ff61f079SJonathan Corbet===========	========	=====================	============================================
230*ff61f079SJonathan Corbet
231*ff61f079SJonathan Corbet.. note::
232*ff61f079SJonathan Corbet  (1) For backwards compatibility, if the setup_sects field contains 0, the
233*ff61f079SJonathan Corbet      real value is 4.
234*ff61f079SJonathan Corbet
235*ff61f079SJonathan Corbet  (2) For boot protocol prior to 2.04, the upper two bytes of the syssize
236*ff61f079SJonathan Corbet      field are unusable, which means the size of a bzImage kernel
237*ff61f079SJonathan Corbet      cannot be determined.
238*ff61f079SJonathan Corbet
239*ff61f079SJonathan Corbet  (3) Ignored, but safe to set, for boot protocols 2.02-2.09.
240*ff61f079SJonathan Corbet
241*ff61f079SJonathan CorbetIf the "HdrS" (0x53726448) magic number is not found at offset 0x202,
242*ff61f079SJonathan Corbetthe boot protocol version is "old".  Loading an old kernel, the
243*ff61f079SJonathan Corbetfollowing parameters should be assumed::
244*ff61f079SJonathan Corbet
245*ff61f079SJonathan Corbet	Image type = zImage
246*ff61f079SJonathan Corbet	initrd not supported
247*ff61f079SJonathan Corbet	Real-mode kernel must be located at 0x90000.
248*ff61f079SJonathan Corbet
249*ff61f079SJonathan CorbetOtherwise, the "version" field contains the protocol version,
250*ff61f079SJonathan Corbete.g. protocol version 2.01 will contain 0x0201 in this field.  When
251*ff61f079SJonathan Corbetsetting fields in the header, you must make sure only to set fields
252*ff61f079SJonathan Corbetsupported by the protocol version in use.
253*ff61f079SJonathan Corbet
254*ff61f079SJonathan Corbet
255*ff61f079SJonathan CorbetDetails of Header Fields
256*ff61f079SJonathan Corbet========================
257*ff61f079SJonathan Corbet
258*ff61f079SJonathan CorbetFor each field, some are information from the kernel to the bootloader
259*ff61f079SJonathan Corbet("read"), some are expected to be filled out by the bootloader
260*ff61f079SJonathan Corbet("write"), and some are expected to be read and modified by the
261*ff61f079SJonathan Corbetbootloader ("modify").
262*ff61f079SJonathan Corbet
263*ff61f079SJonathan CorbetAll general purpose boot loaders should write the fields marked
264*ff61f079SJonathan Corbet(obligatory).  Boot loaders who want to load the kernel at a
265*ff61f079SJonathan Corbetnonstandard address should fill in the fields marked (reloc); other
266*ff61f079SJonathan Corbetboot loaders can ignore those fields.
267*ff61f079SJonathan Corbet
268*ff61f079SJonathan CorbetThe byte order of all fields is littleendian (this is x86, after all.)
269*ff61f079SJonathan Corbet
270*ff61f079SJonathan Corbet============	===========
271*ff61f079SJonathan CorbetField name:	setup_sects
272*ff61f079SJonathan CorbetType:		read
273*ff61f079SJonathan CorbetOffset/size:	0x1f1/1
274*ff61f079SJonathan CorbetProtocol:	ALL
275*ff61f079SJonathan Corbet============	===========
276*ff61f079SJonathan Corbet
277*ff61f079SJonathan Corbet  The size of the setup code in 512-byte sectors.  If this field is
278*ff61f079SJonathan Corbet  0, the real value is 4.  The real-mode code consists of the boot
279*ff61f079SJonathan Corbet  sector (always one 512-byte sector) plus the setup code.
280*ff61f079SJonathan Corbet
281*ff61f079SJonathan Corbet============	=================
282*ff61f079SJonathan CorbetField name:	root_flags
283*ff61f079SJonathan CorbetType:		modify (optional)
284*ff61f079SJonathan CorbetOffset/size:	0x1f2/2
285*ff61f079SJonathan CorbetProtocol:	ALL
286*ff61f079SJonathan Corbet============	=================
287*ff61f079SJonathan Corbet
288*ff61f079SJonathan Corbet  If this field is nonzero, the root defaults to readonly.  The use of
289*ff61f079SJonathan Corbet  this field is deprecated; use the "ro" or "rw" options on the
290*ff61f079SJonathan Corbet  command line instead.
291*ff61f079SJonathan Corbet
292*ff61f079SJonathan Corbet============	===============================================
293*ff61f079SJonathan CorbetField name:	syssize
294*ff61f079SJonathan CorbetType:		read
295*ff61f079SJonathan CorbetOffset/size:	0x1f4/4 (protocol 2.04+) 0x1f4/2 (protocol ALL)
296*ff61f079SJonathan CorbetProtocol:	2.04+
297*ff61f079SJonathan Corbet============	===============================================
298*ff61f079SJonathan Corbet
299*ff61f079SJonathan Corbet  The size of the protected-mode code in units of 16-byte paragraphs.
300*ff61f079SJonathan Corbet  For protocol versions older than 2.04 this field is only two bytes
301*ff61f079SJonathan Corbet  wide, and therefore cannot be trusted for the size of a kernel if
302*ff61f079SJonathan Corbet  the LOAD_HIGH flag is set.
303*ff61f079SJonathan Corbet
304*ff61f079SJonathan Corbet============	===============
305*ff61f079SJonathan CorbetField name:	ram_size
306*ff61f079SJonathan CorbetType:		kernel internal
307*ff61f079SJonathan CorbetOffset/size:	0x1f8/2
308*ff61f079SJonathan CorbetProtocol:	ALL
309*ff61f079SJonathan Corbet============	===============
310*ff61f079SJonathan Corbet
311*ff61f079SJonathan Corbet  This field is obsolete.
312*ff61f079SJonathan Corbet
313*ff61f079SJonathan Corbet============	===================
314*ff61f079SJonathan CorbetField name:	vid_mode
315*ff61f079SJonathan CorbetType:		modify (obligatory)
316*ff61f079SJonathan CorbetOffset/size:	0x1fa/2
317*ff61f079SJonathan Corbet============	===================
318*ff61f079SJonathan Corbet
319*ff61f079SJonathan Corbet  Please see the section on SPECIAL COMMAND LINE OPTIONS.
320*ff61f079SJonathan Corbet
321*ff61f079SJonathan Corbet============	=================
322*ff61f079SJonathan CorbetField name:	root_dev
323*ff61f079SJonathan CorbetType:		modify (optional)
324*ff61f079SJonathan CorbetOffset/size:	0x1fc/2
325*ff61f079SJonathan CorbetProtocol:	ALL
326*ff61f079SJonathan Corbet============	=================
327*ff61f079SJonathan Corbet
328*ff61f079SJonathan Corbet  The default root device device number.  The use of this field is
329*ff61f079SJonathan Corbet  deprecated, use the "root=" option on the command line instead.
330*ff61f079SJonathan Corbet
331*ff61f079SJonathan Corbet============	=========
332*ff61f079SJonathan CorbetField name:	boot_flag
333*ff61f079SJonathan CorbetType:		read
334*ff61f079SJonathan CorbetOffset/size:	0x1fe/2
335*ff61f079SJonathan CorbetProtocol:	ALL
336*ff61f079SJonathan Corbet============	=========
337*ff61f079SJonathan Corbet
338*ff61f079SJonathan Corbet  Contains 0xAA55.  This is the closest thing old Linux kernels have
339*ff61f079SJonathan Corbet  to a magic number.
340*ff61f079SJonathan Corbet
341*ff61f079SJonathan Corbet============	=======
342*ff61f079SJonathan CorbetField name:	jump
343*ff61f079SJonathan CorbetType:		read
344*ff61f079SJonathan CorbetOffset/size:	0x200/2
345*ff61f079SJonathan CorbetProtocol:	2.00+
346*ff61f079SJonathan Corbet============	=======
347*ff61f079SJonathan Corbet
348*ff61f079SJonathan Corbet  Contains an x86 jump instruction, 0xEB followed by a signed offset
349*ff61f079SJonathan Corbet  relative to byte 0x202.  This can be used to determine the size of
350*ff61f079SJonathan Corbet  the header.
351*ff61f079SJonathan Corbet
352*ff61f079SJonathan Corbet============	=======
353*ff61f079SJonathan CorbetField name:	header
354*ff61f079SJonathan CorbetType:		read
355*ff61f079SJonathan CorbetOffset/size:	0x202/4
356*ff61f079SJonathan CorbetProtocol:	2.00+
357*ff61f079SJonathan Corbet============	=======
358*ff61f079SJonathan Corbet
359*ff61f079SJonathan Corbet  Contains the magic number "HdrS" (0x53726448).
360*ff61f079SJonathan Corbet
361*ff61f079SJonathan Corbet============	=======
362*ff61f079SJonathan CorbetField name:	version
363*ff61f079SJonathan CorbetType:		read
364*ff61f079SJonathan CorbetOffset/size:	0x206/2
365*ff61f079SJonathan CorbetProtocol:	2.00+
366*ff61f079SJonathan Corbet============	=======
367*ff61f079SJonathan Corbet
368*ff61f079SJonathan Corbet  Contains the boot protocol version, in (major << 8)+minor format,
369*ff61f079SJonathan Corbet  e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version
370*ff61f079SJonathan Corbet  10.17.
371*ff61f079SJonathan Corbet
372*ff61f079SJonathan Corbet============	=================
373*ff61f079SJonathan CorbetField name:	realmode_swtch
374*ff61f079SJonathan CorbetType:		modify (optional)
375*ff61f079SJonathan CorbetOffset/size:	0x208/4
376*ff61f079SJonathan CorbetProtocol:	2.00+
377*ff61f079SJonathan Corbet============	=================
378*ff61f079SJonathan Corbet
379*ff61f079SJonathan Corbet  Boot loader hook (see ADVANCED BOOT LOADER HOOKS below.)
380*ff61f079SJonathan Corbet
381*ff61f079SJonathan Corbet============	=============
382*ff61f079SJonathan CorbetField name:	start_sys_seg
383*ff61f079SJonathan CorbetType:		read
384*ff61f079SJonathan CorbetOffset/size:	0x20c/2
385*ff61f079SJonathan CorbetProtocol:	2.00+
386*ff61f079SJonathan Corbet============	=============
387*ff61f079SJonathan Corbet
388*ff61f079SJonathan Corbet  The load low segment (0x1000).  Obsolete.
389*ff61f079SJonathan Corbet
390*ff61f079SJonathan Corbet============	==============
391*ff61f079SJonathan CorbetField name:	kernel_version
392*ff61f079SJonathan CorbetType:		read
393*ff61f079SJonathan CorbetOffset/size:	0x20e/2
394*ff61f079SJonathan CorbetProtocol:	2.00+
395*ff61f079SJonathan Corbet============	==============
396*ff61f079SJonathan Corbet
397*ff61f079SJonathan Corbet  If set to a nonzero value, contains a pointer to a NUL-terminated
398*ff61f079SJonathan Corbet  human-readable kernel version number string, less 0x200.  This can
399*ff61f079SJonathan Corbet  be used to display the kernel version to the user.  This value
400*ff61f079SJonathan Corbet  should be less than (0x200*setup_sects).
401*ff61f079SJonathan Corbet
402*ff61f079SJonathan Corbet  For example, if this value is set to 0x1c00, the kernel version
403*ff61f079SJonathan Corbet  number string can be found at offset 0x1e00 in the kernel file.
404*ff61f079SJonathan Corbet  This is a valid value if and only if the "setup_sects" field
405*ff61f079SJonathan Corbet  contains the value 15 or higher, as::
406*ff61f079SJonathan Corbet
407*ff61f079SJonathan Corbet	0x1c00  < 15*0x200 (= 0x1e00) but
408*ff61f079SJonathan Corbet	0x1c00 >= 14*0x200 (= 0x1c00)
409*ff61f079SJonathan Corbet
410*ff61f079SJonathan Corbet	0x1c00 >> 9 = 14, So the minimum value for setup_secs is 15.
411*ff61f079SJonathan Corbet
412*ff61f079SJonathan Corbet============	==================
413*ff61f079SJonathan CorbetField name:	type_of_loader
414*ff61f079SJonathan CorbetType:		write (obligatory)
415*ff61f079SJonathan CorbetOffset/size:	0x210/1
416*ff61f079SJonathan CorbetProtocol:	2.00+
417*ff61f079SJonathan Corbet============	==================
418*ff61f079SJonathan Corbet
419*ff61f079SJonathan Corbet  If your boot loader has an assigned id (see table below), enter
420*ff61f079SJonathan Corbet  0xTV here, where T is an identifier for the boot loader and V is
421*ff61f079SJonathan Corbet  a version number.  Otherwise, enter 0xFF here.
422*ff61f079SJonathan Corbet
423*ff61f079SJonathan Corbet  For boot loader IDs above T = 0xD, write T = 0xE to this field and
424*ff61f079SJonathan Corbet  write the extended ID minus 0x10 to the ext_loader_type field.
425*ff61f079SJonathan Corbet  Similarly, the ext_loader_ver field can be used to provide more than
426*ff61f079SJonathan Corbet  four bits for the bootloader version.
427*ff61f079SJonathan Corbet
428*ff61f079SJonathan Corbet  For example, for T = 0x15, V = 0x234, write::
429*ff61f079SJonathan Corbet
430*ff61f079SJonathan Corbet	type_of_loader  <- 0xE4
431*ff61f079SJonathan Corbet	ext_loader_type <- 0x05
432*ff61f079SJonathan Corbet	ext_loader_ver  <- 0x23
433*ff61f079SJonathan Corbet
434*ff61f079SJonathan Corbet  Assigned boot loader ids (hexadecimal):
435*ff61f079SJonathan Corbet
436*ff61f079SJonathan Corbet	== =======================================
437*ff61f079SJonathan Corbet	0  LILO
438*ff61f079SJonathan Corbet	   (0x00 reserved for pre-2.00 bootloader)
439*ff61f079SJonathan Corbet	1  Loadlin
440*ff61f079SJonathan Corbet	2  bootsect-loader
441*ff61f079SJonathan Corbet	   (0x20, all other values reserved)
442*ff61f079SJonathan Corbet	3  Syslinux
443*ff61f079SJonathan Corbet	4  Etherboot/gPXE/iPXE
444*ff61f079SJonathan Corbet	5  ELILO
445*ff61f079SJonathan Corbet	7  GRUB
446*ff61f079SJonathan Corbet	8  U-Boot
447*ff61f079SJonathan Corbet	9  Xen
448*ff61f079SJonathan Corbet	A  Gujin
449*ff61f079SJonathan Corbet	B  Qemu
450*ff61f079SJonathan Corbet	C  Arcturus Networks uCbootloader
451*ff61f079SJonathan Corbet	D  kexec-tools
452*ff61f079SJonathan Corbet	E  Extended (see ext_loader_type)
453*ff61f079SJonathan Corbet	F  Special (0xFF = undefined)
454*ff61f079SJonathan Corbet	10 Reserved
455*ff61f079SJonathan Corbet	11 Minimal Linux Bootloader
456*ff61f079SJonathan Corbet	   <http://sebastian-plotz.blogspot.de>
457*ff61f079SJonathan Corbet	12 OVMF UEFI virtualization stack
458*ff61f079SJonathan Corbet	13 barebox
459*ff61f079SJonathan Corbet	== =======================================
460*ff61f079SJonathan Corbet
461*ff61f079SJonathan Corbet  Please contact <hpa@zytor.com> if you need a bootloader ID value assigned.
462*ff61f079SJonathan Corbet
463*ff61f079SJonathan Corbet============	===================
464*ff61f079SJonathan CorbetField name:	loadflags
465*ff61f079SJonathan CorbetType:		modify (obligatory)
466*ff61f079SJonathan CorbetOffset/size:	0x211/1
467*ff61f079SJonathan CorbetProtocol:	2.00+
468*ff61f079SJonathan Corbet============	===================
469*ff61f079SJonathan Corbet
470*ff61f079SJonathan Corbet  This field is a bitmask.
471*ff61f079SJonathan Corbet
472*ff61f079SJonathan Corbet  Bit 0 (read):	LOADED_HIGH
473*ff61f079SJonathan Corbet
474*ff61f079SJonathan Corbet	- If 0, the protected-mode code is loaded at 0x10000.
475*ff61f079SJonathan Corbet	- If 1, the protected-mode code is loaded at 0x100000.
476*ff61f079SJonathan Corbet
477*ff61f079SJonathan Corbet  Bit 1 (kernel internal): KASLR_FLAG
478*ff61f079SJonathan Corbet
479*ff61f079SJonathan Corbet	- Used internally by the compressed kernel to communicate
480*ff61f079SJonathan Corbet	  KASLR status to kernel proper.
481*ff61f079SJonathan Corbet
482*ff61f079SJonathan Corbet	    - If 1, KASLR enabled.
483*ff61f079SJonathan Corbet	    - If 0, KASLR disabled.
484*ff61f079SJonathan Corbet
485*ff61f079SJonathan Corbet  Bit 5 (write): QUIET_FLAG
486*ff61f079SJonathan Corbet
487*ff61f079SJonathan Corbet	- If 0, print early messages.
488*ff61f079SJonathan Corbet	- If 1, suppress early messages.
489*ff61f079SJonathan Corbet
490*ff61f079SJonathan Corbet		This requests to the kernel (decompressor and early
491*ff61f079SJonathan Corbet		kernel) to not write early messages that require
492*ff61f079SJonathan Corbet		accessing the display hardware directly.
493*ff61f079SJonathan Corbet
494*ff61f079SJonathan Corbet  Bit 6 (obsolete): KEEP_SEGMENTS
495*ff61f079SJonathan Corbet
496*ff61f079SJonathan Corbet	Protocol: 2.07+
497*ff61f079SJonathan Corbet
498*ff61f079SJonathan Corbet        - This flag is obsolete.
499*ff61f079SJonathan Corbet
500*ff61f079SJonathan Corbet  Bit 7 (write): CAN_USE_HEAP
501*ff61f079SJonathan Corbet
502*ff61f079SJonathan Corbet	Set this bit to 1 to indicate that the value entered in the
503*ff61f079SJonathan Corbet	heap_end_ptr is valid.  If this field is clear, some setup code
504*ff61f079SJonathan Corbet	functionality will be disabled.
505*ff61f079SJonathan Corbet
506*ff61f079SJonathan Corbet
507*ff61f079SJonathan Corbet============	===================
508*ff61f079SJonathan CorbetField name:	setup_move_size
509*ff61f079SJonathan CorbetType:		modify (obligatory)
510*ff61f079SJonathan CorbetOffset/size:	0x212/2
511*ff61f079SJonathan CorbetProtocol:	2.00-2.01
512*ff61f079SJonathan Corbet============	===================
513*ff61f079SJonathan Corbet
514*ff61f079SJonathan Corbet  When using protocol 2.00 or 2.01, if the real mode kernel is not
515*ff61f079SJonathan Corbet  loaded at 0x90000, it gets moved there later in the loading
516*ff61f079SJonathan Corbet  sequence.  Fill in this field if you want additional data (such as
517*ff61f079SJonathan Corbet  the kernel command line) moved in addition to the real-mode kernel
518*ff61f079SJonathan Corbet  itself.
519*ff61f079SJonathan Corbet
520*ff61f079SJonathan Corbet  The unit is bytes starting with the beginning of the boot sector.
521*ff61f079SJonathan Corbet
522*ff61f079SJonathan Corbet  This field is can be ignored when the protocol is 2.02 or higher, or
523*ff61f079SJonathan Corbet  if the real-mode code is loaded at 0x90000.
524*ff61f079SJonathan Corbet
525*ff61f079SJonathan Corbet============	========================
526*ff61f079SJonathan CorbetField name:	code32_start
527*ff61f079SJonathan CorbetType:		modify (optional, reloc)
528*ff61f079SJonathan CorbetOffset/size:	0x214/4
529*ff61f079SJonathan CorbetProtocol:	2.00+
530*ff61f079SJonathan Corbet============	========================
531*ff61f079SJonathan Corbet
532*ff61f079SJonathan Corbet  The address to jump to in protected mode.  This defaults to the load
533*ff61f079SJonathan Corbet  address of the kernel, and can be used by the boot loader to
534*ff61f079SJonathan Corbet  determine the proper load address.
535*ff61f079SJonathan Corbet
536*ff61f079SJonathan Corbet  This field can be modified for two purposes:
537*ff61f079SJonathan Corbet
538*ff61f079SJonathan Corbet    1. as a boot loader hook (see Advanced Boot Loader Hooks below.)
539*ff61f079SJonathan Corbet
540*ff61f079SJonathan Corbet    2. if a bootloader which does not install a hook loads a
541*ff61f079SJonathan Corbet       relocatable kernel at a nonstandard address it will have to modify
542*ff61f079SJonathan Corbet       this field to point to the load address.
543*ff61f079SJonathan Corbet
544*ff61f079SJonathan Corbet============	==================
545*ff61f079SJonathan CorbetField name:	ramdisk_image
546*ff61f079SJonathan CorbetType:		write (obligatory)
547*ff61f079SJonathan CorbetOffset/size:	0x218/4
548*ff61f079SJonathan CorbetProtocol:	2.00+
549*ff61f079SJonathan Corbet============	==================
550*ff61f079SJonathan Corbet
551*ff61f079SJonathan Corbet  The 32-bit linear address of the initial ramdisk or ramfs.  Leave at
552*ff61f079SJonathan Corbet  zero if there is no initial ramdisk/ramfs.
553*ff61f079SJonathan Corbet
554*ff61f079SJonathan Corbet============	==================
555*ff61f079SJonathan CorbetField name:	ramdisk_size
556*ff61f079SJonathan CorbetType:		write (obligatory)
557*ff61f079SJonathan CorbetOffset/size:	0x21c/4
558*ff61f079SJonathan CorbetProtocol:	2.00+
559*ff61f079SJonathan Corbet============	==================
560*ff61f079SJonathan Corbet
561*ff61f079SJonathan Corbet  Size of the initial ramdisk or ramfs.  Leave at zero if there is no
562*ff61f079SJonathan Corbet  initial ramdisk/ramfs.
563*ff61f079SJonathan Corbet
564*ff61f079SJonathan Corbet============	===============
565*ff61f079SJonathan CorbetField name:	bootsect_kludge
566*ff61f079SJonathan CorbetType:		kernel internal
567*ff61f079SJonathan CorbetOffset/size:	0x220/4
568*ff61f079SJonathan CorbetProtocol:	2.00+
569*ff61f079SJonathan Corbet============	===============
570*ff61f079SJonathan Corbet
571*ff61f079SJonathan Corbet  This field is obsolete.
572*ff61f079SJonathan Corbet
573*ff61f079SJonathan Corbet============	==================
574*ff61f079SJonathan CorbetField name:	heap_end_ptr
575*ff61f079SJonathan CorbetType:		write (obligatory)
576*ff61f079SJonathan CorbetOffset/size:	0x224/2
577*ff61f079SJonathan CorbetProtocol:	2.01+
578*ff61f079SJonathan Corbet============	==================
579*ff61f079SJonathan Corbet
580*ff61f079SJonathan Corbet  Set this field to the offset (from the beginning of the real-mode
581*ff61f079SJonathan Corbet  code) of the end of the setup stack/heap, minus 0x0200.
582*ff61f079SJonathan Corbet
583*ff61f079SJonathan Corbet============	================
584*ff61f079SJonathan CorbetField name:	ext_loader_ver
585*ff61f079SJonathan CorbetType:		write (optional)
586*ff61f079SJonathan CorbetOffset/size:	0x226/1
587*ff61f079SJonathan CorbetProtocol:	2.02+
588*ff61f079SJonathan Corbet============	================
589*ff61f079SJonathan Corbet
590*ff61f079SJonathan Corbet  This field is used as an extension of the version number in the
591*ff61f079SJonathan Corbet  type_of_loader field.  The total version number is considered to be
592*ff61f079SJonathan Corbet  (type_of_loader & 0x0f) + (ext_loader_ver << 4).
593*ff61f079SJonathan Corbet
594*ff61f079SJonathan Corbet  The use of this field is boot loader specific.  If not written, it
595*ff61f079SJonathan Corbet  is zero.
596*ff61f079SJonathan Corbet
597*ff61f079SJonathan Corbet  Kernels prior to 2.6.31 did not recognize this field, but it is safe
598*ff61f079SJonathan Corbet  to write for protocol version 2.02 or higher.
599*ff61f079SJonathan Corbet
600*ff61f079SJonathan Corbet============	=====================================================
601*ff61f079SJonathan CorbetField name:	ext_loader_type
602*ff61f079SJonathan CorbetType:		write (obligatory if (type_of_loader & 0xf0) == 0xe0)
603*ff61f079SJonathan CorbetOffset/size:	0x227/1
604*ff61f079SJonathan CorbetProtocol:	2.02+
605*ff61f079SJonathan Corbet============	=====================================================
606*ff61f079SJonathan Corbet
607*ff61f079SJonathan Corbet  This field is used as an extension of the type number in
608*ff61f079SJonathan Corbet  type_of_loader field.  If the type in type_of_loader is 0xE, then
609*ff61f079SJonathan Corbet  the actual type is (ext_loader_type + 0x10).
610*ff61f079SJonathan Corbet
611*ff61f079SJonathan Corbet  This field is ignored if the type in type_of_loader is not 0xE.
612*ff61f079SJonathan Corbet
613*ff61f079SJonathan Corbet  Kernels prior to 2.6.31 did not recognize this field, but it is safe
614*ff61f079SJonathan Corbet  to write for protocol version 2.02 or higher.
615*ff61f079SJonathan Corbet
616*ff61f079SJonathan Corbet============	==================
617*ff61f079SJonathan CorbetField name:	cmd_line_ptr
618*ff61f079SJonathan CorbetType:		write (obligatory)
619*ff61f079SJonathan CorbetOffset/size:	0x228/4
620*ff61f079SJonathan CorbetProtocol:	2.02+
621*ff61f079SJonathan Corbet============	==================
622*ff61f079SJonathan Corbet
623*ff61f079SJonathan Corbet  Set this field to the linear address of the kernel command line.
624*ff61f079SJonathan Corbet  The kernel command line can be located anywhere between the end of
625*ff61f079SJonathan Corbet  the setup heap and 0xA0000; it does not have to be located in the
626*ff61f079SJonathan Corbet  same 64K segment as the real-mode code itself.
627*ff61f079SJonathan Corbet
628*ff61f079SJonathan Corbet  Fill in this field even if your boot loader does not support a
629*ff61f079SJonathan Corbet  command line, in which case you can point this to an empty string
630*ff61f079SJonathan Corbet  (or better yet, to the string "auto".)  If this field is left at
631*ff61f079SJonathan Corbet  zero, the kernel will assume that your boot loader does not support
632*ff61f079SJonathan Corbet  the 2.02+ protocol.
633*ff61f079SJonathan Corbet
634*ff61f079SJonathan Corbet============	===============
635*ff61f079SJonathan CorbetField name:	initrd_addr_max
636*ff61f079SJonathan CorbetType:		read
637*ff61f079SJonathan CorbetOffset/size:	0x22c/4
638*ff61f079SJonathan CorbetProtocol:	2.03+
639*ff61f079SJonathan Corbet============	===============
640*ff61f079SJonathan Corbet
641*ff61f079SJonathan Corbet  The maximum address that may be occupied by the initial
642*ff61f079SJonathan Corbet  ramdisk/ramfs contents.  For boot protocols 2.02 or earlier, this
643*ff61f079SJonathan Corbet  field is not present, and the maximum address is 0x37FFFFFF.  (This
644*ff61f079SJonathan Corbet  address is defined as the address of the highest safe byte, so if
645*ff61f079SJonathan Corbet  your ramdisk is exactly 131072 bytes long and this field is
646*ff61f079SJonathan Corbet  0x37FFFFFF, you can start your ramdisk at 0x37FE0000.)
647*ff61f079SJonathan Corbet
648*ff61f079SJonathan Corbet============	============================
649*ff61f079SJonathan CorbetField name:	kernel_alignment
650*ff61f079SJonathan CorbetType:		read/modify (reloc)
651*ff61f079SJonathan CorbetOffset/size:	0x230/4
652*ff61f079SJonathan CorbetProtocol:	2.05+ (read), 2.10+ (modify)
653*ff61f079SJonathan Corbet============	============================
654*ff61f079SJonathan Corbet
655*ff61f079SJonathan Corbet  Alignment unit required by the kernel (if relocatable_kernel is
656*ff61f079SJonathan Corbet  true.)  A relocatable kernel that is loaded at an alignment
657*ff61f079SJonathan Corbet  incompatible with the value in this field will be realigned during
658*ff61f079SJonathan Corbet  kernel initialization.
659*ff61f079SJonathan Corbet
660*ff61f079SJonathan Corbet  Starting with protocol version 2.10, this reflects the kernel
661*ff61f079SJonathan Corbet  alignment preferred for optimal performance; it is possible for the
662*ff61f079SJonathan Corbet  loader to modify this field to permit a lesser alignment.  See the
663*ff61f079SJonathan Corbet  min_alignment and pref_address field below.
664*ff61f079SJonathan Corbet
665*ff61f079SJonathan Corbet============	==================
666*ff61f079SJonathan CorbetField name:	relocatable_kernel
667*ff61f079SJonathan CorbetType:		read (reloc)
668*ff61f079SJonathan CorbetOffset/size:	0x234/1
669*ff61f079SJonathan CorbetProtocol:	2.05+
670*ff61f079SJonathan Corbet============	==================
671*ff61f079SJonathan Corbet
672*ff61f079SJonathan Corbet  If this field is nonzero, the protected-mode part of the kernel can
673*ff61f079SJonathan Corbet  be loaded at any address that satisfies the kernel_alignment field.
674*ff61f079SJonathan Corbet  After loading, the boot loader must set the code32_start field to
675*ff61f079SJonathan Corbet  point to the loaded code, or to a boot loader hook.
676*ff61f079SJonathan Corbet
677*ff61f079SJonathan Corbet============	=============
678*ff61f079SJonathan CorbetField name:	min_alignment
679*ff61f079SJonathan CorbetType:		read (reloc)
680*ff61f079SJonathan CorbetOffset/size:	0x235/1
681*ff61f079SJonathan CorbetProtocol:	2.10+
682*ff61f079SJonathan Corbet============	=============
683*ff61f079SJonathan Corbet
684*ff61f079SJonathan Corbet  This field, if nonzero, indicates as a power of two the minimum
685*ff61f079SJonathan Corbet  alignment required, as opposed to preferred, by the kernel to boot.
686*ff61f079SJonathan Corbet  If a boot loader makes use of this field, it should update the
687*ff61f079SJonathan Corbet  kernel_alignment field with the alignment unit desired; typically::
688*ff61f079SJonathan Corbet
689*ff61f079SJonathan Corbet	kernel_alignment = 1 << min_alignment
690*ff61f079SJonathan Corbet
691*ff61f079SJonathan Corbet  There may be a considerable performance cost with an excessively
692*ff61f079SJonathan Corbet  misaligned kernel.  Therefore, a loader should typically try each
693*ff61f079SJonathan Corbet  power-of-two alignment from kernel_alignment down to this alignment.
694*ff61f079SJonathan Corbet
695*ff61f079SJonathan Corbet============	==========
696*ff61f079SJonathan CorbetField name:	xloadflags
697*ff61f079SJonathan CorbetType:		read
698*ff61f079SJonathan CorbetOffset/size:	0x236/2
699*ff61f079SJonathan CorbetProtocol:	2.12+
700*ff61f079SJonathan Corbet============	==========
701*ff61f079SJonathan Corbet
702*ff61f079SJonathan Corbet  This field is a bitmask.
703*ff61f079SJonathan Corbet
704*ff61f079SJonathan Corbet  Bit 0 (read):	XLF_KERNEL_64
705*ff61f079SJonathan Corbet
706*ff61f079SJonathan Corbet	- If 1, this kernel has the legacy 64-bit entry point at 0x200.
707*ff61f079SJonathan Corbet
708*ff61f079SJonathan Corbet  Bit 1 (read): XLF_CAN_BE_LOADED_ABOVE_4G
709*ff61f079SJonathan Corbet
710*ff61f079SJonathan Corbet        - If 1, kernel/boot_params/cmdline/ramdisk can be above 4G.
711*ff61f079SJonathan Corbet
712*ff61f079SJonathan Corbet  Bit 2 (read):	XLF_EFI_HANDOVER_32
713*ff61f079SJonathan Corbet
714*ff61f079SJonathan Corbet	- If 1, the kernel supports the 32-bit EFI handoff entry point
715*ff61f079SJonathan Corbet          given at handover_offset.
716*ff61f079SJonathan Corbet
717*ff61f079SJonathan Corbet  Bit 3 (read): XLF_EFI_HANDOVER_64
718*ff61f079SJonathan Corbet
719*ff61f079SJonathan Corbet	- If 1, the kernel supports the 64-bit EFI handoff entry point
720*ff61f079SJonathan Corbet          given at handover_offset + 0x200.
721*ff61f079SJonathan Corbet
722*ff61f079SJonathan Corbet  Bit 4 (read): XLF_EFI_KEXEC
723*ff61f079SJonathan Corbet
724*ff61f079SJonathan Corbet	- If 1, the kernel supports kexec EFI boot with EFI runtime support.
725*ff61f079SJonathan Corbet
726*ff61f079SJonathan Corbet
727*ff61f079SJonathan Corbet============	============
728*ff61f079SJonathan CorbetField name:	cmdline_size
729*ff61f079SJonathan CorbetType:		read
730*ff61f079SJonathan CorbetOffset/size:	0x238/4
731*ff61f079SJonathan CorbetProtocol:	2.06+
732*ff61f079SJonathan Corbet============	============
733*ff61f079SJonathan Corbet
734*ff61f079SJonathan Corbet  The maximum size of the command line without the terminating
735*ff61f079SJonathan Corbet  zero. This means that the command line can contain at most
736*ff61f079SJonathan Corbet  cmdline_size characters. With protocol version 2.05 and earlier, the
737*ff61f079SJonathan Corbet  maximum size was 255.
738*ff61f079SJonathan Corbet
739*ff61f079SJonathan Corbet============	====================================
740*ff61f079SJonathan CorbetField name:	hardware_subarch
741*ff61f079SJonathan CorbetType:		write (optional, defaults to x86/PC)
742*ff61f079SJonathan CorbetOffset/size:	0x23c/4
743*ff61f079SJonathan CorbetProtocol:	2.07+
744*ff61f079SJonathan Corbet============	====================================
745*ff61f079SJonathan Corbet
746*ff61f079SJonathan Corbet  In a paravirtualized environment the hardware low level architectural
747*ff61f079SJonathan Corbet  pieces such as interrupt handling, page table handling, and
748*ff61f079SJonathan Corbet  accessing process control registers needs to be done differently.
749*ff61f079SJonathan Corbet
750*ff61f079SJonathan Corbet  This field allows the bootloader to inform the kernel we are in one
751*ff61f079SJonathan Corbet  one of those environments.
752*ff61f079SJonathan Corbet
753*ff61f079SJonathan Corbet  ==========	==============================
754*ff61f079SJonathan Corbet  0x00000000	The default x86/PC environment
755*ff61f079SJonathan Corbet  0x00000001	lguest
756*ff61f079SJonathan Corbet  0x00000002	Xen
757*ff61f079SJonathan Corbet  0x00000003	Moorestown MID
758*ff61f079SJonathan Corbet  0x00000004	CE4100 TV Platform
759*ff61f079SJonathan Corbet  ==========	==============================
760*ff61f079SJonathan Corbet
761*ff61f079SJonathan Corbet============	=========================
762*ff61f079SJonathan CorbetField name:	hardware_subarch_data
763*ff61f079SJonathan CorbetType:		write (subarch-dependent)
764*ff61f079SJonathan CorbetOffset/size:	0x240/8
765*ff61f079SJonathan CorbetProtocol:	2.07+
766*ff61f079SJonathan Corbet============	=========================
767*ff61f079SJonathan Corbet
768*ff61f079SJonathan Corbet  A pointer to data that is specific to hardware subarch
769*ff61f079SJonathan Corbet  This field is currently unused for the default x86/PC environment,
770*ff61f079SJonathan Corbet  do not modify.
771*ff61f079SJonathan Corbet
772*ff61f079SJonathan Corbet============	==============
773*ff61f079SJonathan CorbetField name:	payload_offset
774*ff61f079SJonathan CorbetType:		read
775*ff61f079SJonathan CorbetOffset/size:	0x248/4
776*ff61f079SJonathan CorbetProtocol:	2.08+
777*ff61f079SJonathan Corbet============	==============
778*ff61f079SJonathan Corbet
779*ff61f079SJonathan Corbet  If non-zero then this field contains the offset from the beginning
780*ff61f079SJonathan Corbet  of the protected-mode code to the payload.
781*ff61f079SJonathan Corbet
782*ff61f079SJonathan Corbet  The payload may be compressed. The format of both the compressed and
783*ff61f079SJonathan Corbet  uncompressed data should be determined using the standard magic
784*ff61f079SJonathan Corbet  numbers.  The currently supported compression formats are gzip
785*ff61f079SJonathan Corbet  (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A), LZMA
786*ff61f079SJonathan Corbet  (magic number 5D 00), XZ (magic number FD 37), LZ4 (magic number
787*ff61f079SJonathan Corbet  02 21) and ZSTD (magic number 28 B5). The uncompressed payload is
788*ff61f079SJonathan Corbet  currently always ELF (magic number 7F 45 4C 46).
789*ff61f079SJonathan Corbet
790*ff61f079SJonathan Corbet============	==============
791*ff61f079SJonathan CorbetField name:	payload_length
792*ff61f079SJonathan CorbetType:		read
793*ff61f079SJonathan CorbetOffset/size:	0x24c/4
794*ff61f079SJonathan CorbetProtocol:	2.08+
795*ff61f079SJonathan Corbet============	==============
796*ff61f079SJonathan Corbet
797*ff61f079SJonathan Corbet  The length of the payload.
798*ff61f079SJonathan Corbet
799*ff61f079SJonathan Corbet============	===============
800*ff61f079SJonathan CorbetField name:	setup_data
801*ff61f079SJonathan CorbetType:		write (special)
802*ff61f079SJonathan CorbetOffset/size:	0x250/8
803*ff61f079SJonathan CorbetProtocol:	2.09+
804*ff61f079SJonathan Corbet============	===============
805*ff61f079SJonathan Corbet
806*ff61f079SJonathan Corbet  The 64-bit physical pointer to NULL terminated single linked list of
807*ff61f079SJonathan Corbet  struct setup_data. This is used to define a more extensible boot
808*ff61f079SJonathan Corbet  parameters passing mechanism. The definition of struct setup_data is
809*ff61f079SJonathan Corbet  as follow::
810*ff61f079SJonathan Corbet
811*ff61f079SJonathan Corbet	struct setup_data {
812*ff61f079SJonathan Corbet		u64 next;
813*ff61f079SJonathan Corbet		u32 type;
814*ff61f079SJonathan Corbet		u32 len;
815*ff61f079SJonathan Corbet		u8  data[0];
816*ff61f079SJonathan Corbet	};
817*ff61f079SJonathan Corbet
818*ff61f079SJonathan Corbet  Where, the next is a 64-bit physical pointer to the next node of
819*ff61f079SJonathan Corbet  linked list, the next field of the last node is 0; the type is used
820*ff61f079SJonathan Corbet  to identify the contents of data; the len is the length of data
821*ff61f079SJonathan Corbet  field; the data holds the real payload.
822*ff61f079SJonathan Corbet
823*ff61f079SJonathan Corbet  This list may be modified at a number of points during the bootup
824*ff61f079SJonathan Corbet  process.  Therefore, when modifying this list one should always make
825*ff61f079SJonathan Corbet  sure to consider the case where the linked list already contains
826*ff61f079SJonathan Corbet  entries.
827*ff61f079SJonathan Corbet
828*ff61f079SJonathan Corbet  The setup_data is a bit awkward to use for extremely large data objects,
829*ff61f079SJonathan Corbet  both because the setup_data header has to be adjacent to the data object
830*ff61f079SJonathan Corbet  and because it has a 32-bit length field. However, it is important that
831*ff61f079SJonathan Corbet  intermediate stages of the boot process have a way to identify which
832*ff61f079SJonathan Corbet  chunks of memory are occupied by kernel data.
833*ff61f079SJonathan Corbet
834*ff61f079SJonathan Corbet  Thus setup_indirect struct and SETUP_INDIRECT type were introduced in
835*ff61f079SJonathan Corbet  protocol 2.15::
836*ff61f079SJonathan Corbet
837*ff61f079SJonathan Corbet    struct setup_indirect {
838*ff61f079SJonathan Corbet      __u32 type;
839*ff61f079SJonathan Corbet      __u32 reserved;  /* Reserved, must be set to zero. */
840*ff61f079SJonathan Corbet      __u64 len;
841*ff61f079SJonathan Corbet      __u64 addr;
842*ff61f079SJonathan Corbet    };
843*ff61f079SJonathan Corbet
844*ff61f079SJonathan Corbet  The type member is a SETUP_INDIRECT | SETUP_* type. However, it cannot be
845*ff61f079SJonathan Corbet  SETUP_INDIRECT itself since making the setup_indirect a tree structure
846*ff61f079SJonathan Corbet  could require a lot of stack space in something that needs to parse it
847*ff61f079SJonathan Corbet  and stack space can be limited in boot contexts.
848*ff61f079SJonathan Corbet
849*ff61f079SJonathan Corbet  Let's give an example how to point to SETUP_E820_EXT data using setup_indirect.
850*ff61f079SJonathan Corbet  In this case setup_data and setup_indirect will look like this::
851*ff61f079SJonathan Corbet
852*ff61f079SJonathan Corbet    struct setup_data {
853*ff61f079SJonathan Corbet      __u64 next = 0 or <addr_of_next_setup_data_struct>;
854*ff61f079SJonathan Corbet      __u32 type = SETUP_INDIRECT;
855*ff61f079SJonathan Corbet      __u32 len = sizeof(setup_indirect);
856*ff61f079SJonathan Corbet      __u8 data[sizeof(setup_indirect)] = struct setup_indirect {
857*ff61f079SJonathan Corbet        __u32 type = SETUP_INDIRECT | SETUP_E820_EXT;
858*ff61f079SJonathan Corbet        __u32 reserved = 0;
859*ff61f079SJonathan Corbet        __u64 len = <len_of_SETUP_E820_EXT_data>;
860*ff61f079SJonathan Corbet        __u64 addr = <addr_of_SETUP_E820_EXT_data>;
861*ff61f079SJonathan Corbet      }
862*ff61f079SJonathan Corbet    }
863*ff61f079SJonathan Corbet
864*ff61f079SJonathan Corbet.. note::
865*ff61f079SJonathan Corbet     SETUP_INDIRECT | SETUP_NONE objects cannot be properly distinguished
866*ff61f079SJonathan Corbet     from SETUP_INDIRECT itself. So, this kind of objects cannot be provided
867*ff61f079SJonathan Corbet     by the bootloaders.
868*ff61f079SJonathan Corbet
869*ff61f079SJonathan Corbet============	============
870*ff61f079SJonathan CorbetField name:	pref_address
871*ff61f079SJonathan CorbetType:		read (reloc)
872*ff61f079SJonathan CorbetOffset/size:	0x258/8
873*ff61f079SJonathan CorbetProtocol:	2.10+
874*ff61f079SJonathan Corbet============	============
875*ff61f079SJonathan Corbet
876*ff61f079SJonathan Corbet  This field, if nonzero, represents a preferred load address for the
877*ff61f079SJonathan Corbet  kernel.  A relocating bootloader should attempt to load at this
878*ff61f079SJonathan Corbet  address if possible.
879*ff61f079SJonathan Corbet
880*ff61f079SJonathan Corbet  A non-relocatable kernel will unconditionally move itself and to run
881*ff61f079SJonathan Corbet  at this address.
882*ff61f079SJonathan Corbet
883*ff61f079SJonathan Corbet============	=======
884*ff61f079SJonathan CorbetField name:	init_size
885*ff61f079SJonathan CorbetType:		read
886*ff61f079SJonathan CorbetOffset/size:	0x260/4
887*ff61f079SJonathan Corbet============	=======
888*ff61f079SJonathan Corbet
889*ff61f079SJonathan Corbet  This field indicates the amount of linear contiguous memory starting
890*ff61f079SJonathan Corbet  at the kernel runtime start address that the kernel needs before it
891*ff61f079SJonathan Corbet  is capable of examining its memory map.  This is not the same thing
892*ff61f079SJonathan Corbet  as the total amount of memory the kernel needs to boot, but it can
893*ff61f079SJonathan Corbet  be used by a relocating boot loader to help select a safe load
894*ff61f079SJonathan Corbet  address for the kernel.
895*ff61f079SJonathan Corbet
896*ff61f079SJonathan Corbet  The kernel runtime start address is determined by the following algorithm::
897*ff61f079SJonathan Corbet
898*ff61f079SJonathan Corbet	if (relocatable_kernel)
899*ff61f079SJonathan Corbet	runtime_start = align_up(load_address, kernel_alignment)
900*ff61f079SJonathan Corbet	else
901*ff61f079SJonathan Corbet	runtime_start = pref_address
902*ff61f079SJonathan Corbet
903*ff61f079SJonathan Corbet============	===============
904*ff61f079SJonathan CorbetField name:	handover_offset
905*ff61f079SJonathan CorbetType:		read
906*ff61f079SJonathan CorbetOffset/size:	0x264/4
907*ff61f079SJonathan Corbet============	===============
908*ff61f079SJonathan Corbet
909*ff61f079SJonathan Corbet  This field is the offset from the beginning of the kernel image to
910*ff61f079SJonathan Corbet  the EFI handover protocol entry point. Boot loaders using the EFI
911*ff61f079SJonathan Corbet  handover protocol to boot the kernel should jump to this offset.
912*ff61f079SJonathan Corbet
913*ff61f079SJonathan Corbet  See EFI HANDOVER PROTOCOL below for more details.
914*ff61f079SJonathan Corbet
915*ff61f079SJonathan Corbet============	==================
916*ff61f079SJonathan CorbetField name:	kernel_info_offset
917*ff61f079SJonathan CorbetType:		read
918*ff61f079SJonathan CorbetOffset/size:	0x268/4
919*ff61f079SJonathan CorbetProtocol:	2.15+
920*ff61f079SJonathan Corbet============	==================
921*ff61f079SJonathan Corbet
922*ff61f079SJonathan Corbet  This field is the offset from the beginning of the kernel image to the
923*ff61f079SJonathan Corbet  kernel_info. The kernel_info structure is embedded in the Linux image
924*ff61f079SJonathan Corbet  in the uncompressed protected mode region.
925*ff61f079SJonathan Corbet
926*ff61f079SJonathan Corbet
927*ff61f079SJonathan CorbetThe kernel_info
928*ff61f079SJonathan Corbet===============
929*ff61f079SJonathan Corbet
930*ff61f079SJonathan CorbetThe relationships between the headers are analogous to the various data
931*ff61f079SJonathan Corbetsections:
932*ff61f079SJonathan Corbet
933*ff61f079SJonathan Corbet  setup_header = .data
934*ff61f079SJonathan Corbet  boot_params/setup_data = .bss
935*ff61f079SJonathan Corbet
936*ff61f079SJonathan CorbetWhat is missing from the above list? That's right:
937*ff61f079SJonathan Corbet
938*ff61f079SJonathan Corbet  kernel_info = .rodata
939*ff61f079SJonathan Corbet
940*ff61f079SJonathan CorbetWe have been (ab)using .data for things that could go into .rodata or .bss for
941*ff61f079SJonathan Corbeta long time, for lack of alternatives and -- especially early on -- inertia.
942*ff61f079SJonathan CorbetAlso, the BIOS stub is responsible for creating boot_params, so it isn't
943*ff61f079SJonathan Corbetavailable to a BIOS-based loader (setup_data is, though).
944*ff61f079SJonathan Corbet
945*ff61f079SJonathan Corbetsetup_header is permanently limited to 144 bytes due to the reach of the
946*ff61f079SJonathan Corbet2-byte jump field, which doubles as a length field for the structure, combined
947*ff61f079SJonathan Corbetwith the size of the "hole" in struct boot_params that a protected-mode loader
948*ff61f079SJonathan Corbetor the BIOS stub has to copy it into. It is currently 119 bytes long, which
949*ff61f079SJonathan Corbetleaves us with 25 very precious bytes. This isn't something that can be fixed
950*ff61f079SJonathan Corbetwithout revising the boot protocol entirely, breaking backwards compatibility.
951*ff61f079SJonathan Corbet
952*ff61f079SJonathan Corbetboot_params proper is limited to 4096 bytes, but can be arbitrarily extended
953*ff61f079SJonathan Corbetby adding setup_data entries. It cannot be used to communicate properties of
954*ff61f079SJonathan Corbetthe kernel image, because it is .bss and has no image-provided content.
955*ff61f079SJonathan Corbet
956*ff61f079SJonathan Corbetkernel_info solves this by providing an extensible place for information about
957*ff61f079SJonathan Corbetthe kernel image. It is readonly, because the kernel cannot rely on a
958*ff61f079SJonathan Corbetbootloader copying its contents anywhere, but that is OK; if it becomes
959*ff61f079SJonathan Corbetnecessary it can still contain data items that an enabled bootloader would be
960*ff61f079SJonathan Corbetexpected to copy into a setup_data chunk.
961*ff61f079SJonathan Corbet
962*ff61f079SJonathan CorbetAll kernel_info data should be part of this structure. Fixed size data have to
963*ff61f079SJonathan Corbetbe put before kernel_info_var_len_data label. Variable size data have to be put
964*ff61f079SJonathan Corbetafter kernel_info_var_len_data label. Each chunk of variable size data has to
965*ff61f079SJonathan Corbetbe prefixed with header/magic and its size, e.g.::
966*ff61f079SJonathan Corbet
967*ff61f079SJonathan Corbet  kernel_info:
968*ff61f079SJonathan Corbet          .ascii  "LToP"          /* Header, Linux top (structure). */
969*ff61f079SJonathan Corbet          .long   kernel_info_var_len_data - kernel_info
970*ff61f079SJonathan Corbet          .long   kernel_info_end - kernel_info
971*ff61f079SJonathan Corbet          .long   0x01234567      /* Some fixed size data for the bootloaders. */
972*ff61f079SJonathan Corbet  kernel_info_var_len_data:
973*ff61f079SJonathan Corbet  example_struct:                 /* Some variable size data for the bootloaders. */
974*ff61f079SJonathan Corbet          .ascii  "0123"          /* Header/Magic. */
975*ff61f079SJonathan Corbet          .long   example_struct_end - example_struct
976*ff61f079SJonathan Corbet          .ascii  "Struct"
977*ff61f079SJonathan Corbet          .long   0x89012345
978*ff61f079SJonathan Corbet  example_struct_end:
979*ff61f079SJonathan Corbet  example_strings:                /* Some variable size data for the bootloaders. */
980*ff61f079SJonathan Corbet          .ascii  "ABCD"          /* Header/Magic. */
981*ff61f079SJonathan Corbet          .long   example_strings_end - example_strings
982*ff61f079SJonathan Corbet          .asciz  "String_0"
983*ff61f079SJonathan Corbet          .asciz  "String_1"
984*ff61f079SJonathan Corbet  example_strings_end:
985*ff61f079SJonathan Corbet  kernel_info_end:
986*ff61f079SJonathan Corbet
987*ff61f079SJonathan CorbetThis way the kernel_info is self-contained blob.
988*ff61f079SJonathan Corbet
989*ff61f079SJonathan Corbet.. note::
990*ff61f079SJonathan Corbet     Each variable size data header/magic can be any 4-character string,
991*ff61f079SJonathan Corbet     without \0 at the end of the string, which does not collide with
992*ff61f079SJonathan Corbet     existing variable length data headers/magics.
993*ff61f079SJonathan Corbet
994*ff61f079SJonathan Corbet
995*ff61f079SJonathan CorbetDetails of the kernel_info Fields
996*ff61f079SJonathan Corbet=================================
997*ff61f079SJonathan Corbet
998*ff61f079SJonathan Corbet============	========
999*ff61f079SJonathan CorbetField name:	header
1000*ff61f079SJonathan CorbetOffset/size:	0x0000/4
1001*ff61f079SJonathan Corbet============	========
1002*ff61f079SJonathan Corbet
1003*ff61f079SJonathan Corbet  Contains the magic number "LToP" (0x506f544c).
1004*ff61f079SJonathan Corbet
1005*ff61f079SJonathan Corbet============	========
1006*ff61f079SJonathan CorbetField name:	size
1007*ff61f079SJonathan CorbetOffset/size:	0x0004/4
1008*ff61f079SJonathan Corbet============	========
1009*ff61f079SJonathan Corbet
1010*ff61f079SJonathan Corbet  This field contains the size of the kernel_info including kernel_info.header.
1011*ff61f079SJonathan Corbet  It does not count kernel_info.kernel_info_var_len_data size. This field should be
1012*ff61f079SJonathan Corbet  used by the bootloaders to detect supported fixed size fields in the kernel_info
1013*ff61f079SJonathan Corbet  and beginning of kernel_info.kernel_info_var_len_data.
1014*ff61f079SJonathan Corbet
1015*ff61f079SJonathan Corbet============	========
1016*ff61f079SJonathan CorbetField name:	size_total
1017*ff61f079SJonathan CorbetOffset/size:	0x0008/4
1018*ff61f079SJonathan Corbet============	========
1019*ff61f079SJonathan Corbet
1020*ff61f079SJonathan Corbet  This field contains the size of the kernel_info including kernel_info.header
1021*ff61f079SJonathan Corbet  and kernel_info.kernel_info_var_len_data.
1022*ff61f079SJonathan Corbet
1023*ff61f079SJonathan Corbet============	==============
1024*ff61f079SJonathan CorbetField name:	setup_type_max
1025*ff61f079SJonathan CorbetOffset/size:	0x000c/4
1026*ff61f079SJonathan Corbet============	==============
1027*ff61f079SJonathan Corbet
1028*ff61f079SJonathan Corbet  This field contains maximal allowed type for setup_data and setup_indirect structs.
1029*ff61f079SJonathan Corbet
1030*ff61f079SJonathan Corbet
1031*ff61f079SJonathan CorbetThe Image Checksum
1032*ff61f079SJonathan Corbet==================
1033*ff61f079SJonathan Corbet
1034*ff61f079SJonathan CorbetFrom boot protocol version 2.08 onwards the CRC-32 is calculated over
1035*ff61f079SJonathan Corbetthe entire file using the characteristic polynomial 0x04C11DB7 and an
1036*ff61f079SJonathan Corbetinitial remainder of 0xffffffff.  The checksum is appended to the
1037*ff61f079SJonathan Corbetfile; therefore the CRC of the file up to the limit specified in the
1038*ff61f079SJonathan Corbetsyssize field of the header is always 0.
1039*ff61f079SJonathan Corbet
1040*ff61f079SJonathan Corbet
1041*ff61f079SJonathan CorbetThe Kernel Command Line
1042*ff61f079SJonathan Corbet=======================
1043*ff61f079SJonathan Corbet
1044*ff61f079SJonathan CorbetThe kernel command line has become an important way for the boot
1045*ff61f079SJonathan Corbetloader to communicate with the kernel.  Some of its options are also
1046*ff61f079SJonathan Corbetrelevant to the boot loader itself, see "special command line options"
1047*ff61f079SJonathan Corbetbelow.
1048*ff61f079SJonathan Corbet
1049*ff61f079SJonathan CorbetThe kernel command line is a null-terminated string. The maximum
1050*ff61f079SJonathan Corbetlength can be retrieved from the field cmdline_size.  Before protocol
1051*ff61f079SJonathan Corbetversion 2.06, the maximum was 255 characters.  A string that is too
1052*ff61f079SJonathan Corbetlong will be automatically truncated by the kernel.
1053*ff61f079SJonathan Corbet
1054*ff61f079SJonathan CorbetIf the boot protocol version is 2.02 or later, the address of the
1055*ff61f079SJonathan Corbetkernel command line is given by the header field cmd_line_ptr (see
1056*ff61f079SJonathan Corbetabove.)  This address can be anywhere between the end of the setup
1057*ff61f079SJonathan Corbetheap and 0xA0000.
1058*ff61f079SJonathan Corbet
1059*ff61f079SJonathan CorbetIf the protocol version is *not* 2.02 or higher, the kernel
1060*ff61f079SJonathan Corbetcommand line is entered using the following protocol:
1061*ff61f079SJonathan Corbet
1062*ff61f079SJonathan Corbet  - At offset 0x0020 (word), "cmd_line_magic", enter the magic
1063*ff61f079SJonathan Corbet    number 0xA33F.
1064*ff61f079SJonathan Corbet
1065*ff61f079SJonathan Corbet  - At offset 0x0022 (word), "cmd_line_offset", enter the offset
1066*ff61f079SJonathan Corbet    of the kernel command line (relative to the start of the
1067*ff61f079SJonathan Corbet    real-mode kernel).
1068*ff61f079SJonathan Corbet
1069*ff61f079SJonathan Corbet  - The kernel command line *must* be within the memory region
1070*ff61f079SJonathan Corbet    covered by setup_move_size, so you may need to adjust this
1071*ff61f079SJonathan Corbet    field.
1072*ff61f079SJonathan Corbet
1073*ff61f079SJonathan Corbet
1074*ff61f079SJonathan CorbetMemory Layout of The Real-Mode Code
1075*ff61f079SJonathan Corbet===================================
1076*ff61f079SJonathan Corbet
1077*ff61f079SJonathan CorbetThe real-mode code requires a stack/heap to be set up, as well as
1078*ff61f079SJonathan Corbetmemory allocated for the kernel command line.  This needs to be done
1079*ff61f079SJonathan Corbetin the real-mode accessible memory in bottom megabyte.
1080*ff61f079SJonathan Corbet
1081*ff61f079SJonathan CorbetIt should be noted that modern machines often have a sizable Extended
1082*ff61f079SJonathan CorbetBIOS Data Area (EBDA).  As a result, it is advisable to use as little
1083*ff61f079SJonathan Corbetof the low megabyte as possible.
1084*ff61f079SJonathan Corbet
1085*ff61f079SJonathan CorbetUnfortunately, under the following circumstances the 0x90000 memory
1086*ff61f079SJonathan Corbetsegment has to be used:
1087*ff61f079SJonathan Corbet
1088*ff61f079SJonathan Corbet	- When loading a zImage kernel ((loadflags & 0x01) == 0).
1089*ff61f079SJonathan Corbet	- When loading a 2.01 or earlier boot protocol kernel.
1090*ff61f079SJonathan Corbet
1091*ff61f079SJonathan Corbet.. note::
1092*ff61f079SJonathan Corbet     For the 2.00 and 2.01 boot protocols, the real-mode code
1093*ff61f079SJonathan Corbet     can be loaded at another address, but it is internally
1094*ff61f079SJonathan Corbet     relocated to 0x90000.  For the "old" protocol, the
1095*ff61f079SJonathan Corbet     real-mode code must be loaded at 0x90000.
1096*ff61f079SJonathan Corbet
1097*ff61f079SJonathan CorbetWhen loading at 0x90000, avoid using memory above 0x9a000.
1098*ff61f079SJonathan Corbet
1099*ff61f079SJonathan CorbetFor boot protocol 2.02 or higher, the command line does not have to be
1100*ff61f079SJonathan Corbetlocated in the same 64K segment as the real-mode setup code; it is
1101*ff61f079SJonathan Corbetthus permitted to give the stack/heap the full 64K segment and locate
1102*ff61f079SJonathan Corbetthe command line above it.
1103*ff61f079SJonathan Corbet
1104*ff61f079SJonathan CorbetThe kernel command line should not be located below the real-mode
1105*ff61f079SJonathan Corbetcode, nor should it be located in high memory.
1106*ff61f079SJonathan Corbet
1107*ff61f079SJonathan Corbet
1108*ff61f079SJonathan CorbetSample Boot Configuartion
1109*ff61f079SJonathan Corbet=========================
1110*ff61f079SJonathan Corbet
1111*ff61f079SJonathan CorbetAs a sample configuration, assume the following layout of the real
1112*ff61f079SJonathan Corbetmode segment.
1113*ff61f079SJonathan Corbet
1114*ff61f079SJonathan Corbet    When loading below 0x90000, use the entire segment:
1115*ff61f079SJonathan Corbet
1116*ff61f079SJonathan Corbet        =============	===================
1117*ff61f079SJonathan Corbet	0x0000-0x7fff	Real mode kernel
1118*ff61f079SJonathan Corbet	0x8000-0xdfff	Stack and heap
1119*ff61f079SJonathan Corbet	0xe000-0xffff	Kernel command line
1120*ff61f079SJonathan Corbet	=============	===================
1121*ff61f079SJonathan Corbet
1122*ff61f079SJonathan Corbet    When loading at 0x90000 OR the protocol version is 2.01 or earlier:
1123*ff61f079SJonathan Corbet
1124*ff61f079SJonathan Corbet	=============	===================
1125*ff61f079SJonathan Corbet	0x0000-0x7fff	Real mode kernel
1126*ff61f079SJonathan Corbet	0x8000-0x97ff	Stack and heap
1127*ff61f079SJonathan Corbet	0x9800-0x9fff	Kernel command line
1128*ff61f079SJonathan Corbet	=============	===================
1129*ff61f079SJonathan Corbet
1130*ff61f079SJonathan CorbetSuch a boot loader should enter the following fields in the header::
1131*ff61f079SJonathan Corbet
1132*ff61f079SJonathan Corbet	unsigned long base_ptr;	/* base address for real-mode segment */
1133*ff61f079SJonathan Corbet
1134*ff61f079SJonathan Corbet	if ( setup_sects == 0 ) {
1135*ff61f079SJonathan Corbet		setup_sects = 4;
1136*ff61f079SJonathan Corbet	}
1137*ff61f079SJonathan Corbet
1138*ff61f079SJonathan Corbet	if ( protocol >= 0x0200 ) {
1139*ff61f079SJonathan Corbet		type_of_loader = <type code>;
1140*ff61f079SJonathan Corbet		if ( loading_initrd ) {
1141*ff61f079SJonathan Corbet			ramdisk_image = <initrd_address>;
1142*ff61f079SJonathan Corbet			ramdisk_size = <initrd_size>;
1143*ff61f079SJonathan Corbet		}
1144*ff61f079SJonathan Corbet
1145*ff61f079SJonathan Corbet		if ( protocol >= 0x0202 && loadflags & 0x01 )
1146*ff61f079SJonathan Corbet			heap_end = 0xe000;
1147*ff61f079SJonathan Corbet		else
1148*ff61f079SJonathan Corbet			heap_end = 0x9800;
1149*ff61f079SJonathan Corbet
1150*ff61f079SJonathan Corbet		if ( protocol >= 0x0201 ) {
1151*ff61f079SJonathan Corbet			heap_end_ptr = heap_end - 0x200;
1152*ff61f079SJonathan Corbet			loadflags |= 0x80; /* CAN_USE_HEAP */
1153*ff61f079SJonathan Corbet		}
1154*ff61f079SJonathan Corbet
1155*ff61f079SJonathan Corbet		if ( protocol >= 0x0202 ) {
1156*ff61f079SJonathan Corbet			cmd_line_ptr = base_ptr + heap_end;
1157*ff61f079SJonathan Corbet			strcpy(cmd_line_ptr, cmdline);
1158*ff61f079SJonathan Corbet		} else {
1159*ff61f079SJonathan Corbet			cmd_line_magic	= 0xA33F;
1160*ff61f079SJonathan Corbet			cmd_line_offset = heap_end;
1161*ff61f079SJonathan Corbet			setup_move_size = heap_end + strlen(cmdline)+1;
1162*ff61f079SJonathan Corbet			strcpy(base_ptr+cmd_line_offset, cmdline);
1163*ff61f079SJonathan Corbet		}
1164*ff61f079SJonathan Corbet	} else {
1165*ff61f079SJonathan Corbet		/* Very old kernel */
1166*ff61f079SJonathan Corbet
1167*ff61f079SJonathan Corbet		heap_end = 0x9800;
1168*ff61f079SJonathan Corbet
1169*ff61f079SJonathan Corbet		cmd_line_magic	= 0xA33F;
1170*ff61f079SJonathan Corbet		cmd_line_offset = heap_end;
1171*ff61f079SJonathan Corbet
1172*ff61f079SJonathan Corbet		/* A very old kernel MUST have its real-mode code
1173*ff61f079SJonathan Corbet		   loaded at 0x90000 */
1174*ff61f079SJonathan Corbet
1175*ff61f079SJonathan Corbet		if ( base_ptr != 0x90000 ) {
1176*ff61f079SJonathan Corbet			/* Copy the real-mode kernel */
1177*ff61f079SJonathan Corbet			memcpy(0x90000, base_ptr, (setup_sects+1)*512);
1178*ff61f079SJonathan Corbet			base_ptr = 0x90000;		 /* Relocated */
1179*ff61f079SJonathan Corbet		}
1180*ff61f079SJonathan Corbet
1181*ff61f079SJonathan Corbet		strcpy(0x90000+cmd_line_offset, cmdline);
1182*ff61f079SJonathan Corbet
1183*ff61f079SJonathan Corbet		/* It is recommended to clear memory up to the 32K mark */
1184*ff61f079SJonathan Corbet		memset(0x90000 + (setup_sects+1)*512, 0,
1185*ff61f079SJonathan Corbet		       (64-(setup_sects+1))*512);
1186*ff61f079SJonathan Corbet	}
1187*ff61f079SJonathan Corbet
1188*ff61f079SJonathan Corbet
1189*ff61f079SJonathan CorbetLoading The Rest of The Kernel
1190*ff61f079SJonathan Corbet==============================
1191*ff61f079SJonathan Corbet
1192*ff61f079SJonathan CorbetThe 32-bit (non-real-mode) kernel starts at offset (setup_sects+1)*512
1193*ff61f079SJonathan Corbetin the kernel file (again, if setup_sects == 0 the real value is 4.)
1194*ff61f079SJonathan CorbetIt should be loaded at address 0x10000 for Image/zImage kernels and
1195*ff61f079SJonathan Corbet0x100000 for bzImage kernels.
1196*ff61f079SJonathan Corbet
1197*ff61f079SJonathan CorbetThe kernel is a bzImage kernel if the protocol >= 2.00 and the 0x01
1198*ff61f079SJonathan Corbetbit (LOAD_HIGH) in the loadflags field is set::
1199*ff61f079SJonathan Corbet
1200*ff61f079SJonathan Corbet	is_bzImage = (protocol >= 0x0200) && (loadflags & 0x01);
1201*ff61f079SJonathan Corbet	load_address = is_bzImage ? 0x100000 : 0x10000;
1202*ff61f079SJonathan Corbet
1203*ff61f079SJonathan CorbetNote that Image/zImage kernels can be up to 512K in size, and thus use
1204*ff61f079SJonathan Corbetthe entire 0x10000-0x90000 range of memory.  This means it is pretty
1205*ff61f079SJonathan Corbetmuch a requirement for these kernels to load the real-mode part at
1206*ff61f079SJonathan Corbet0x90000.  bzImage kernels allow much more flexibility.
1207*ff61f079SJonathan Corbet
1208*ff61f079SJonathan CorbetSpecial Command Line Options
1209*ff61f079SJonathan Corbet============================
1210*ff61f079SJonathan Corbet
1211*ff61f079SJonathan CorbetIf the command line provided by the boot loader is entered by the
1212*ff61f079SJonathan Corbetuser, the user may expect the following command line options to work.
1213*ff61f079SJonathan CorbetThey should normally not be deleted from the kernel command line even
1214*ff61f079SJonathan Corbetthough not all of them are actually meaningful to the kernel.  Boot
1215*ff61f079SJonathan Corbetloader authors who need additional command line options for the boot
1216*ff61f079SJonathan Corbetloader itself should get them registered in
1217*ff61f079SJonathan CorbetDocumentation/admin-guide/kernel-parameters.rst to make sure they will not
1218*ff61f079SJonathan Corbetconflict with actual kernel options now or in the future.
1219*ff61f079SJonathan Corbet
1220*ff61f079SJonathan Corbet  vga=<mode>
1221*ff61f079SJonathan Corbet	<mode> here is either an integer (in C notation, either
1222*ff61f079SJonathan Corbet	decimal, octal, or hexadecimal) or one of the strings
1223*ff61f079SJonathan Corbet	"normal" (meaning 0xFFFF), "ext" (meaning 0xFFFE) or "ask"
1224*ff61f079SJonathan Corbet	(meaning 0xFFFD).  This value should be entered into the
1225*ff61f079SJonathan Corbet	vid_mode field, as it is used by the kernel before the command
1226*ff61f079SJonathan Corbet	line is parsed.
1227*ff61f079SJonathan Corbet
1228*ff61f079SJonathan Corbet  mem=<size>
1229*ff61f079SJonathan Corbet	<size> is an integer in C notation optionally followed by
1230*ff61f079SJonathan Corbet	(case insensitive) K, M, G, T, P or E (meaning << 10, << 20,
1231*ff61f079SJonathan Corbet	<< 30, << 40, << 50 or << 60).  This specifies the end of
1232*ff61f079SJonathan Corbet	memory to the kernel. This affects the possible placement of
1233*ff61f079SJonathan Corbet	an initrd, since an initrd should be placed near end of
1234*ff61f079SJonathan Corbet	memory.  Note that this is an option to *both* the kernel and
1235*ff61f079SJonathan Corbet	the bootloader!
1236*ff61f079SJonathan Corbet
1237*ff61f079SJonathan Corbet  initrd=<file>
1238*ff61f079SJonathan Corbet	An initrd should be loaded.  The meaning of <file> is
1239*ff61f079SJonathan Corbet	obviously bootloader-dependent, and some boot loaders
1240*ff61f079SJonathan Corbet	(e.g. LILO) do not have such a command.
1241*ff61f079SJonathan Corbet
1242*ff61f079SJonathan CorbetIn addition, some boot loaders add the following options to the
1243*ff61f079SJonathan Corbetuser-specified command line:
1244*ff61f079SJonathan Corbet
1245*ff61f079SJonathan Corbet  BOOT_IMAGE=<file>
1246*ff61f079SJonathan Corbet	The boot image which was loaded.  Again, the meaning of <file>
1247*ff61f079SJonathan Corbet	is obviously bootloader-dependent.
1248*ff61f079SJonathan Corbet
1249*ff61f079SJonathan Corbet  auto
1250*ff61f079SJonathan Corbet	The kernel was booted without explicit user intervention.
1251*ff61f079SJonathan Corbet
1252*ff61f079SJonathan CorbetIf these options are added by the boot loader, it is highly
1253*ff61f079SJonathan Corbetrecommended that they are located *first*, before the user-specified
1254*ff61f079SJonathan Corbetor configuration-specified command line.  Otherwise, "init=/bin/sh"
1255*ff61f079SJonathan Corbetgets confused by the "auto" option.
1256*ff61f079SJonathan Corbet
1257*ff61f079SJonathan Corbet
1258*ff61f079SJonathan CorbetRunning the Kernel
1259*ff61f079SJonathan Corbet==================
1260*ff61f079SJonathan Corbet
1261*ff61f079SJonathan CorbetThe kernel is started by jumping to the kernel entry point, which is
1262*ff61f079SJonathan Corbetlocated at *segment* offset 0x20 from the start of the real mode
1263*ff61f079SJonathan Corbetkernel.  This means that if you loaded your real-mode kernel code at
1264*ff61f079SJonathan Corbet0x90000, the kernel entry point is 9020:0000.
1265*ff61f079SJonathan Corbet
1266*ff61f079SJonathan CorbetAt entry, ds = es = ss should point to the start of the real-mode
1267*ff61f079SJonathan Corbetkernel code (0x9000 if the code is loaded at 0x90000), sp should be
1268*ff61f079SJonathan Corbetset up properly, normally pointing to the top of the heap, and
1269*ff61f079SJonathan Corbetinterrupts should be disabled.  Furthermore, to guard against bugs in
1270*ff61f079SJonathan Corbetthe kernel, it is recommended that the boot loader sets fs = gs = ds =
1271*ff61f079SJonathan Corbetes = ss.
1272*ff61f079SJonathan Corbet
1273*ff61f079SJonathan CorbetIn our example from above, we would do::
1274*ff61f079SJonathan Corbet
1275*ff61f079SJonathan Corbet	/* Note: in the case of the "old" kernel protocol, base_ptr must
1276*ff61f079SJonathan Corbet	   be == 0x90000 at this point; see the previous sample code */
1277*ff61f079SJonathan Corbet
1278*ff61f079SJonathan Corbet	seg = base_ptr >> 4;
1279*ff61f079SJonathan Corbet
1280*ff61f079SJonathan Corbet	cli();	/* Enter with interrupts disabled! */
1281*ff61f079SJonathan Corbet
1282*ff61f079SJonathan Corbet	/* Set up the real-mode kernel stack */
1283*ff61f079SJonathan Corbet	_SS = seg;
1284*ff61f079SJonathan Corbet	_SP = heap_end;
1285*ff61f079SJonathan Corbet
1286*ff61f079SJonathan Corbet	_DS = _ES = _FS = _GS = seg;
1287*ff61f079SJonathan Corbet	jmp_far(seg+0x20, 0);	/* Run the kernel */
1288*ff61f079SJonathan Corbet
1289*ff61f079SJonathan CorbetIf your boot sector accesses a floppy drive, it is recommended to
1290*ff61f079SJonathan Corbetswitch off the floppy motor before running the kernel, since the
1291*ff61f079SJonathan Corbetkernel boot leaves interrupts off and thus the motor will not be
1292*ff61f079SJonathan Corbetswitched off, especially if the loaded kernel has the floppy driver as
1293*ff61f079SJonathan Corbeta demand-loaded module!
1294*ff61f079SJonathan Corbet
1295*ff61f079SJonathan Corbet
1296*ff61f079SJonathan CorbetAdvanced Boot Loader Hooks
1297*ff61f079SJonathan Corbet==========================
1298*ff61f079SJonathan Corbet
1299*ff61f079SJonathan CorbetIf the boot loader runs in a particularly hostile environment (such as
1300*ff61f079SJonathan CorbetLOADLIN, which runs under DOS) it may be impossible to follow the
1301*ff61f079SJonathan Corbetstandard memory location requirements.  Such a boot loader may use the
1302*ff61f079SJonathan Corbetfollowing hooks that, if set, are invoked by the kernel at the
1303*ff61f079SJonathan Corbetappropriate time.  The use of these hooks should probably be
1304*ff61f079SJonathan Corbetconsidered an absolutely last resort!
1305*ff61f079SJonathan Corbet
1306*ff61f079SJonathan CorbetIMPORTANT: All the hooks are required to preserve %esp, %ebp, %esi and
1307*ff61f079SJonathan Corbet%edi across invocation.
1308*ff61f079SJonathan Corbet
1309*ff61f079SJonathan Corbet  realmode_swtch:
1310*ff61f079SJonathan Corbet	A 16-bit real mode far subroutine invoked immediately before
1311*ff61f079SJonathan Corbet	entering protected mode.  The default routine disables NMI, so
1312*ff61f079SJonathan Corbet	your routine should probably do so, too.
1313*ff61f079SJonathan Corbet
1314*ff61f079SJonathan Corbet  code32_start:
1315*ff61f079SJonathan Corbet	A 32-bit flat-mode routine *jumped* to immediately after the
1316*ff61f079SJonathan Corbet	transition to protected mode, but before the kernel is
1317*ff61f079SJonathan Corbet	uncompressed.  No segments, except CS, are guaranteed to be
1318*ff61f079SJonathan Corbet	set up (current kernels do, but older ones do not); you should
1319*ff61f079SJonathan Corbet	set them up to BOOT_DS (0x18) yourself.
1320*ff61f079SJonathan Corbet
1321*ff61f079SJonathan Corbet	After completing your hook, you should jump to the address
1322*ff61f079SJonathan Corbet	that was in this field before your boot loader overwrote it
1323*ff61f079SJonathan Corbet	(relocated, if appropriate.)
1324*ff61f079SJonathan Corbet
1325*ff61f079SJonathan Corbet
1326*ff61f079SJonathan Corbet32-bit Boot Protocol
1327*ff61f079SJonathan Corbet====================
1328*ff61f079SJonathan Corbet
1329*ff61f079SJonathan CorbetFor machine with some new BIOS other than legacy BIOS, such as EFI,
1330*ff61f079SJonathan CorbetLinuxBIOS, etc, and kexec, the 16-bit real mode setup code in kernel
1331*ff61f079SJonathan Corbetbased on legacy BIOS can not be used, so a 32-bit boot protocol needs
1332*ff61f079SJonathan Corbetto be defined.
1333*ff61f079SJonathan Corbet
1334*ff61f079SJonathan CorbetIn 32-bit boot protocol, the first step in loading a Linux kernel
1335*ff61f079SJonathan Corbetshould be to setup the boot parameters (struct boot_params,
1336*ff61f079SJonathan Corbettraditionally known as "zero page"). The memory for struct boot_params
1337*ff61f079SJonathan Corbetshould be allocated and initialized to all zero. Then the setup header
1338*ff61f079SJonathan Corbetfrom offset 0x01f1 of kernel image on should be loaded into struct
1339*ff61f079SJonathan Corbetboot_params and examined. The end of setup header can be calculated as
1340*ff61f079SJonathan Corbetfollow::
1341*ff61f079SJonathan Corbet
1342*ff61f079SJonathan Corbet	0x0202 + byte value at offset 0x0201
1343*ff61f079SJonathan Corbet
1344*ff61f079SJonathan CorbetIn addition to read/modify/write the setup header of the struct
1345*ff61f079SJonathan Corbetboot_params as that of 16-bit boot protocol, the boot loader should
1346*ff61f079SJonathan Corbetalso fill the additional fields of the struct boot_params as
1347*ff61f079SJonathan Corbetdescribed in chapter Documentation/arch/x86/zero-page.rst.
1348*ff61f079SJonathan Corbet
1349*ff61f079SJonathan CorbetAfter setting up the struct boot_params, the boot loader can load the
1350*ff61f079SJonathan Corbet32/64-bit kernel in the same way as that of 16-bit boot protocol.
1351*ff61f079SJonathan Corbet
1352*ff61f079SJonathan CorbetIn 32-bit boot protocol, the kernel is started by jumping to the
1353*ff61f079SJonathan Corbet32-bit kernel entry point, which is the start address of loaded
1354*ff61f079SJonathan Corbet32/64-bit kernel.
1355*ff61f079SJonathan Corbet
1356*ff61f079SJonathan CorbetAt entry, the CPU must be in 32-bit protected mode with paging
1357*ff61f079SJonathan Corbetdisabled; a GDT must be loaded with the descriptors for selectors
1358*ff61f079SJonathan Corbet__BOOT_CS(0x10) and __BOOT_DS(0x18); both descriptors must be 4G flat
1359*ff61f079SJonathan Corbetsegment; __BOOT_CS must have execute/read permission, and __BOOT_DS
1360*ff61f079SJonathan Corbetmust have read/write permission; CS must be __BOOT_CS and DS, ES, SS
1361*ff61f079SJonathan Corbetmust be __BOOT_DS; interrupt must be disabled; %esi must hold the base
1362*ff61f079SJonathan Corbetaddress of the struct boot_params; %ebp, %edi and %ebx must be zero.
1363*ff61f079SJonathan Corbet
1364*ff61f079SJonathan Corbet64-bit Boot Protocol
1365*ff61f079SJonathan Corbet====================
1366*ff61f079SJonathan Corbet
1367*ff61f079SJonathan CorbetFor machine with 64bit cpus and 64bit kernel, we could use 64bit bootloader
1368*ff61f079SJonathan Corbetand we need a 64-bit boot protocol.
1369*ff61f079SJonathan Corbet
1370*ff61f079SJonathan CorbetIn 64-bit boot protocol, the first step in loading a Linux kernel
1371*ff61f079SJonathan Corbetshould be to setup the boot parameters (struct boot_params,
1372*ff61f079SJonathan Corbettraditionally known as "zero page"). The memory for struct boot_params
1373*ff61f079SJonathan Corbetcould be allocated anywhere (even above 4G) and initialized to all zero.
1374*ff61f079SJonathan CorbetThen, the setup header at offset 0x01f1 of kernel image on should be
1375*ff61f079SJonathan Corbetloaded into struct boot_params and examined. The end of setup header
1376*ff61f079SJonathan Corbetcan be calculated as follows::
1377*ff61f079SJonathan Corbet
1378*ff61f079SJonathan Corbet	0x0202 + byte value at offset 0x0201
1379*ff61f079SJonathan Corbet
1380*ff61f079SJonathan CorbetIn addition to read/modify/write the setup header of the struct
1381*ff61f079SJonathan Corbetboot_params as that of 16-bit boot protocol, the boot loader should
1382*ff61f079SJonathan Corbetalso fill the additional fields of the struct boot_params as described
1383*ff61f079SJonathan Corbetin chapter Documentation/arch/x86/zero-page.rst.
1384*ff61f079SJonathan Corbet
1385*ff61f079SJonathan CorbetAfter setting up the struct boot_params, the boot loader can load
1386*ff61f079SJonathan Corbet64-bit kernel in the same way as that of 16-bit boot protocol, but
1387*ff61f079SJonathan Corbetkernel could be loaded above 4G.
1388*ff61f079SJonathan Corbet
1389*ff61f079SJonathan CorbetIn 64-bit boot protocol, the kernel is started by jumping to the
1390*ff61f079SJonathan Corbet64-bit kernel entry point, which is the start address of loaded
1391*ff61f079SJonathan Corbet64-bit kernel plus 0x200.
1392*ff61f079SJonathan Corbet
1393*ff61f079SJonathan CorbetAt entry, the CPU must be in 64-bit mode with paging enabled.
1394*ff61f079SJonathan CorbetThe range with setup_header.init_size from start address of loaded
1395*ff61f079SJonathan Corbetkernel and zero page and command line buffer get ident mapping;
1396*ff61f079SJonathan Corbeta GDT must be loaded with the descriptors for selectors
1397*ff61f079SJonathan Corbet__BOOT_CS(0x10) and __BOOT_DS(0x18); both descriptors must be 4G flat
1398*ff61f079SJonathan Corbetsegment; __BOOT_CS must have execute/read permission, and __BOOT_DS
1399*ff61f079SJonathan Corbetmust have read/write permission; CS must be __BOOT_CS and DS, ES, SS
1400*ff61f079SJonathan Corbetmust be __BOOT_DS; interrupt must be disabled; %rsi must hold the base
1401*ff61f079SJonathan Corbetaddress of the struct boot_params.
1402*ff61f079SJonathan Corbet
1403*ff61f079SJonathan CorbetEFI Handover Protocol (deprecated)
1404*ff61f079SJonathan Corbet==================================
1405*ff61f079SJonathan Corbet
1406*ff61f079SJonathan CorbetThis protocol allows boot loaders to defer initialisation to the EFI
1407*ff61f079SJonathan Corbetboot stub. The boot loader is required to load the kernel/initrd(s)
1408*ff61f079SJonathan Corbetfrom the boot media and jump to the EFI handover protocol entry point
1409*ff61f079SJonathan Corbetwhich is hdr->handover_offset bytes from the beginning of
1410*ff61f079SJonathan Corbetstartup_{32,64}.
1411*ff61f079SJonathan Corbet
1412*ff61f079SJonathan CorbetThe boot loader MUST respect the kernel's PE/COFF metadata when it comes
1413*ff61f079SJonathan Corbetto section alignment, the memory footprint of the executable image beyond
1414*ff61f079SJonathan Corbetthe size of the file itself, and any other aspect of the PE/COFF header
1415*ff61f079SJonathan Corbetthat may affect correct operation of the image as a PE/COFF binary in the
1416*ff61f079SJonathan Corbetexecution context provided by the EFI firmware.
1417*ff61f079SJonathan Corbet
1418*ff61f079SJonathan CorbetThe function prototype for the handover entry point looks like this::
1419*ff61f079SJonathan Corbet
1420*ff61f079SJonathan Corbet    efi_main(void *handle, efi_system_table_t *table, struct boot_params *bp)
1421*ff61f079SJonathan Corbet
1422*ff61f079SJonathan Corbet'handle' is the EFI image handle passed to the boot loader by the EFI
1423*ff61f079SJonathan Corbetfirmware, 'table' is the EFI system table - these are the first two
1424*ff61f079SJonathan Corbetarguments of the "handoff state" as described in section 2.3 of the
1425*ff61f079SJonathan CorbetUEFI specification. 'bp' is the boot loader-allocated boot params.
1426*ff61f079SJonathan Corbet
1427*ff61f079SJonathan CorbetThe boot loader *must* fill out the following fields in bp::
1428*ff61f079SJonathan Corbet
1429*ff61f079SJonathan Corbet  - hdr.cmd_line_ptr
1430*ff61f079SJonathan Corbet  - hdr.ramdisk_image (if applicable)
1431*ff61f079SJonathan Corbet  - hdr.ramdisk_size  (if applicable)
1432*ff61f079SJonathan Corbet
1433*ff61f079SJonathan CorbetAll other fields should be zero.
1434*ff61f079SJonathan Corbet
1435*ff61f079SJonathan CorbetNOTE: The EFI Handover Protocol is deprecated in favour of the ordinary PE/COFF
1436*ff61f079SJonathan Corbet      entry point, combined with the LINUX_EFI_INITRD_MEDIA_GUID based initrd
1437*ff61f079SJonathan Corbet      loading protocol (refer to [0] for an example of the bootloader side of
1438*ff61f079SJonathan Corbet      this), which removes the need for any knowledge on the part of the EFI
1439*ff61f079SJonathan Corbet      bootloader regarding the internal representation of boot_params or any
1440*ff61f079SJonathan Corbet      requirements/limitations regarding the placement of the command line
1441*ff61f079SJonathan Corbet      and ramdisk in memory, or the placement of the kernel image itself.
1442*ff61f079SJonathan Corbet
1443*ff61f079SJonathan Corbet[0] https://github.com/u-boot/u-boot/commit/ec80b4735a593961fe701cc3a5d717d4739b0fd0
1444