]>
git.saurik.com Git - apple/boot.git/blob - i386/boot2/boot.c
48145f415d0635a303eee2fabc88e948bb854c07
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
25 * Mach Operating System
26 * Copyright (c) 1990 Carnegie-Mellon University
27 * Copyright (c) 1989 Carnegie-Mellon University
28 * All rights reserved. The CMU software License Agreement specifies
29 * the terms and conditions for use and redistribution.
33 * INTEL CORPORATION PROPRIETARY INFORMATION
35 * This software is supplied under the terms of a license agreement or
36 * nondisclosure agreement with Intel Corporation and may not be copied
37 * nor disclosed except in accordance with the terms of that agreement.
39 * Copyright 1988, 1989 by Intel Corporation
43 * Copyright 1993 NeXT Computer, Inc.
44 * All rights reserved.
48 * Completely reworked by Sam Streeper (sam_s@NeXT.com)
49 * Reworked again by Curtis Galloway (galloway@NeXT.com)
53 #include "bootstruct.h"
57 * The user asked for boot graphics.
59 BOOL gBootGraphics
= NO
;
60 long gBootMode
= kBootModeNormal
;
61 static char gBootKernelCacheFile
[512];
63 static BOOL gUnloadPXEOnExit
= 0;
66 * How long to wait (in seconds) to load the
67 * kernel after displaying the "boot:" prompt.
69 #define kBootErrorTimeout 5
72 * Default path to kernel cache file
74 #define kDefaultCachePath "/System/Library/Caches/com.apple.kernelcaches/kernelcache"
76 //==========================================================================
81 extern char _DATA__bss__begin
, _DATA__bss__end
;
82 extern char _DATA__common__begin
, _DATA__common__end
;
84 bzero( &_DATA__bss__begin
,
85 (&_DATA__bss__end
- &_DATA__bss__begin
) );
87 bzero( &_DATA__common__begin
,
88 (&_DATA__common__end
- &_DATA__common__begin
) );
91 //==========================================================================
92 // Malloc error function
94 static void malloc_error(char *addr
, size_t size
)
96 printf("\nMemory allocation error (0x%x, 0x%x)\n",
97 (unsigned)addr
, (unsigned)size
);
101 //==========================================================================
102 // execKernel - Load the kernel image (mach-o) and jump to its entry point.
104 static int ExecKernel(void *binary
)
109 bootArgs
->kaddr
= bootArgs
->ksize
= 0;
111 ret
= DecodeKernel(binary
,
113 (char **) &bootArgs
->kaddr
,
119 // Reserve space for boot args
120 reserveKernBootStruct();
122 // Load boot drivers from the specifed root path.
124 if (!gHaveKernelCache
) {
128 clearActivityIndicator();
131 printf("Errors encountered while starting up the computer.\n");
132 printf("Pausing %d seconds...\n", kBootErrorTimeout
);
133 sleep(kBootErrorTimeout
);
136 printf("Starting Darwin/x86");
140 // Connect to APM BIOS.
142 if ( getBoolForKey("APM") )
144 if ( APMPresent() ) APMConnect32();
147 // Cleanup the PXE base code.
149 if ( (gBootFileType
== kNetworkDeviceType
) && gUnloadPXEOnExit
) {
150 if ( (ret
= nbpUnloadBaseCode()) != nbpStatusSuccess
)
152 printf("nbpUnloadBaseCode error %d\n", (int) ret
);
157 // Switch to desired video mode just before starting the kernel.
159 setVideoMode( gBootGraphics
? GRAPHICS_MODE
: TEXT_MODE
);
161 // Jump to kernel's entry point. There's no going back now.
163 startprog( kernelEntry
, bootArgs
);
170 //==========================================================================
171 // Scan and record the system's hardware information.
173 static void scanHardware()
175 extern int ReadPCIBusInfo(PCI_bus_info_t
*);
176 extern void PCI_Bus_Init(PCI_bus_info_t
*);
178 ReadPCIBusInfo( &bootArgs
->pciInfo
);
181 // Initialize PCI matching support in the booter.
182 // Not used, commented out to minimize code size.
184 // PCI_Bus_Init( &bootArgs->pciInfo );
187 //==========================================================================
188 // The 'main' function for the booter. Called by boot0 when booting
189 // from a block device, or by the network booter.
192 // biosdev - Value passed from boot1/NBP to specify the device
193 // that the booter was loaded from.
195 // If biosdev is kBIOSDevNetwork, then this function will return if
196 // booting was unsuccessful. This allows the PXE firmware to try the
197 // next boot device on its list.
199 void boot(int biosdev
)
208 malloc_init(0, 0, 0, malloc_error
);
210 // Enable A20 gate before accessing memory above 1Mb.
214 // Set reminder to unload the PXE base code. Neglect to unload
215 // the base code will result in a hang or kernel panic.
217 gUnloadPXEOnExit
= 1;
219 // Record the device that the booter was loaded from.
221 gBIOSDev
= biosdev
& kBIOSDevMask
;
223 // Initialize boot info structure.
225 initKernBootStruct( gBIOSDev
);
227 // Setup VGA text mode.
228 // Not sure if it is safe to call setVideoMode() before the
229 // config table has been loaded. Call video_mode() instead.
231 video_mode( 2 ); // 80x25 mono text mode.
233 // Scan hardware configuration.
237 // Display banner and show hardware info.
239 setCursorPosition( 0, 0, 0 );
240 printf( bootBanner
, bootArgs
->convmem
, bootArgs
->extmem
);
243 // Parse args, load and start kernel.
249 long flags
, cachetime
, time
;
252 // Initialize globals.
257 // Reset config space.
258 bootArgs
->configEnd
= bootArgs
->config
;
261 status
= processBootOptions();
262 if ( status
== 1 ) break;
263 if ( status
== -1 ) continue;
265 // Found and loaded a config file. Proceed with boot.
267 // Check for cache file.
269 if (getValueForKey(kKernelCacheKey
, &val
, &len
)) {
270 strncpy(gBootKernelCacheFile
, val
, len
);
271 gBootKernelCacheFile
[len
] = '\0';
273 strcpy(gBootKernelCacheFile
, kDefaultCachePath
);
276 trycache
= (((gBootMode
& kBootModeSafe
) == 0) &&
277 (gBootFileType
== kBlockDeviceType
) &&
278 (gBootKernelCacheFile
[0] != '\0'));
280 printf("Loading Darwin/x86\n");
284 // if we haven't found the kernel yet, don't use the cache
285 ret
= GetFileInfo(NULL
, bootArgs
->bootFile
, &flags
, &time
);
286 if ((ret
!= 0) || ((flags
& kFileTypeMask
) != kFileTypeFlat
)) {
290 ret
= GetFileInfo(NULL
, gBootKernelCacheFile
, &flags
, &cachetime
);
291 if ((ret
!= 0) || ((flags
& kFileTypeMask
) != kFileTypeFlat
)
292 || (cachetime
< time
)) {
296 ret
= GetFileInfo("/System/Library/", "Extensions", &flags
, &time
);
297 if ((ret
== 0) && ((flags
& kFileTypeMask
) == kFileTypeDirectory
)
298 && (cachetime
< time
)) {
306 bootFile
= gBootKernelCacheFile
;
307 verbose("Loading kernel cache %s\n", bootFile
);
308 ret
= LoadFile(bootFile
);
313 bootFile
= bootArgs
->bootFile
;
314 verbose("Loading kernel %s\n", bootFile
);
315 ret
= LoadFile(bootFile
);
318 clearActivityIndicator();
321 error("Can't find %s\n", bootFile
);
323 if ( gBootFileType
== kBIOSDevTypeFloppy
)
325 // floppy in drive, but failed to load kernel.
326 gBIOSDev
= kBIOSDevTypeHardDrive
;
327 initKernBootStruct( gBIOSDev
);
328 printf("Attempt to load from hard drive.");
330 else if ( gBootFileType
== kNetworkDeviceType
)
332 // Return control back to PXE. Don't unload PXE base code.
333 gUnloadPXEOnExit
= 0;
337 /* Won't return if successful. */
338 ret
= ExecKernel((void *)kLoadAddr
);
343 if ((gBootFileType
== kNetworkDeviceType
) && gUnloadPXEOnExit
) {