Exemple #1
0
void initKernBootStruct( void )
{
	Node *node;
	int nameLen;
	static int init_done = 0;
	
	if ( !init_done )
	{
		bootArgs = (boot_args *)malloc(sizeof(boot_args));
		bootArgsPreLion = (boot_args_pre_lion *)malloc(sizeof(boot_args_pre_lion));
		bootInfo = (PrivateBootInfo_t *)malloc(sizeof(PrivateBootInfo_t));
		if (bootArgs == 0 || bootInfo == 0)
			stop("Couldn't allocate boot info\n");
		
		bzero(bootArgs, sizeof(boot_args));
		bzero(bootArgsPreLion, sizeof(boot_args_pre_lion));
		bzero(bootInfo, sizeof(PrivateBootInfo_t));
		
		// Get system memory map. Also update the size of the
		// conventional/extended memory for backwards compatibility.
		
		bootInfo->memoryMapCount =
			getMemoryMap( bootInfo->memoryMap, kMemoryMapCountMax,
						  (unsigned long *) &bootInfo->convmem,
						  (unsigned long *) &bootInfo->extmem );
		
		if ( bootInfo->memoryMapCount == 0 )
		{
			// BIOS did not provide a memory map, systems with
			// discontiguous memory or unusual memory hole locations
			// may have problems.
			
			bootInfo->convmem = getConventionalMemorySize();
			bootInfo->extmem  = getExtendedMemorySize();
		}
		
		bootInfo->configEnd	   = bootInfo->config;
		bootArgs->Video.v_display = VGA_TEXT_MODE;
		
		DT__Initialize();
		
		node = DT__FindNode("/", true);
		if (node == 0) {
			stop("Couldn't create root node");
		}
		getPlatformName(platformName);
		nameLen = strlen(platformName) + 1;
		DT__AddProperty(node, "compatible", nameLen, platformName);
		DT__AddProperty(node, "model", nameLen, platformName);
		
		gMemoryMapNode = DT__FindNode("/chosen/memory-map", true);
		
		bootArgs->Version  = kBootArgsVersion;
		bootArgs->Revision = kBootArgsRevision;
		
		bootArgsPreLion->Version  = kBootArgsPreLionVersion;
		bootArgsPreLion->Revision = kBootArgsPreLionRevision;
		
		init_done = 1;
	}
}
Exemple #2
0
// Notify OS X that a ramdisk has been setup. XNU will attach this to /dev/md0
void md0Ramdisk()
{
	RAMDiskParam ramdiskPtr;
	char filename[512];
	const char* override_filename = 0;
	int fh = -1;
	int len;
	
	if (getValueForKey(kMD0ImageKey, &override_filename, &len, &bootInfo->bootConfig))
	{
		// Use user specified md0 file
		sprintf(filename, "%s", override_filename);
		fh = open(filename, 0);
		
		if (fh < 0)
		{
			sprintf(filename, "rd(0,0)/Extra/Postboot.img");
			fh = open(filename, 0);

			if (fh < 0)
			{
				sprintf(filename, "bt(0,0)/Extra/Postboot.img");	// Check /Extra if not in rd(0,0)
				fh = open(filename, 0);
			}
		}		
	}		

	if (fh >= 0)
	{
		verbose("Enabling ramdisk %s\n", filename);

		ramdiskPtr.size = file_size(fh);
		ramdiskPtr.base = AllocateKernelMemory(ramdiskPtr.size);

		if (ramdiskPtr.size && ramdiskPtr.base)
		{
			// Read new ramdisk image contents in kernel memory.
			if (read(fh, (char*) ramdiskPtr.base, ramdiskPtr.size) == ramdiskPtr.size)
			{
				AllocateMemoryRange("RAMDisk", ramdiskPtr.base, ramdiskPtr.size, kBootDriverTypeInvalid);
				Node* node = DT__FindNode("/chosen/memory-map", false);
				if (node != NULL)
				{
					DT__AddProperty(node, "RAMDisk", sizeof(RAMDiskParam),  (void*)&ramdiskPtr);		
				}
				else
				{
					verbose("Unable to notify Mac OS X of the ramdisk %s.\n", filename);
				}
			}
			else
			{
				verbose("Unable to read md0 image %s.\n", filename);
			}			
		}
		else
		{
			verbose("md0 image %s is empty.\n", filename);
		}

		close(fh);
	}
}
Exemple #3
0
void setupEfiDeviceTree(void)
{
	EFI_CHAR8*	 ret = 0;
	EFI_CHAR16*	 ret16 = 0;
	size_t		 len = 0;
	Node		*node;
	
	node = DT__FindNode("/", false);
	
	if (node == 0) stop("Couldn't get root node");
	
	// We could also just do DT__FindNode("/efi/platform", true)
	// But I think eventually we want to fill stuff in the efi node
	// too so we might as well create it so we have a pointer for it too.
	node = DT__AddChild(node, "efi");
	
	if (archCpuType == CPU_TYPE_I386)
	{
		DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_32_PROP_VALUE), (char*)FIRMWARE_ABI_32_PROP_VALUE);
	}
	else
	{
		DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_64_PROP_VALUE), (char*)FIRMWARE_ABI_64_PROP_VALUE);
	}
	
	DT__AddProperty(node, FIRMWARE_REVISION_PROP, sizeof(FIRMWARE_REVISION), (EFI_UINT32*)&FIRMWARE_REVISION);
	DT__AddProperty(node, FIRMWARE_VENDOR_PROP, sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*)FIRMWARE_VENDOR);
	
	// TODO: Fill in other efi properties if necessary
	
	// Set up the /efi/runtime-services table node similar to the way a child node of configuration-table
	// is set up.  That is, name and table properties
	Node *runtimeServicesNode = DT__AddChild(node, "runtime-services");
	
	if (archCpuType == CPU_TYPE_I386)
	{
		// The value of the table property is the 32-bit physical address for the RuntimeServices table.
		// Since the EFI system table already has a pointer to it, we simply use the address of that pointer
		// for the pointer to the property data.  Warning.. DT finalization calls free on that but we're not
		// the only thing to use a non-malloc'd pointer for something in the DT
		
		DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST32->RuntimeServices);
	}
	else
	{
		DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST64->RuntimeServices);
	}
	
	// Set up the /efi/configuration-table node which will eventually have several child nodes for
	// all of the configuration tables needed by various kernel extensions.
	gEfiConfigurationTableNode = DT__AddChild(node, "configuration-table");
	
	// Now fill in the /efi/platform Node
	Node *efiPlatformNode = DT__AddChild(node, "platform");
	
	// NOTE WELL: If you do add FSB Frequency detection, make sure to store
	// the value in the fsbFrequency global and not an malloc'd pointer
	// because the DT_AddProperty function does not copy its args.
	
	if (Platform.CPU.FSBFrequency != 0)
		DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &Platform.CPU.FSBFrequency);
	
	// Export TSC and CPU frequencies for use by the kernel or KEXTs
	if (Platform.CPU.TSCFrequency != 0)
		DT__AddProperty(efiPlatformNode, TSC_Frequency_prop, sizeof(uint64_t), &Platform.CPU.TSCFrequency);
	
	if (Platform.CPU.CPUFrequency != 0)
		DT__AddProperty(efiPlatformNode, CPU_Frequency_prop, sizeof(uint64_t), &Platform.CPU.CPUFrequency);
	
	// Export system-id. Can be disabled with SystemId=No in com.apple.Boot.plist
	if ((ret=getSystemID()))
		DT__AddProperty(efiPlatformNode, SYSTEM_ID_PROP, UUID_LEN, (EFI_UINT32*) ret);
	
	// Export SystemSerialNumber if present
	if ((ret16=getSmbiosChar16("SMserial", &len)))
		DT__AddProperty(efiPlatformNode, SYSTEM_SERIAL_PROP, len, ret16);
	
	// Export Model if present
	if ((ret16=getSmbiosChar16("SMproductname", &len)))
		DT__AddProperty(efiPlatformNode, MODEL_PROP, len, ret16);
	
	// Fill /efi/device-properties node.
	setupDeviceProperties(node);
}
Exemple #4
0
void initEFITree(void)
{
	_EFI_DEBUG_DUMP("Entering initEFITree(%x)\n", gPlatform.ACPI.Guid.Data1);

	static char ACPI[] = "ACPI";

	// The required information should be added to private_data.h
	static EFI_CHAR16 const MODEL_NAME[]			= STATIC_MODEL_NAME;
	static EFI_CHAR16 const SYSTEM_SERIAL_NUMBER[]	= STATIC_SYSTEM_SERIAL_NUMBER;

	DT__Initialize(); // Add and initialize gPlatform.DT.RootNode

	/*
	 * The root node is available until the call to DT__Finalize, or the first call 
	 * to DT__AddChild with NULL as first argument. Which we don't do and thus we 
	 * can use it in the meantime, instead of defining a local / global variable.
	 */

	DT__AddProperty(gPlatform.DT.RootNode, "model", 5, ACPI);
	DT__AddProperty(gPlatform.DT.RootNode, "compatible", 5, ACPI);
	
	Node * efiNode = DT__AddChild(gPlatform.DT.RootNode, "efi");

	DT__AddProperty(efiNode, "firmware-abi", 6, (gPlatform.ArchCPUType == CPU_TYPE_X86_64) ? "EFI64" : "EFI32");
	DT__AddProperty(efiNode, "firmware-revision", sizeof(FIRMWARE_REVISION), (EFI_UINT32*) &FIRMWARE_REVISION);
	DT__AddProperty(efiNode, "firmware-vendor", sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*) FIRMWARE_VENDOR);

	// Initialize a global var, used by function setupEFITables later on, to
	// add the address to the boot arguments (done to speed up the process).
	gPlatform.EFI.Nodes.RuntimeServices = DT__AddChild(efiNode, "runtime-services");

	// Initialize a global var, used by function addConfigurationTable later on, 
	// to add the SMBIOS and ACPI tables (done to speed up the process).
	gPlatform.EFI.Nodes.ConfigurationTable = DT__AddChild(efiNode, "configuration-table");

	Node * platformNode = DT__AddChild(efiNode, "platform");

	gPlatform.EFI.Nodes.Platform = platformNode;

	// Satisfying AppleACPIPlatform.kext
	static EFI_UINT8 const DEVICE_PATHS_SUPPORTED[] = { 0x01, 0x00, 0x00, 0x00 };

	DT__AddProperty(platformNode, "DevicePathsSupported", sizeof(DEVICE_PATHS_SUPPORTED), (EFI_UINT8*) &DEVICE_PATHS_SUPPORTED);

	// The use of sizeof() here is mandatory (to prevent breakage).
	DT__AddProperty(platformNode, "Model", sizeof(MODEL_NAME), (EFI_CHAR16*) MODEL_NAME);
	DT__AddProperty(platformNode, "SystemSerialNumber", sizeof(SYSTEM_SERIAL_NUMBER), (EFI_CHAR16*) SYSTEM_SERIAL_NUMBER);

	if (gPlatform.CPU.FSBFrequency)
	{
		_EFI_DEBUG_DUMP("Adding FSBFrequency property (%dMHz)\n", (gPlatform.CPU.FSBFrequency / 1000));
		DT__AddProperty(platformNode, "FSBFrequency", sizeof(uint64_t), &gPlatform.CPU.FSBFrequency);
	}

	Node * chosenNode = DT__AddChild(gPlatform.DT.RootNode, "chosen");

	if (chosenNode == 0)
	{
		stop("Couldn't create /chosen node"); // Mimics boot.efi
	}

	gPlatform.EFI.Nodes.MemoryMap = DT__AddChild(chosenNode, "memory-map");

	// Adding the root path for kextcache.
	DT__AddProperty(chosenNode, "boot-device-path", 38, "\\System\\Library\\CoreServices\\boot.efi");

	/* static EFI_UINT8 const BOOT_DEVICE_PATH[] =
	{
		0x02, 0x01, 0x0C, 0x00, 0xD0, 0x41, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x06, 0x00,
		0x02, 0x1F, 0x03, 0x12, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x2A, 0x00,
		0x02, 0x00, 0x00, 0x00, 0x28, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0B, 0x63, 0x34,
		0x00, 0x00, 0x00, 0x00, 0x65, 0x8C, 0x53, 0x3F, 0x1B, 0xCA, 0x83, 0x38, 0xA9, 0xD0, 0xF0, 0x46,
		0x19, 0x14, 0x8E, 0x31, 0x02, 0x02, 0x7F, 0xFF, 0x04, 0x00
	};

	DT__AddProperty(chosenNode, "boot-device-path", sizeof(BOOT_DEVICE_PATH), &BOOT_DEVICE_PATH); */

	// Adding the default kernel name (mach_kernel) for kextcache.
	DT__AddProperty(chosenNode, "boot-file", sizeof(bootInfo->bootFile), bootInfo->bootFile);

#if APPLE_STYLE_EFI

	static EFI_UINT8 const BOOT_FILE_PATH[] =
	{
		0x04, 0x04, 0x50, 0x00, 0x5c, 0x00, 0x53, 0x00, 0x79, 0x00, 0x73, 0x00, 0x74, 0x00, 0x65, 0x00, 
		0x6d, 0x00, 0x5c, 0x00, 0x4c, 0x00, 0x69, 0x00, 0x62, 0x00, 0x72, 0x00, 0x61, 0x00, 0x72, 0x00,
		0x79, 0x00, 0x5c, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x53, 0x00, 0x65, 0x00,
		0x72, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x5c, 0x00, 0x62, 0x00, 
		0x6f, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x65, 0x00, 0x66, 0x00, 0x69, 0x00, 0x00, 0x00, 
		0x7f, 0xff, 0x04, 0x00
	};

	DT__AddProperty(chosenNode, "boot-file-path", sizeof(BOOT_FILE_PATH), (EFI_UINT8*) &BOOT_FILE_PATH);

	static EFI_UINT8 const BOOT_ARGS[] = { 0x00 };

	DT__AddProperty(chosenNode, "boot-args", sizeof(BOOT_ARGS), (EFI_UINT8*) &BOOT_ARGS);

	/* Adding kIOHibernateMachineSignatureKey (IOHibernatePrivate.h).
	 *
	 * This 'Hardware Signature' (offset 8 in the FACS table) is calculated by the BIOS on a best effort 
	 * basis to indicate the base hardware configuration of the system such that different base hardware 
	 * configurations  can have different hardware signature values. OSPM uses this information in waking 
	 * from an S4 state, by comparing the current hardware signature to the signature values saved in the 
	 * non-volatile sleep image. If the values are not the same, OSPM assumes that the saved non-volatile 
	 * image is from a different hardware configuration and cannot be restored.
	 */
	
	static EFI_UINT8 const MACHINE_SIGNATURE[] = { 0x00, 0x00, 0x00, 0x00 };

	DT__AddProperty(chosenNode, "machine-signature", sizeof(MACHINE_SIGNATURE), (EFI_UINT8*) &MACHINE_SIGNATURE);

#if ((MAKE_TARGET_OS & LION) == LION)

	// Used by boot.efi - cosmetic only node/properties on hacks.
	Node * kernelCompatNode = DT__AddChild(efiNode, "kernel-compatibility");

	static EFI_UINT8 const COMPAT_MODE[] = { 0x01, 0x00, 0x00, 0x00 };

	DT__AddProperty(kernelCompatNode, "i386", sizeof(COMPAT_MODE), (EFI_UINT8*) &COMPAT_MODE);
	DT__AddProperty(kernelCompatNode, "x86_64", sizeof(COMPAT_MODE), (EFI_UINT8*) &COMPAT_MODE);
#endif

	// Adding the options node breaks AppleEFINVRAM (missing hardware UUID).
	// Node *optionsNode = DT__AddChild(gPlatform.DT.RootNode, "options");
	// DT__AddProperty(optionsNode, "EFICapsuleResult", 4, "STAR"); // 53 54 41 52

#endif

	// DT__AddProperty(chosenNode, "boot-kernelcache-adler32", sizeof(uint64_t), adler32);

	gPlatform.EFI.Nodes.Chosen = chosenNode;

#if INJECT_EFI_DEVICE_PROPERTIES

	static EFI_UINT8 const EFI_DEVICE_PROPERTIES[] = 
	{
		STATIC_EFI_DEVICE_PROPERTIES
	};

	_EFI_DEBUG_DUMP("Injecting EFI device-properties\n");

	DT__AddProperty(efiNode, "device-properties", sizeof(EFI_DEVICE_PROPERTIES), (EFI_CHAR8*) &EFI_DEVICE_PROPERTIES);
#endif

	_EFI_DEBUG_DUMP("Exiting initEFITree()\n");
	_EFI_DEBUG_SLEEP(5);
}