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

TOMOYO Linux Cross Reference
Linux/arch/x86/boot/compressed/head_32.S

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ 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.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 /*
  3  *  linux/boot/head.S
  4  *
  5  *  Copyright (C) 1991, 1992, 1993  Linus Torvalds
  6  */
  7 
  8 /*
  9  *  head.S contains the 32-bit startup code.
 10  *
 11  * NOTE!!! Startup happens at absolute address 0x00001000, which is also where
 12  * the page directory will exist. The startup code will be overwritten by
 13  * the page directory. [According to comments etc elsewhere on a compressed
 14  * kernel it will end up at 0x1000 + 1Mb I hope so as I assume this. - AC]
 15  *
 16  * Page 0 is deliberately kept safe, since System Management Mode code in
 17  * laptops may need to access the BIOS data stored there.  This is also
 18  * useful for future device drivers that either access the BIOS via VM86
 19  * mode.
 20  */
 21 
 22 /*
 23  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
 24  */
 25         .text
 26 
 27 #include <linux/init.h>
 28 #include <linux/linkage.h>
 29 #include <asm/segment.h>
 30 #include <asm/page_types.h>
 31 #include <asm/boot.h>
 32 #include <asm/asm-offsets.h>
 33 #include <asm/bootparam.h>
 34 
 35 /*
 36  * These symbols needed to be marked as .hidden to prevent the BFD linker from
 37  * generating R_386_32 (rather than R_386_RELATIVE) relocations for them when
 38  * the 32-bit compressed kernel is linked as PIE. This is no longer necessary,
 39  * but it doesn't hurt to keep them .hidden.
 40  */
 41         .hidden _bss
 42         .hidden _ebss
 43         .hidden _end
 44 
 45         __HEAD
 46 SYM_FUNC_START(startup_32)
 47         cld
 48         cli
 49 
 50 /*
 51  * Calculate the delta between where we were compiled to run
 52  * at and where we were actually loaded at.  This can only be done
 53  * with a short local call on x86.  Nothing  else will tell us what
 54  * address we are running at.  The reserved chunk of the real-mode
 55  * data at 0x1e4 (defined as a scratch field) are used as the stack
 56  * for this calculation. Only 4 bytes are needed.
 57  */
 58         leal    (BP_scratch+4)(%esi), %esp
 59         call    1f
 60 1:      popl    %edx
 61         addl    $_GLOBAL_OFFSET_TABLE_+(.-1b), %edx
 62 
 63         /* Load new GDT */
 64         leal    gdt@GOTOFF(%edx), %eax
 65         movl    %eax, 2(%eax)
 66         lgdt    (%eax)
 67 
 68         /* Load segment registers with our descriptors */
 69         movl    $__BOOT_DS, %eax
 70         movl    %eax, %ds
 71         movl    %eax, %es
 72         movl    %eax, %fs
 73         movl    %eax, %gs
 74         movl    %eax, %ss
 75 
 76 /*
 77  * %edx contains the address we are loaded at by the boot loader (plus the
 78  * offset to the GOT).  The below code calculates %ebx to be the address where
 79  * we should move the kernel image temporarily for safe in-place decompression
 80  * (again, plus the offset to the GOT).
 81  *
 82  * %ebp is calculated to be the address that the kernel will be decompressed to.
 83  */
 84 
 85 #ifdef CONFIG_RELOCATABLE
 86         leal    startup_32@GOTOFF(%edx), %ebx
 87         movl    BP_kernel_alignment(%esi), %eax
 88         decl    %eax
 89         addl    %eax, %ebx
 90         notl    %eax
 91         andl    %eax, %ebx
 92         cmpl    $LOAD_PHYSICAL_ADDR, %ebx
 93         jae     1f
 94 #endif
 95         movl    $LOAD_PHYSICAL_ADDR, %ebx
 96 1:
 97 
 98         movl    %ebx, %ebp      // Save the output address for later
 99         /* Target address to relocate to for decompression */
100         addl    BP_init_size(%esi), %ebx
101         subl    $_end@GOTOFF, %ebx
102 
103         /* Set up the stack */
104         leal    boot_stack_end@GOTOFF(%ebx), %esp
105 
106         /* Zero EFLAGS */
107         pushl   $0
108         popfl
109 
110 /*
111  * Copy the compressed kernel to the end of our buffer
112  * where decompression in place becomes safe.
113  */
114         pushl   %esi
115         leal    (_bss@GOTOFF-4)(%edx), %esi
116         leal    (_bss@GOTOFF-4)(%ebx), %edi
117         movl    $(_bss - startup_32), %ecx
118         shrl    $2, %ecx
119         std
120         rep     movsl
121         cld
122         popl    %esi
123 
124         /*
125          * The GDT may get overwritten either during the copy we just did or
126          * during extract_kernel below. To avoid any issues, repoint the GDTR
127          * to the new copy of the GDT.
128          */
129         leal    gdt@GOTOFF(%ebx), %eax
130         movl    %eax, 2(%eax)
131         lgdt    (%eax)
132 
133 /*
134  * Jump to the relocated address.
135  */
136         leal    .Lrelocated@GOTOFF(%ebx), %eax
137         jmp     *%eax
138 SYM_FUNC_END(startup_32)
139 
140         .text
141 SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
142 
143 /*
144  * Clear BSS (stack is currently empty)
145  */
146         xorl    %eax, %eax
147         leal    _bss@GOTOFF(%ebx), %edi
148         leal    _ebss@GOTOFF(%ebx), %ecx
149         subl    %edi, %ecx
150         shrl    $2, %ecx
151         rep     stosl
152 
153 /*
154  * Do the extraction, and jump to the new kernel..
155  */
156         /* push arguments for extract_kernel: */
157 
158         pushl   %ebp                    /* output address */
159         pushl   %esi                    /* real mode pointer */
160         call    extract_kernel          /* returns kernel entry point in %eax */
161         addl    $24, %esp
162 
163 /*
164  * Jump to the extracted kernel.
165  */
166         xorl    %ebx, %ebx
167         jmp     *%eax
168 SYM_FUNC_END(.Lrelocated)
169 
170         .data
171         .balign 8
172 SYM_DATA_START_LOCAL(gdt)
173         .word   gdt_end - gdt - 1
174         .long   0
175         .word   0
176         .quad   0x0000000000000000      /* Reserved */
177         .quad   0x00cf9a000000ffff      /* __KERNEL_CS */
178         .quad   0x00cf92000000ffff      /* __KERNEL_DS */
179 SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end)
180 
181 /*
182  * Stack and heap for uncompression
183  */
184         .bss
185         .balign 4
186 boot_stack:
187         .fill BOOT_STACK_SIZE, 1, 0
188 boot_stack_end:

~ [ 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