~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/x86/boot/header.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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   MZ_MAGIC
 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   PE_MAGIC
 55 
 56 coff_header:
 57 #ifdef CONFIG_X86_32
 58         .set    image_file_add_flags, IMAGE_FILE_32BIT_MACHINE
 59         .set    pe_opt_magic, PE_OPT_MAGIC_PE32
 60         .word   IMAGE_FILE_MACHINE_I386
 61 #else
 62         .set    image_file_add_flags, 0
 63         .set    pe_opt_magic, PE_OPT_MAGIC_PE32PLUS
 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_DLL_CHARACTERISTICS_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"
183         .byte   0
184         .byte   0
185         .byte   0
186         .long   ZO__data
187         .long   setup_size
188         .long   ZO__data                        # Size of initialized data
189                                                 # on disk
190         .long   setup_size
191         .long   0                               # PointerToRelocations
192         .long   0                               # PointerToLineNumbers
193         .word   0                               # NumberOfRelocations
194         .word   0                               # NumberOfLineNumbers
195         .long   IMAGE_SCN_CNT_CODE              | \
196                 IMAGE_SCN_MEM_READ              | \
197                 IMAGE_SCN_MEM_EXECUTE           # Characteristics
198 
199         .ascii  ".data\0\0\0"
200         .long   ZO__end - ZO__data              # VirtualSize
201         .long   setup_size + ZO__data           # VirtualAddress
202         .long   ZO__edata - ZO__data            # SizeOfRawData
203         .long   setup_size + ZO__data           # PointerToRawData
204 
205         .long   0, 0, 0
206         .long   IMAGE_SCN_CNT_INITIALIZED_DATA  | \
207                 IMAGE_SCN_MEM_READ              | \
208                 IMAGE_SCN_MEM_WRITE             # Characteristics
209 
210         .set    section_count, (. - section_table) / 40
211 #endif /* CONFIG_EFI_STUB */
212 
213         # Kernel attributes; used by setup.  This is part 1 of the
214         # header, from the old boot sector.
215 
216         .section ".header", "a"
217         .globl  sentinel
218 sentinel:       .byte 0xff, 0xff        /* Used to detect broken loaders */
219 
220         .globl  hdr
221 hdr:
222                 .byte setup_sects - 1
223 root_flags:     .word ROOT_RDONLY
224 syssize:        .long ZO__edata / 16
225 ram_size:       .word 0                 /* Obsolete */
226 vid_mode:       .word SVGA_MODE
227 root_dev:       .word 0                 /* Default to major/minor 0/0 */
228 boot_flag:      .word 0xAA55
229 
230         # offset 512, entry point
231 
232         .globl  _start
233 _start:
234                 # Explicitly enter this as bytes, or the assembler
235                 # tries to generate a 3-byte jump here, which causes
236                 # everything else to push off to the wrong offset.
237                 .byte   0xeb            # short (2-byte) jump
238                 .byte   start_of_setup-1f
239 1:
240 
241         # Part 2 of the header, from the old setup.S
242 
243                 .ascii  "HdrS"          # header signature
244                 .word   0x020f          # header version number (>= 0x0105)
245                                         # or else old loadlin-1.5 will fail)
246                 .globl realmode_swtch
247 realmode_swtch: .word   0, 0            # default_switch, SETUPSEG
248 start_sys_seg:  .word   SYSSEG          # obsolete and meaningless, but just
249                                         # in case something decided to "use" it
250                 .word   kernel_version-512 # pointing to kernel version string
251                                         # above section of header is compatible
252                                         # with loadlin-1.5 (header v1.5). Don't
253                                         # change it.
254 
255 type_of_loader: .byte   0               # 0 means ancient bootloader, newer
256                                         # bootloaders know to change this.
257                                         # See Documentation/arch/x86/boot.rst for
258                                         # assigned ids
259 
260 # flags, unused bits must be zero (RFU) bit within loadflags
261 loadflags:
262                 .byte   LOADED_HIGH     # The kernel is to be loaded high
263 
264 setup_move_size: .word  0x8000          # size to move, when setup is not
265                                         # loaded at 0x90000. We will move setup
266                                         # to 0x90000 then just before jumping
267                                         # into the kernel. However, only the
268                                         # loader knows how much data behind
269                                         # us also needs to be loaded.
270 
271 code32_start:                           # here loaders can put a different
272                                         # start address for 32-bit code.
273                 .long   0x100000        # 0x100000 = default for big kernel
274 
275 ramdisk_image:  .long   0               # address of loaded ramdisk image
276                                         # Here the loader puts the 32-bit
277                                         # address where it loaded the image.
278                                         # This only will be read by the kernel.
279 
280 ramdisk_size:   .long   0               # its size in bytes
281 
282 bootsect_kludge:
283                 .long   0               # obsolete
284 
285 heap_end_ptr:   .word   _end+STACK_SIZE-512
286                                         # (Header version 0x0201 or later)
287                                         # space from here (exclusive) down to
288                                         # end of setup code can be used by setup
289                                         # for local heap purposes.
290 
291 ext_loader_ver:
292                 .byte   0               # Extended boot loader version
293 ext_loader_type:
294                 .byte   0               # Extended boot loader type
295 
296 cmd_line_ptr:   .long   0               # (Header version 0x0202 or later)
297                                         # If nonzero, a 32-bit pointer
298                                         # to the kernel command line.
299                                         # The command line should be
300                                         # located between the start of
301                                         # setup and the end of low
302                                         # memory (0xa0000), or it may
303                                         # get overwritten before it
304                                         # gets read.  If this field is
305                                         # used, there is no longer
306                                         # anything magical about the
307                                         # 0x90000 segment; the setup
308                                         # can be located anywhere in
309                                         # low memory 0x10000 or higher.
310 
311 initrd_addr_max: .long 0x7fffffff
312                                         # (Header version 0x0203 or later)
313                                         # The highest safe address for
314                                         # the contents of an initrd
315                                         # The current kernel allows up to 4 GB,
316                                         # but leave it at 2 GB to avoid
317                                         # possible bootloader bugs.
318 
319 kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN  #physical addr alignment
320                                                 #required for protected mode
321                                                 #kernel
322 #ifdef CONFIG_RELOCATABLE
323 relocatable_kernel:    .byte 1
324 #else
325 relocatable_kernel:    .byte 0
326 #endif
327 min_alignment:          .byte MIN_KERNEL_ALIGN_LG2      # minimum alignment
328 
329 xloadflags:
330 #ifdef CONFIG_X86_64
331 # define XLF0 XLF_KERNEL_64                     /* 64-bit kernel */
332 #else
333 # define XLF0 0
334 #endif
335 
336 #if defined(CONFIG_RELOCATABLE) && defined(CONFIG_X86_64)
337    /* kernel/boot_param/ramdisk could be loaded above 4g */
338 # define XLF1 XLF_CAN_BE_LOADED_ABOVE_4G
339 #else
340 # define XLF1 0
341 #endif
342 
343 #ifdef CONFIG_EFI_HANDOVER_PROTOCOL
344 # ifdef CONFIG_EFI_MIXED
345 #  define XLF23 (XLF_EFI_HANDOVER_32|XLF_EFI_HANDOVER_64)
346 # else
347 #  ifdef CONFIG_X86_64
348 #   define XLF23 XLF_EFI_HANDOVER_64            /* 64-bit EFI handover ok */
349 #  else
350 #   define XLF23 XLF_EFI_HANDOVER_32            /* 32-bit EFI handover ok */
351 #  endif
352 # endif
353 #else
354 # define XLF23 0
355 #endif
356 
357 #if defined(CONFIG_X86_64) && defined(CONFIG_EFI) && defined(CONFIG_KEXEC_CORE)
358 # define XLF4 XLF_EFI_KEXEC
359 #else
360 # define XLF4 0
361 #endif
362 
363 #ifdef CONFIG_X86_64
364 #ifdef CONFIG_X86_5LEVEL
365 #define XLF56 (XLF_5LEVEL|XLF_5LEVEL_ENABLED)
366 #else
367 #define XLF56 XLF_5LEVEL
368 #endif
369 #else
370 #define XLF56 0
371 #endif
372 
373                         .word XLF0 | XLF1 | XLF23 | XLF4 | XLF56
374 
375 cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
376                                                 #added with boot protocol
377                                                 #version 2.06
378 
379 hardware_subarch:       .long 0                 # subarchitecture, added with 2.07
380                                                 # default to 0 for normal x86 PC
381 
382 hardware_subarch_data:  .quad 0
383 
384 payload_offset:         .long ZO_input_data
385 payload_length:         .long ZO_z_input_len
386 
387 setup_data:             .quad 0                 # 64-bit physical pointer to
388                                                 # single linked list of
389                                                 # struct setup_data
390 
391 pref_address:           .quad LOAD_PHYSICAL_ADDR        # preferred load addr
392 
393 #
394 # Getting to provably safe in-place decompression is hard. Worst case
395 # behaviours need to be analyzed. Here let's take the decompression of
396 # a gzip-compressed kernel as example, to illustrate it:
397 #
398 # The file layout of gzip compressed kernel is:
399 #
400 #    magic[2]
401 #    method[1]
402 #    flags[1]
403 #    timestamp[4]
404 #    extraflags[1]
405 #    os[1]
406 #    compressed data blocks[N]
407 #    crc[4] orig_len[4]
408 #
409 # ... resulting in +18 bytes overhead of uncompressed data.
410 #
411 # (For more information, please refer to RFC 1951 and RFC 1952.)
412 #
413 # Files divided into blocks
414 # 1 bit (last block flag)
415 # 2 bits (block type)
416 #
417 # 1 block occurs every 32K -1 bytes or when there 50% compression
418 # has been achieved. The smallest block type encoding is always used.
419 #
420 # stored:
421 #    32 bits length in bytes.
422 #
423 # fixed:
424 #    magic fixed tree.
425 #    symbols.
426 #
427 # dynamic:
428 #    dynamic tree encoding.
429 #    symbols.
430 #
431 #
432 # The buffer for decompression in place is the length of the uncompressed
433 # data, plus a small amount extra to keep the algorithm safe. The
434 # compressed data is placed at the end of the buffer.  The output pointer
435 # is placed at the start of the buffer and the input pointer is placed
436 # where the compressed data starts. Problems will occur when the output
437 # pointer overruns the input pointer.
438 #
439 # The output pointer can only overrun the input pointer if the input
440 # pointer is moving faster than the output pointer.  A condition only
441 # triggered by data whose compressed form is larger than the uncompressed
442 # form.
443 #
444 # The worst case at the block level is a growth of the compressed data
445 # of 5 bytes per 32767 bytes.
446 #
447 # The worst case internal to a compressed block is very hard to figure.
448 # The worst case can at least be bounded by having one bit that represents
449 # 32764 bytes and then all of the rest of the bytes representing the very
450 # very last byte.
451 #
452 # All of which is enough to compute an amount of extra data that is required
453 # to be safe.  To avoid problems at the block level allocating 5 extra bytes
454 # per 32767 bytes of data is sufficient.  To avoid problems internal to a
455 # block adding an extra 32767 bytes (the worst case uncompressed block size)
456 # is sufficient, to ensure that in the worst case the decompressed data for
457 # block will stop the byte before the compressed data for a block begins.
458 # To avoid problems with the compressed data's meta information an extra 18
459 # bytes are needed.  Leading to the formula:
460 #
461 # extra_bytes = (uncompressed_size >> 12) + 32768 + 18
462 #
463 # Adding 8 bytes per 32K is a bit excessive but much easier to calculate.
464 # Adding 32768 instead of 32767 just makes for round numbers.
465 #
466 # Above analysis is for decompressing gzip compressed kernel only. Up to
467 # now 6 different decompressor are supported all together. And among them
468 # xz stores data in chunks and has maximum chunk of 64K. Hence safety
469 # margin should be updated to cover all decompressors so that we don't
470 # need to deal with each of them separately. Please check
471 # the description in lib/decompressor_xxx.c for specific information.
472 #
473 # extra_bytes = (uncompressed_size >> 12) + 65536 + 128
474 #
475 # LZ4 is even worse: data that cannot be further compressed grows by 0.4%,
476 # or one byte per 256 bytes. OTOH, we can safely get rid of the +128 as
477 # the size-dependent part now grows so fast.
478 #
479 # extra_bytes = (uncompressed_size >> 8) + 65536
480 #
481 # ZSTD compressed data grows by at most 3 bytes per 128K, and only has a 22
482 # byte fixed overhead but has a maximum block size of 128K, so it needs a
483 # larger margin.
484 #
485 # extra_bytes = (uncompressed_size >> 8) + 131072
486 
487 #define ZO_z_extra_bytes        ((ZO_z_output_len >> 8) + 131072)
488 #if ZO_z_output_len > ZO_z_input_len
489 # define ZO_z_extract_offset    (ZO_z_output_len + ZO_z_extra_bytes - \
490                                  ZO_z_input_len)
491 #else
492 # define ZO_z_extract_offset    ZO_z_extra_bytes
493 #endif
494 
495 /*
496  * The extract_offset has to be bigger than ZO head section. Otherwise when
497  * the head code is running to move ZO to the end of the buffer, it will
498  * overwrite the head code itself.
499  */
500 #if (ZO__ehead - ZO_startup_32) > ZO_z_extract_offset
501 # define ZO_z_min_extract_offset ((ZO__ehead - ZO_startup_32 + 4095) & ~4095)
502 #else
503 # define ZO_z_min_extract_offset ((ZO_z_extract_offset + 4095) & ~4095)
504 #endif
505 
506 #define ZO_INIT_SIZE    (ZO__end - ZO_startup_32 + ZO_z_min_extract_offset)
507 
508 #define VO_INIT_SIZE    (VO__end - VO__text)
509 #if ZO_INIT_SIZE > VO_INIT_SIZE
510 # define INIT_SIZE ZO_INIT_SIZE
511 #else
512 # define INIT_SIZE VO_INIT_SIZE
513 #endif
514 
515         .macro          __handover_offset
516 #ifndef CONFIG_EFI_HANDOVER_PROTOCOL
517         .long           0
518 #elif !defined(CONFIG_X86_64)
519         .long           ZO_efi32_stub_entry
520 #else
521         /* Yes, this is really how we defined it :( */
522         .long           ZO_efi64_stub_entry - 0x200
523 #ifdef CONFIG_EFI_MIXED
524         .if             ZO_efi32_stub_entry != ZO_efi64_stub_entry - 0x200
525         .error          "32-bit and 64-bit EFI entry points do not match"
526         .endif
527 #endif
528 #endif
529         .endm
530 
531 init_size:              .long INIT_SIZE         # kernel initialization size
532 handover_offset:        __handover_offset
533 kernel_info_offset:     .long ZO_kernel_info
534 
535 # End of setup header #####################################################
536 
537         .section ".entrytext", "ax"
538 start_of_setup:
539 # Force %es = %ds
540         movw    %ds, %ax
541         movw    %ax, %es
542         cld
543 
544 # Apparently some ancient versions of LILO invoked the kernel with %ss != %ds,
545 # which happened to work by accident for the old code.  Recalculate the stack
546 # pointer if %ss is invalid.  Otherwise leave it alone, LOADLIN sets up the
547 # stack behind its own code, so we can't blindly put it directly past the heap.
548 
549         movw    %ss, %dx
550         cmpw    %ax, %dx        # %ds == %ss?
551         movw    %sp, %dx
552         je      2f              # -> assume %sp is reasonably set
553 
554         # Invalid %ss, make up a new stack
555         movw    $_end, %dx
556         testb   $CAN_USE_HEAP, loadflags
557         jz      1f
558         movw    heap_end_ptr, %dx
559 1:      addw    $STACK_SIZE, %dx
560         jnc     2f
561         xorw    %dx, %dx        # Prevent wraparound
562 
563 2:      # Now %dx should point to the end of our stack space
564         andw    $~3, %dx        # dword align (might as well...)
565         jnz     3f
566         movw    $0xfffc, %dx    # Make sure we're not zero
567 3:      movw    %ax, %ss
568         movzwl  %dx, %esp       # Clear upper half of %esp
569         sti                     # Now we should have a working stack
570 
571 # We will have entered with %cs = %ds+0x20, normalize %cs so
572 # it is on par with the other segments.
573         pushw   %ds
574         pushw   $6f
575         lretw
576 6:
577 
578 # Check signature at end of setup
579         cmpl    $0x5a5aaa55, setup_sig
580         jne     setup_bad
581 
582 # Zero the bss
583         movw    $__bss_start, %di
584         movw    $_end+3, %cx
585         xorl    %eax, %eax
586         subw    %di, %cx
587         shrw    $2, %cx
588         rep; stosl
589 
590 # Jump to C code (should not return)
591         calll   main
592 
593 # Setup corrupt somehow...
594 setup_bad:
595         movl    $setup_corrupt, %eax
596         calll   puts
597         # Fall through...
598 
599         .globl  die
600         .type   die, @function
601 die:
602         hlt
603         jmp     die
604 
605         .size   die, .-die
606 
607         .section ".initdata", "a"
608 setup_corrupt:
609         .byte   7
610         .string "No setup signature found...\n"

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php