]>
git.saurik.com Git - apple/boot.git/blob - i386/boot2/boot.c
fbd37ca11135fa8ef8e02584a9a70f0b43a0fc7b
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Mach Operating System
27 * Copyright (c) 1990 Carnegie-Mellon University
28 * Copyright (c) 1989 Carnegie-Mellon University
29 * All rights reserved. The CMU software License Agreement specifies
30 * the terms and conditions for use and redistribution.
34 * INTEL CORPORATION PROPRIETARY INFORMATION
36 * This software is supplied under the terms of a license agreement or
37 * nondisclosure agreement with Intel Corporation and may not be copied
38 * nor disclosed except in accordance with the terms of that agreement.
40 * Copyright 1988, 1989 by Intel Corporation
44 * Copyright 1993 NeXT Computer, Inc.
45 * All rights reserved.
49 * Completely reworked by Sam Streeper (sam_s@NeXT.com)
50 * Reworked again by Curtis Galloway (galloway@NeXT.com)
54 #include "bootstruct.h"
58 * The user asked for boot graphics.
60 BOOL gBootGraphics
= NO
;
61 long gBootMode
= kBootModeNormal
;
62 static char gBootKernelCacheFile
[512];
64 static BOOL gUnloadPXEOnExit
= 0;
67 * How long to wait (in seconds) to load the
68 * kernel after displaying the "boot:" prompt.
70 #define kBootErrorTimeout 5
73 * Default path to kernel cache file
75 #define kDefaultCachePath "/System/Library/Caches/com.apple.kernelcaches/kernelcache"
77 //==========================================================================
82 extern char _DATA__bss__begin
, _DATA__bss__end
;
83 extern char _DATA__common__begin
, _DATA__common__end
;
85 bzero( &_DATA__bss__begin
,
86 (&_DATA__bss__end
- &_DATA__bss__begin
) );
88 bzero( &_DATA__common__begin
,
89 (&_DATA__common__end
- &_DATA__common__begin
) );
92 //==========================================================================
93 // Malloc error function
95 static void malloc_error(char *addr
, size_t size
)
97 printf("\nMemory allocation error (0x%x, 0x%x)\n",
98 (unsigned)addr
, (unsigned)size
);
102 //==========================================================================
103 // execKernel - Load the kernel image (mach-o) and jump to its entry point.
105 static int ExecKernel(void *binary
)
110 bootArgs
->kaddr
= bootArgs
->ksize
= 0;
112 ret
= DecodeKernel(binary
,
114 (char **) &bootArgs
->kaddr
,
120 // Reserve space for boot args
121 reserveKernBootStruct();
123 // Load boot drivers from the specifed root path.
125 if (!gHaveKernelCache
) {
129 clearActivityIndicator();
132 printf("Errors encountered while starting up the computer.\n");
133 printf("Pausing %d seconds...\n", kBootErrorTimeout
);
134 sleep(kBootErrorTimeout
);
137 printf("Starting Darwin/x86");
141 // Connect to APM BIOS.
143 if ( getBoolForKey("APM") )
145 if ( APMPresent() ) APMConnect32();
148 // Cleanup the PXE base code.
150 if ( (gBootFileType
== kNetworkDeviceType
) && gUnloadPXEOnExit
) {
151 if ( (ret
= nbpUnloadBaseCode()) != nbpStatusSuccess
)
153 printf("nbpUnloadBaseCode error %d\n", (int) ret
);
158 // Switch to desired video mode just before starting the kernel.
160 setVideoMode( gBootGraphics
? GRAPHICS_MODE
: TEXT_MODE
);
162 // Jump to kernel's entry point. There's no going back now.
164 startprog( kernelEntry
, bootArgs
);
171 //==========================================================================
172 // Scan and record the system's hardware information.
174 static void scanHardware()
176 extern int ReadPCIBusInfo(PCI_bus_info_t
*);
177 extern void PCI_Bus_Init(PCI_bus_info_t
*);
179 ReadPCIBusInfo( &bootArgs
->pciInfo
);
182 // Initialize PCI matching support in the booter.
183 // Not used, commented out to minimize code size.
185 // PCI_Bus_Init( &bootArgs->pciInfo );
188 //==========================================================================
189 // The 'main' function for the booter. Called by boot0 when booting
190 // from a block device, or by the network booter.
193 // biosdev - Value passed from boot1/NBP to specify the device
194 // that the booter was loaded from.
196 // If biosdev is kBIOSDevNetwork, then this function will return if
197 // booting was unsuccessful. This allows the PXE firmware to try the
198 // next boot device on its list.
200 void boot(int biosdev
)
209 malloc_init(0, 0, 0, malloc_error
);
211 // Enable A20 gate before accessing memory above 1Mb.
215 // Set reminder to unload the PXE base code. Neglect to unload
216 // the base code will result in a hang or kernel panic.
218 gUnloadPXEOnExit
= 1;
220 // Record the device that the booter was loaded from.
222 gBIOSDev
= biosdev
& kBIOSDevMask
;
224 // Initialize boot info structure.
226 initKernBootStruct( gBIOSDev
);
228 // Setup VGA text mode.
229 // Not sure if it is safe to call setVideoMode() before the
230 // config table has been loaded. Call video_mode() instead.
232 video_mode( 2 ); // 80x25 mono text mode.
234 // Scan hardware configuration.
238 // Display banner and show hardware info.
240 setCursorPosition( 0, 0, 0 );
241 printf( bootBanner
, bootArgs
->convmem
, bootArgs
->extmem
);
244 // Parse args, load and start kernel.
250 long flags
, cachetime
, time
;
253 // Initialize globals.
258 // Reset config space.
259 bootArgs
->configEnd
= bootArgs
->config
;
262 status
= processBootOptions();
263 if ( status
== 1 ) break;
264 if ( status
== -1 ) continue;
266 // Found and loaded a config file. Proceed with boot.
268 // Check for cache file.
270 if (getValueForKey(kKernelCacheKey
, &val
, &len
)) {
271 strncpy(gBootKernelCacheFile
, val
, len
);
272 gBootKernelCacheFile
[len
] = '\0';
274 strcpy(gBootKernelCacheFile
, kDefaultCachePath
);
277 trycache
= (((gBootMode
& kBootModeSafe
) == 0) &&
278 (gBootFileType
== kBlockDeviceType
) &&
279 (gBootKernelCacheFile
[0] != '\0'));
281 printf("Loading Darwin/x86\n");
285 // if we haven't found the kernel yet, don't use the cache
286 ret
= GetFileInfo(NULL
, bootArgs
->bootFile
, &flags
, &time
);
287 if ((ret
!= 0) || ((flags
& kFileTypeMask
) != kFileTypeFlat
)) {
291 ret
= GetFileInfo(NULL
, gBootKernelCacheFile
, &flags
, &cachetime
);
292 if ((ret
!= 0) || ((flags
& kFileTypeMask
) != kFileTypeFlat
)
293 || (cachetime
< time
)) {
297 ret
= GetFileInfo("/System/Library/", "Extensions", &flags
, &time
);
298 if ((ret
== 0) && ((flags
& kFileTypeMask
) == kFileTypeDirectory
)
299 && (cachetime
< time
)) {
307 bootFile
= gBootKernelCacheFile
;
308 verbose("Loading kernel cache %s\n", bootFile
);
309 ret
= LoadFile(bootFile
);
314 bootFile
= bootArgs
->bootFile
;
315 verbose("Loading kernel %s\n", bootFile
);
316 ret
= LoadFile(bootFile
);
319 clearActivityIndicator();
322 error("Can't find %s\n", bootFile
);
324 if ( gBootFileType
== kBIOSDevTypeFloppy
)
326 // floppy in drive, but failed to load kernel.
327 gBIOSDev
= kBIOSDevTypeHardDrive
;
328 initKernBootStruct( gBIOSDev
);
329 printf("Attempt to load from hard drive.");
331 else if ( gBootFileType
== kNetworkDeviceType
)
333 // Return control back to PXE. Don't unload PXE base code.
334 gUnloadPXEOnExit
= 0;
338 /* Won't return if successful. */
339 ret
= ExecKernel((void *)kLoadAddr
);
344 if ((gBootFileType
== kNetworkDeviceType
) && gUnloadPXEOnExit
) {