Commit | Line | Data |
---|---|---|
1da177e4 LT |
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> | |
d0537508 | 31 | #include <asm/page.h> |
1da177e4 LT |
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 | |
d0537508 | 81 | ljmp $(__KERNEL_CS), $__PHYSICAL_START |
1da177e4 LT |
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 | |
d0537508 | 107 | movl $__PHYSICAL_START,%edi |
1da177e4 LT |
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 | |
d0537508 | 132 | ljmp $(__KERNEL_CS), $__PHYSICAL_START |
1da177e4 LT |
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 |