]> nv-tegra.nvidia Code Review - linux-3.10.git/blob - arch/x86_64/boot/compressed/head.S
b0df2aeff5dcc81c19cbe08e883ebb58ab55d73e
[linux-3.10.git] / arch / x86_64 / boot / compressed / head.S
1 /*
2  *  linux/boot/head.S
3  *
4  *  Copyright (C) 1991, 1992, 1993  Linus Torvalds
5  *
6  *  $Id: head.S,v 1.3 2001/04/20 00:59:28 ak Exp $                      
7  */
8
9 /*
10  *  head.S contains the 32-bit startup code.
11  *
12  * NOTE!!! Startup happens at absolute address 0x00001000, which is also where
13  * the page directory will exist. The startup code will be overwritten by
14  * the page directory. [According to comments etc elsewhere on a compressed
15  * kernel it will end up at 0x1000 + 1Mb I hope so as I assume this. - AC]
16  *
17  * Page 0 is deliberately kept safe, since System Management Mode code in 
18  * laptops may need to access the BIOS data stored there.  This is also
19  * useful for future device drivers that either access the BIOS via VM86 
20  * mode.
21  */
22
23 /*
24  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996     
25  */
26 .code32
27 .text
28
29 #include <linux/linkage.h>
30 #include <asm/segment.h>
31 #include <asm/page.h>
32
33         .code32
34         .globl startup_32
35         
36 startup_32:
37         cld
38         cli
39         movl $(__KERNEL_DS),%eax
40         movl %eax,%ds
41         movl %eax,%es
42         movl %eax,%fs
43         movl %eax,%gs
44
45         lss stack_start,%esp
46         xorl %eax,%eax
47 1:      incl %eax               # check that A20 really IS enabled
48         movl %eax,0x000000      # loop forever if it isn't
49         cmpl %eax,0x100000
50         je 1b
51
52 /*
53  * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
54  * confuse the debugger if this code is traced.
55  * XXX - best to initialize before switching to protected mode.
56  */
57         pushl $0
58         popfl
59 /*
60  * Clear BSS
61  */
62         xorl %eax,%eax
63         movl $_edata,%edi
64         movl $_end,%ecx
65         subl %edi,%ecx
66         cld
67         rep
68         stosb
69 /*
70  * Do the decompression, and jump to the new kernel..
71  */
72         subl $16,%esp   # place for structure on the stack
73         movl %esp,%eax
74         pushl %esi      # real mode pointer as second arg
75         pushl %eax      # address of structure as first arg
76         call decompress_kernel
77         orl  %eax,%eax 
78         jnz  3f
79         addl $8,%esp
80         xorl %ebx,%ebx
81         ljmp $(__KERNEL_CS), $__PHYSICAL_START
82
83 /*
84  * We come here, if we were loaded high.
85  * We need to move the move-in-place routine down to 0x1000
86  * and then start it with the buffer addresses in registers,
87  * which we got from the stack.
88  */
89 3:
90         movl %esi,%ebx  
91         movl $move_routine_start,%esi
92         movl $0x1000,%edi
93         movl $move_routine_end,%ecx
94         subl %esi,%ecx
95         addl $3,%ecx
96         shrl $2,%ecx
97         cld
98         rep
99         movsl
100
101         popl %esi       # discard the address
102         addl $4,%esp    # real mode pointer
103         popl %esi       # low_buffer_start
104         popl %ecx       # lcount
105         popl %edx       # high_buffer_start
106         popl %eax       # hcount
107         movl $__PHYSICAL_START,%edi
108         cli             # make sure we don't get interrupted
109         ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine
110
111 /*
112  * Routine (template) for moving the decompressed kernel in place,
113  * if we were high loaded. This _must_ PIC-code !
114  */
115 move_routine_start:
116         movl %ecx,%ebp
117         shrl $2,%ecx
118         rep
119         movsl
120         movl %ebp,%ecx
121         andl $3,%ecx
122         rep
123         movsb
124         movl %edx,%esi
125         movl %eax,%ecx  # NOTE: rep movsb won't move if %ecx == 0
126         addl $3,%ecx
127         shrl $2,%ecx
128         rep
129         movsl
130         movl %ebx,%esi  # Restore setup pointer
131         xorl %ebx,%ebx
132         ljmp $(__KERNEL_CS), $__PHYSICAL_START
133 move_routine_end:
134
135
136 /* Stack for uncompression */   
137         .align 32
138 user_stack:             
139         .fill 4096,4,0
140 stack_start:    
141         .long user_stack+4096
142         .word __KERNEL_DS
143