Linux-2.6.12-rc2
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / arch / x86_64 / boot / compressed / head.S
blob27264dbd575c222f0fd02c8758d7edf459e34adb
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  */
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  */
24  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996     
25  */
26 .code32
27 .text
29 #include <linux/linkage.h>
30 #include <asm/segment.h>
32         .code32
33         .globl startup_32
34         
35 startup_32:
36         cld
37         cli
38         movl $(__KERNEL_DS),%eax
39         movl %eax,%ds
40         movl %eax,%es
41         movl %eax,%fs
42         movl %eax,%gs
44         lss stack_start,%esp
45         xorl %eax,%eax
46 1:      incl %eax               # check that A20 really IS enabled
47         movl %eax,0x000000      # loop forever if it isn't
48         cmpl %eax,0x100000
49         je 1b
52  * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
53  * confuse the debugger if this code is traced.
54  * XXX - best to initialize before switching to protected mode.
55  */
56         pushl $0
57         popfl
59  * Clear BSS
60  */
61         xorl %eax,%eax
62         movl $_edata,%edi
63         movl $_end,%ecx
64         subl %edi,%ecx
65         cld
66         rep
67         stosb
69  * Do the decompression, and jump to the new kernel..
70  */
71         subl $16,%esp   # place for structure on the stack
72         movl %esp,%eax
73         pushl %esi      # real mode pointer as second arg
74         pushl %eax      # address of structure as first arg
75         call decompress_kernel
76         orl  %eax,%eax 
77         jnz  3f
78         addl $8,%esp
79         xorl %ebx,%ebx
80         ljmp $(__KERNEL_CS), $0x100000
83  * We come here, if we were loaded high.
84  * We need to move the move-in-place routine down to 0x1000
85  * and then start it with the buffer addresses in registers,
86  * which we got from the stack.
87  */
89         movl %esi,%ebx  
90         movl $move_routine_start,%esi
91         movl $0x1000,%edi
92         movl $move_routine_end,%ecx
93         subl %esi,%ecx
94         addl $3,%ecx
95         shrl $2,%ecx
96         cld
97         rep
98         movsl
100         popl %esi       # discard the address
101         addl $4,%esp    # real mode pointer
102         popl %esi       # low_buffer_start
103         popl %ecx       # lcount
104         popl %edx       # high_buffer_start
105         popl %eax       # hcount
106         movl $0x100000,%edi
107         cli             # make sure we don't get interrupted
108         ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine
111  * Routine (template) for moving the decompressed kernel in place,
112  * if we were high loaded. This _must_ PIC-code !
113  */
114 move_routine_start:
115         movl %ecx,%ebp
116         shrl $2,%ecx
117         rep
118         movsl
119         movl %ebp,%ecx
120         andl $3,%ecx
121         rep
122         movsb
123         movl %edx,%esi
124         movl %eax,%ecx  # NOTE: rep movsb won't move if %ecx == 0
125         addl $3,%ecx
126         shrl $2,%ecx
127         rep
128         movsl
129         movl %ebx,%esi  # Restore setup pointer
130         xorl %ebx,%ebx
131         ljmp $(__KERNEL_CS), $0x100000
132 move_routine_end:
135 /* Stack for uncompression */   
136         .align 32
137 user_stack:             
138         .fill 4096,4,0
139 stack_start:    
140         .long user_stack+4096
141         .word __KERNEL_DS