[SHELL32] Remove 2 redundant initializations
[reactos.git] / boot / freeldr / freeldr / arch / i386 / multiboot.S
1 /*
2 * FreeLoader
3 * Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <asm.inc>
21 #include <arch/pc/x86common.h>
22 #include <multiboot.h>
23
24 /* Multiboot support
25 *
26 * Allows freeldr to be loaded as a "multiboot kernel" by
27 * other boot loaders like GRUB.
28 * This code is not referenced from anywhere. GRUB searches for
29 * the header signature and uses the header to load it.
30 */
31
32 #define MB_INFO_FLAGS_OFFSET 0
33 #define MB_INFO_BOOT_DEVICE_OFFSET 12
34 #define MB_INFO_COMMAND_LINE_OFFSET 16
35 #define CMDLINE_SIZE 256
36
37 /*
38 * We want to execute at FREELDR_BASE (to be compatible with
39 * bootsector loading), but GRUB only allows loading of
40 * multiboot kernels above 1MB. So we let GRUB load us
41 * there and then relocate ourself to FREELDR_BASE.
42 */
43 #define INITIAL_BASE HEX(200000)
44
45
46 #ifdef _USE_ML
47 EXTERN __bss_start__:DWORD
48 EXTERN __bss_end__:DWORD
49 #endif
50
51
52 #ifdef _USE_ML
53 .MBDATA SEGMENT PUBLIC 'DATA'
54 ASSUME nothing
55 #endif
56
57 /* Align to 32 bits boundary */
58 .align 4
59
60 /* Multiboot header */
61 MultibootHeader:
62 /* magic */
63 .long MULTIBOOT_HEADER_MAGIC
64 /* flags */
65 .long MULTIBOOT_HEADER_FLAGS
66 /* checksum */
67 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
68 /* header_addr */
69 .long MultibootHeader + INITIAL_BASE - FREELDR_BASE
70 /* load_addr */
71 .long INITIAL_BASE
72 /* load_end_addr */
73 .long 0
74 /* bss_end_addr */
75 .long 0
76 /* entry_addr */
77 .long MultibootEntry + INITIAL_BASE - FREELDR_BASE
78
79 #ifdef _USE_ML
80 .MBDATA ENDS
81 #endif
82
83
84 .code32
85 ASSUME ES:NOTHING, FS:NOTHING, GS:NOTHING
86
87 MultibootEntry:
88 cld
89
90 /* Check for valid multiboot signature */
91 cmp eax, MULTIBOOT_BOOTLOADER_MAGIC
92 jne mbfail
93
94 /* Save command line */
95 test dword ptr ds:[ebx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_COMMAND_LINE
96 jz mb2
97 mov esi, dword ptr ds:[ebx + MB_INFO_COMMAND_LINE_OFFSET]
98 mov edi, offset cmdline + INITIAL_BASE - FREELDR_BASE
99 mov ecx, CMDLINE_SIZE - 1
100 mb1:
101 lodsb
102 stosb
103 test al, al
104 jz mb2
105 dec ecx
106 jnz mb1
107
108 mb2:
109 /* See if the boot device was passed in */
110 test dword ptr ds:[ebx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_BOOT_DEVICE
111
112 /* If no boot device known, assume first partition of first harddisk */
113 mov dx, HEX(0180)
114 jz mb3
115
116 /* Load boot drive into DL, boot partition into DH */
117 mov edx, dword ptr ds:[ebx + MB_INFO_BOOT_DEVICE_OFFSET]
118 bswap edx
119 inc dh
120
121 mb3:
122 /* Relocate itself to lower address */
123 mov esi, INITIAL_BASE
124 mov edi, FREELDR_BASE
125 mov ecx, offset __bss_start__ - FREELDR_BASE
126 shr ecx, 2
127 rep movsd
128
129 /* Load segment registers for real-address mode */
130 #ifdef _USE_ML
131 lgdt fword ptr ds:[gdtptr]
132 #else
133 lgdt ds:[gdtptr]
134 #endif
135 mov ax, HEX(10)
136 mov ds, ax
137 mov es, ax
138 mov fs, ax
139 mov gs, ax
140 mov ss, ax
141
142 /* Jump to relocated code */
143 ljmp HEX(08), mb4
144
145 mbfail:
146 int 3
147 mbstop:
148 jmp short mbstop /* We should never get here */
149
150 .code16
151 mb4:
152 /* Disable protected mode */
153 mov eax, cr0
154 and eax, CR0_PE_CLR
155 mov cr0, eax
156
157 /* Jump to real entry point */
158 ljmp16 0, FREELDR_BASE
159 .endcode16
160
161
162 /* Force 8-byte alignment */
163 .align 8
164 gdt:
165 .word HEX(0000), HEX(0000), HEX(0000), HEX(0000) /* 00: NULL descriptor */
166 .word HEX(FFFF), HEX(0000), HEX(9B00), HEX(008F) /* 08: 16-bit flat CS (!) */
167 .word HEX(FFFF), HEX(0000), HEX(9300), HEX(0000) /* 10: 16-bit real mode DS */
168
169 /* GDT table pointer */
170 gdtptr:
171 .word HEX(17) /* Limit */
172 .long gdt /* Base Address */
173
174 PUBLIC cmdline
175 cmdline:
176 .space CMDLINE_SIZE
177
178 END