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