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