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