blob: 6f55565e4d4213cbfd295000bc88b70f742f8425 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/boot/head.S
3 *
4 * Copyright (C) 1991, 1992, 1993 Linus Torvalds
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 */
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/*
Domen Puncerf4549442005-06-25 14:58:59 -070022 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
Linus Torvalds1da177e2005-04-16 15:20:36 -070023 */
24.code32
25.text
26
27#include <linux/linkage.h>
28#include <asm/segment.h>
Eric W. Biedermand0537502005-06-25 14:57:52 -070029#include <asm/page.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
31 .code32
32 .globl startup_32
33
34startup_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
451: 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
Eric W. Biedermand0537502005-06-25 14:57:52 -070079 ljmp $(__KERNEL_CS), $__PHYSICAL_START
Linus Torvalds1da177e2005-04-16 15:20:36 -070080
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 */
873:
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
Eric W. Biedermand0537502005-06-25 14:57:52 -0700105 movl $__PHYSICAL_START,%edi
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 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 */
113move_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
Eric W. Biedermand0537502005-06-25 14:57:52 -0700130 ljmp $(__KERNEL_CS), $__PHYSICAL_START
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131move_routine_end:
132
133
134/* Stack for uncompression */
135 .align 32
136user_stack:
137 .fill 4096,4,0
138stack_start:
139 .long user_stack+4096
140 .word __KERNEL_DS
141