Beispiel #1
0
static long DecodeSegment(long cmdBase)
{
  struct segment_command *segCmd;
  char   rangeName[32];
  char   *vmaddr, *fileaddr;
  long   vmsize, filesize;
  
  segCmd = (struct segment_command *)cmdBase;
  
  vmaddr = (char *)segCmd->vmaddr;
  vmsize = segCmd->vmsize;
  
  fileaddr = (char *)(gPPCAddress + segCmd->fileoff);
  filesize = segCmd->filesize;
  
#if 0
  printf("segname: %s, vmaddr: %x, vmsize: %x, fileoff: %x, filesize: %x, nsects: %d, flags: %x.\n",
	 segCmd->segname, vmaddr, vmsize, fileaddr, filesize,
	 segCmd->nsects, segCmd->flags);
#endif
  
  // Add the Segment to the memory-map.
  sprintf(rangeName, "Kernel-%s", segCmd->segname);
  AllocateMemoryRange(rangeName, (long)vmaddr, vmsize);

  if (vmsize && (strcmp(segCmd->segname, "__PRELINK") == 0))
    gHaveKernelCache = 1;
  
  // Handle special segments first.
  
  // If it is the vectors, save them in their special place.
  if ((strcmp(segCmd->segname, "__VECTORS") == 0) &&
      ((long)vmaddr < (kVectorAddr + kVectorSize)) &&
      (vmsize != 0) && (filesize != 0)) {
    
    // Copy the first part into the save area.
    bcopy(fileaddr, gVectorSaveAddr,
	  (filesize <= kVectorSize) ? filesize : kVectorSize);
    
    // Copy the rest into memory.
    if (filesize > kVectorSize)
      bcopy(fileaddr + kVectorSize, (char *)kVectorSize,
	    filesize - kVectorSize);
    
    return 0;
  }
  
  // It is nothing special, so do the usual. Only copy sections
  // that have a filesize.  Others are handle by the original bzero.
  if (filesize != 0) {
    bcopy(fileaddr, vmaddr, filesize);
  }
  
  // Adjust the last address used by the kernel
  if ((long)vmaddr + vmsize > AllocateKernelMemory(0)) {
    AllocateKernelMemory((long)vmaddr + vmsize - AllocateKernelMemory(0));
  }
  
  return 0;
}
Beispiel #2
0
void reserveKernBootStruct(void)
{
	if ( TIGER || LEOPARD || SNOW_LEOPARD )
	{
		// for 10.4 10.5 10.6
		void *oldAddr = bootArgsPreLion;
		bootArgsPreLion = (boot_args_pre_lion *)AllocateKernelMemory(sizeof(boot_args_pre_lion));
		bcopy(oldAddr, bootArgsPreLion, sizeof(boot_args_pre_lion));
	} else {
		// for 10.7 10.8 10.9 10.10
		void *oldAddr = bootArgs;
		bootArgs = (boot_args *)AllocateKernelMemory(sizeof(boot_args));
		bcopy(oldAddr, bootArgs, sizeof(boot_args));
	}
}
Beispiel #3
0
// Assumes mkext driver has been loaded to kLoadAddr already
long 
AddDriverMKext( void )
{
	long driversAddr, driversLength;
	char segName[32];

	DriversPackage *package = (DriversPackage *)kLoadAddr;

	// Verify the MKext.
	if( (package->signature1 != kDriverPackageSignature1) ||
	    (package->signature2 != kDriverPackageSignature2)) return -1;
	if( package->length > kLoadSize) return -1;
	if( package->alder32 != Alder32((unsigned char *)&package->version,
					package->length - 0x10)) return -1;

	// Make space for the MKext.
	driversLength = package->length;
	driversAddr = AllocateKernelMemory(driversLength);

	// Copy the MKext.
	memcpy((void *)driversAddr, (void *)kLoadAddr, driversLength);
	
	// Add the MKext to the memory map.
	sprintf(segName, "DriversPackage-%lx", driversAddr);
	//printm("DriversPackage-%lx\n", driversAddr);
	AllocateMemoryRange(segName, driversAddr, driversLength);
	
	return 0;
}
Beispiel #4
0
void *loadACPITable (const char * filename)
{
	void *tableAddr;
	const char * dirspec=NULL;

	int fd = search_and_get_acpi_fd(filename, &dirspec);

	if (fd>=0)
	{
		tableAddr=(void*)AllocateKernelMemory(file_size (fd));
		if (tableAddr)
		{
			if (read (fd, tableAddr, file_size (fd))!=file_size (fd))
			{
				printf("Couldn't read table %s\n",dirspec);
				free (tableAddr);
				close (fd);
				return NULL;
			}
			
			DBG("Table %s read and stored at: %x\n", dirspec, tableAddr);
			close (fd);
			return tableAddr;
		}
		close (fd);
		printf("Couldn't allocate memory for table \n", dirspec);
	}  
	//printf("Couldn't find table %s\n", filename);
	return NULL;
}
Beispiel #5
0
static long DecodeSymbolTable(long cmdBase)
{
  struct symtab_command *symTab, *symTableSave;
  long   tmpAddr, symsSize, totalSize;
  
  symTab = (struct symtab_command *)cmdBase;
  
#if 0
  printf("symoff: %x, nsyms: %x, stroff: %x, strsize: %x\n",
	 symTab->symoff, symTab->nsyms, symTab->stroff, symTab->strsize);
#endif
  
  symsSize = symTab->stroff - symTab->symoff;
  totalSize = symsSize + symTab->strsize;
  
  gSymbolTableSize = totalSize + sizeof(struct symtab_command);
  gSymbolTableAddr = AllocateKernelMemory(gSymbolTableSize);
  
  // Add the SymTab to the memory-map.
  AllocateMemoryRange("Kernel-__SYMTAB", gSymbolTableAddr, gSymbolTableSize);
  
  symTableSave = (struct symtab_command *)gSymbolTableAddr;
  tmpAddr = gSymbolTableAddr + sizeof(struct symtab_command);
  
  symTableSave->symoff = tmpAddr;
  symTableSave->nsyms = symTab->nsyms;
  symTableSave->stroff = tmpAddr + symsSize;
  symTableSave->strsize = symTab->strsize;
  
  bcopy((char *)(gPPCAddress + symTab->symoff),
	(char *)tmpAddr, totalSize);
  
  return 0;
}
Beispiel #6
0
void
reserveKernLegacyBootStruct(void)
{
    bootArgsLegacy = (boot_args_legacy *)AllocateKernelMemory(sizeof(boot_args_legacy));
    assert(bootArgsLegacy != NULL);
    bzero(bootArgsLegacy,sizeof(boot_args_legacy));
    bootArgsLegacy->Revision = bootArgs->Revision ;
    bootArgsLegacy->Version = bootArgs->Version   ;
    bcopy(bootArgs->CommandLine, bootArgsLegacy->CommandLine, BOOT_LINE_LENGTH);
    bootArgsLegacy->MemoryMap = bootArgs->MemoryMap ;
    bootArgsLegacy->MemoryMapSize = bootArgs->MemoryMapSize ;
    bootArgsLegacy->MemoryMapDescriptorSize = bootArgs->MemoryMapDescriptorSize ;
    bootArgsLegacy->MemoryMapDescriptorVersion = bootArgs->MemoryMapDescriptorVersion ;
    bootArgsLegacy->Video.v_display  = bootArgs->Video.v_display;
    bootArgsLegacy->Video.v_width    = bootArgs->Video.v_width ;
    bootArgsLegacy->Video.v_height   = bootArgs->Video.v_height;
    bootArgsLegacy->Video.v_depth    = bootArgs->Video.v_depth;
    bootArgsLegacy->Video.v_rowBytes = bootArgs->Video.v_rowBytes;
    bootArgsLegacy->Video.v_baseAddr = bootArgs->Video.v_baseAddr;
    bootArgsLegacy->deviceTreeP = bootArgs->deviceTreeP ;
    bootArgsLegacy->deviceTreeLength = bootArgs->deviceTreeLength ;
    bootArgsLegacy->kaddr = bootArgs->kaddr ;
    bootArgsLegacy->ksize = bootArgs->ksize ;
    bootArgsLegacy->efiRuntimeServicesPageStart = bootArgs->efiRuntimeServicesPageStart ;
    bootArgsLegacy->efiRuntimeServicesPageCount = bootArgs->efiRuntimeServicesPageCount ;
    bootArgsLegacy->efiSystemTable = bootArgs->efiSystemTable ;
    bootArgsLegacy->efiMode = bootArgs->efiMode ;
    bootArgsLegacy->performanceDataStart = bootArgs->performanceDataStart ;
    bootArgsLegacy->performanceDataSize = bootArgs->performanceDataSize ;
    bootArgsLegacy->efiRuntimeServicesVirtualPageStart = bootArgs->efiRuntimeServicesVirtualPageStart ;


}
Beispiel #7
0
void saveOriginalSMBIOS(void)
{
	Node *node;
	SMBEntryPoint *origeps;
	void *tableAddress;

	node = DT__FindNode("/efi/platform", false);
	if (!node)
	{
		verbose("/efi/platform node not found\n");
		return;
	}

	origeps = getSmbios(SMBIOS_ORIGINAL);
	if (!origeps)
	{
		return;
	}

	tableAddress = (void *)AllocateKernelMemory(origeps->dmi.tableLength);
	if (!tableAddress)
	{
		return;
	}

	memcpy(tableAddress, (void *)origeps->dmi.tableAddress, origeps->dmi.tableLength);
	DT__AddProperty(node, "SMBIOS", origeps->dmi.tableLength, tableAddress);
}
Beispiel #8
0
void
reserveKernBootStruct(void)
{
	if ((gMacOSVersion[0] == '1') && (gMacOSVersion[1] == '0')
		&& (gMacOSVersion[2] == '.') && ((gMacOSVersion[3] == '7') || (gMacOSVersion[3] == '8')))
	{
		void *oldAddr = bootArgs;
		bootArgs = (boot_args *)AllocateKernelMemory(sizeof(boot_args));
		bcopy(oldAddr, bootArgs, sizeof(boot_args));
	}
	else
	{
		void *oldAddr = bootArgsPreLion;
		bootArgsPreLion = (boot_args_pre_lion *)AllocateKernelMemory(sizeof(boot_args_pre_lion));
		bcopy(oldAddr, bootArgsPreLion, sizeof(boot_args_pre_lion));
	}
}
Beispiel #9
0
void
reserveKernBootStruct(void)
{
    void *oldAddr = bootArgs;
    bootArgs = (boot_args *)AllocateKernelMemory(sizeof(boot_args));
    assert(bootArgs != NULL);
    bcopy(oldAddr, bootArgs, sizeof(boot_args));

}
Beispiel #10
0
void NBI_md0Ramdisk()
{
	RAMDiskParam ramdiskPtr;
	char filename[512];
	int fh = -1;
	
	// TODO: embed NBI.img in this file
	// If runNetbookInstaller is true, then the system has changed states, patch it 
	snprintf(filename, sizeof(filename),"%s", "Extra/NetbookInstaller.img");;
	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);
				
				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);
		
	}
}
Beispiel #11
0
long
LoadDriverMKext( char * fileSpec )
{
	unsigned long    driversAddr, driversLength;
	long             length;
	char             segName[32];
	DriversPackage * package;

#define GetPackageElement(e)     OSSwapBigToHostInt32(package->e)

	// Load the MKext.
	length = LoadThinFatFile(fileSpec, (void **)&package);
	if (length < sizeof (DriversPackage)) {
		return -1;
	}

	// call hook to notify modules that the mkext has been loaded
	execute_hook("LoadDriverMKext", (void*)fileSpec, (void*)package, (void*) &length, NULL);

	
	// Verify the MKext.
	if (( GetPackageElement(signature1) != kDriverPackageSignature1) ||
		( GetPackageElement(signature2) != kDriverPackageSignature2) ||
		( GetPackageElement(length)      > kLoadSize )               ||
		( GetPackageElement(adler32)    !=
		Adler32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )
	{
		return -1;
	}

	// Make space for the MKext.
	driversLength = GetPackageElement(length);
	driversAddr   = AllocateKernelMemory(driversLength);

	// Copy the MKext.
	memcpy((void *)driversAddr, (void *)package, driversLength);

	// Add the MKext to the memory map.
	snprintf(segName, sizeof(segName), "DriversPackage-%lx", driversAddr);
	AllocateMemoryRange(segName, driversAddr, driversLength, kBootDriverTypeMKEXT);

	return 0;
}
Beispiel #12
0
static long
LoadDriverMKext( char * fileSpec )
{
    unsigned long    driversAddr, driversLength;
    long             length;
    char             segName[32];
    DriversPackage * package = (DriversPackage *)kLoadAddr;

#define GetPackageElement(e)     OSSwapBigToHostInt32(package->e)

    // Load the MKext.
    length = LoadFile(fileSpec);
    if (length == -1) return -1;

    ThinFatFile((void **)&package, &length);

    // Verify the MKext.
    if (( GetPackageElement(signature1) != kDriverPackageSignature1) ||
        ( GetPackageElement(signature2) != kDriverPackageSignature2) ||
        ( GetPackageElement(length)      > kLoadSize )               ||
        ( GetPackageElement(alder32)    !=
          Alder32((char *)&package->version, GetPackageElement(length) - 0x10) ) )
    {
        return -1;
    }

    // Make space for the MKext.
    driversLength = GetPackageElement(length);
    driversAddr   = AllocateKernelMemory(driversLength);

    // Copy the MKext.
    memcpy((void *)driversAddr, (void *)package, driversLength);

    // Add the MKext to the memory map.
    sprintf(segName, "DriversPackage-%lx", driversAddr);
    AllocateMemoryRange(segName, driversAddr, driversLength,
                        kBootDriverTypeMKEXT);

    return 0;
}
Beispiel #13
0
void
finalizeBootStruct(void)
{
	uint32_t size;
	void *addr;
	int i;
	EfiMemoryRange *memoryMap;
	MemoryRange *range;
	int memoryMapCount = bootInfo->memoryMapCount;
	
	if (memoryMapCount == 0) {
		// XXX could make a two-part map here
		stop("Unable to convert memory map into proper format\n");
	}
	
	// convert memory map to boot_args memory map
	memoryMap = (EfiMemoryRange *)AllocateKernelMemory(sizeof(EfiMemoryRange) * memoryMapCount);
	bootArgs->MemoryMap = (uint32_t)memoryMap;
	bootArgs->MemoryMapSize = sizeof(EfiMemoryRange) * memoryMapCount;
	bootArgs->MemoryMapDescriptorSize = sizeof(EfiMemoryRange);
	bootArgs->MemoryMapDescriptorVersion = 0;
	
	for (i = 0; i < memoryMapCount; i++, memoryMap++) {
		range = &bootInfo->memoryMap[i];
		switch(range->type) {
			case kMemoryRangeACPI:
				memoryMap->Type = kEfiACPIReclaimMemory;
				break;
			case kMemoryRangeNVS:
				memoryMap->Type = kEfiACPIMemoryNVS;
				break;
			case kMemoryRangeUsable:
				memoryMap->Type = kEfiConventionalMemory;
				break;
			case kMemoryRangeReserved:
			default:
				memoryMap->Type = kEfiReservedMemoryType;
				break;
		}
		memoryMap->PhysicalStart = range->base;
		memoryMap->VirtualStart = range->base;
		memoryMap->NumberOfPages = range->length >> I386_PGSHIFT;
		memoryMap->Attribute = 0;
	}
	
	// copy bootFile into device tree
	// XXX
	
	// add PCI info somehow into device tree
	// XXX
	
	// Flatten device tree
	DT__FlattenDeviceTree(0, &size);
	addr = (void *)AllocateKernelMemory(size);
	if (addr == 0) {
		stop("Couldn't allocate device tree\n");
	}
	
	DT__FlattenDeviceTree((void **)&addr, &size);
	bootArgs->deviceTreeP = (uint32_t)addr;
	bootArgs->deviceTreeLength = size;

	// Copy BootArgs values to older structure
	
	memcpy(&bootArgsPreLion->CommandLine, &bootArgs->CommandLine, BOOT_LINE_LENGTH);
	memcpy(&bootArgsPreLion->Video, &bootArgs->Video, sizeof(Boot_Video));
	
	bootArgsPreLion->MemoryMap = bootArgs->MemoryMap;
	bootArgsPreLion->MemoryMapSize = bootArgs->MemoryMapSize;
	bootArgsPreLion->MemoryMapDescriptorSize = bootArgs->MemoryMapDescriptorSize;
	bootArgsPreLion->MemoryMapDescriptorVersion = bootArgs->MemoryMapDescriptorVersion;
	
	bootArgsPreLion->deviceTreeP = bootArgs->deviceTreeP;
	bootArgsPreLion->deviceTreeLength = bootArgs->deviceTreeLength;
	
	bootArgsPreLion->kaddr = bootArgs->kaddr;
	bootArgsPreLion->ksize = bootArgs->ksize;
	
	bootArgsPreLion->efiRuntimeServicesPageStart = bootArgs->efiRuntimeServicesPageStart;
	bootArgsPreLion->efiRuntimeServicesPageCount = bootArgs->efiRuntimeServicesPageCount;
	bootArgsPreLion->efiSystemTable = bootArgs->efiSystemTable;
	
	bootArgsPreLion->efiMode = bootArgs->efiMode;
	
	bootArgsPreLion->performanceDataStart = bootArgs->performanceDataStart;
	bootArgsPreLion->performanceDataSize = bootArgs->performanceDataSize;
	bootArgsPreLion->efiRuntimeServicesVirtualPageStart = bootArgs->efiRuntimeServicesVirtualPageStart;
}
Beispiel #14
0
static long
LoadMatchedModules( void )
{
    TagPtr        prop;
    ModulePtr     module;
    char          *fileName, segName[32];
    DriverInfoPtr driver;
    long          length, driverAddr, driverLength;
    void          *driverModuleAddr = 0;

  
    module = gModuleHead;

    while (module != 0)
    {
        if (module->willLoad)
        {
            prop = XMLGetProperty(module->dict, kPropCFBundleExecutable);

            if (prop != 0)
            {
                fileName = prop->string;
                sprintf(gFileSpec, "%s%s", module->driverPath, fileName);
                length = LoadThinFatFile(gFileSpec, &driverModuleAddr);
                //length = LoadFile(gFileSpec);
                //driverModuleAddr = (void *)kLoadAddr;
                //printf("%s length = %d addr = 0x%x\n", gFileSpec, length, driverModuleAddr); getc();
            }
            else
                length = 0;

            if (length != -1)
            {
		//driverModuleAddr = (void *)kLoadAddr;
                //if (length != 0)
                //{
		//    ThinFatFile(&driverModuleAddr, &length);
		//}

                // Make make in the image area.
                driverLength = sizeof(DriverInfo) + module->plistLength + length;
                driverAddr = AllocateKernelMemory(driverLength);

                // Set up the DriverInfo.
                driver = (DriverInfoPtr)driverAddr;
                driver->plistAddr = (char *)(driverAddr + sizeof(DriverInfo));
                driver->plistLength = module->plistLength;
                if (length != 0)
                {
                    driver->moduleAddr = (void *)(driverAddr + sizeof(DriverInfo) +
					                     module->plistLength);
                    driver->moduleLength = length;
                }
                else
                {
                    driver->moduleAddr   = 0;
                    driver->moduleLength = 0;
                }

                // Save the plist and module.
                strcpy(driver->plistAddr, module->plistAddr);
                if (length != 0)
                {
                    memcpy(driver->moduleAddr, driverModuleAddr, length);
                }

                // Add an entry to the memory map.
                sprintf(segName, "Driver-%lx", (unsigned long)driver);
                AllocateMemoryRange(segName, driverAddr, driverLength,
                                    kBootDriverTypeKEXT);
            }
        }
        module = module->nextModule;
    }

    return 0;
}
Beispiel #15
0
void setupEfiTables64(void)
{
	struct fake_efi_pages
	{
		EFI_SYSTEM_TABLE_64 efiSystemTable;
		EFI_RUNTIME_SERVICES_64 efiRuntimeServices;
		EFI_CONFIGURATION_TABLE_64 efiConfigurationTable[MAX_CONFIGURATION_TABLE_ENTRIES];
		EFI_CHAR16 firmwareVendor[sizeof(FIRMWARE_VENDOR)/sizeof(EFI_CHAR16)];
		uint8_t voidret_instructions[sizeof(VOIDRET_INSTRUCTIONS)/sizeof(uint8_t)];
		uint8_t unsupportedret_instructions[sizeof(UNSUPPORTEDRET_INSTRUCTIONS)/sizeof(uint8_t)];
	};
	
	struct fake_efi_pages *fakeEfiPages = (struct fake_efi_pages*)AllocateKernelMemory(sizeof(struct fake_efi_pages));
	
	// Zero out all the tables in case fields are added later
	bzero(fakeEfiPages, sizeof(struct fake_efi_pages));
	
	// --------------------------------------------------------------------
	// Initialize some machine code that will return EFI_UNSUPPORTED for
	// functions returning int and simply return for void functions.
	memcpy(fakeEfiPages->voidret_instructions, VOIDRET_INSTRUCTIONS, sizeof(VOIDRET_INSTRUCTIONS));
	memcpy(fakeEfiPages->unsupportedret_instructions, UNSUPPORTEDRET_INSTRUCTIONS, sizeof(UNSUPPORTEDRET_INSTRUCTIONS));
	
	// --------------------------------------------------------------------
	// System table
	EFI_SYSTEM_TABLE_64 *efiSystemTable = gST64 = &fakeEfiPages->efiSystemTable;
	efiSystemTable->Hdr.Signature = EFI_SYSTEM_TABLE_SIGNATURE;
	efiSystemTable->Hdr.Revision = EFI_SYSTEM_TABLE_REVISION;
	efiSystemTable->Hdr.HeaderSize = sizeof(EFI_SYSTEM_TABLE_64);
	efiSystemTable->Hdr.CRC32 = 0; // Initialize to zero and then do CRC32
	efiSystemTable->Hdr.Reserved = 0;
	
	efiSystemTable->FirmwareVendor = ptov64((EFI_PTR32)&fakeEfiPages->firmwareVendor);
	memcpy(fakeEfiPages->firmwareVendor, FIRMWARE_VENDOR, sizeof(FIRMWARE_VENDOR));
	efiSystemTable->FirmwareRevision = FIRMWARE_REVISION;
	
	// XXX: We may need to have basic implementations of ConIn/ConOut/StdErr
	// The EFI spec states that all handles are invalid after boot services have been
	// exited so we can probably get by with leaving the handles as zero.
	efiSystemTable->ConsoleInHandle = 0;
	efiSystemTable->ConIn = 0;
	
	efiSystemTable->ConsoleOutHandle = 0;
	efiSystemTable->ConOut = 0;
	
	efiSystemTable->StandardErrorHandle = 0;
	efiSystemTable->StdErr = 0;
	
	efiSystemTable->RuntimeServices = ptov64((EFI_PTR32)&fakeEfiPages->efiRuntimeServices);
	// According to the EFI spec, BootServices aren't valid after the
	// boot process is exited so we can probably do without it.
	// Apple didn't provide a definition for it in pexpert/i386/efi.h
	// so I'm guessing they don't use it.
	efiSystemTable->BootServices = 0;
	
	efiSystemTable->NumberOfTableEntries = 0;
	efiSystemTable->ConfigurationTable = ptov64((EFI_PTR32)fakeEfiPages->efiConfigurationTable);
	
	// We're done.	Now CRC32 the thing so the kernel will accept it
	gST64->Hdr.CRC32 = crc32(0L, gST64, gST64->Hdr.HeaderSize);
	
	// --------------------------------------------------------------------
	// Runtime services
	EFI_RUNTIME_SERVICES_64 *efiRuntimeServices = &fakeEfiPages->efiRuntimeServices;
	efiRuntimeServices->Hdr.Signature = EFI_RUNTIME_SERVICES_SIGNATURE;
	efiRuntimeServices->Hdr.Revision = EFI_RUNTIME_SERVICES_REVISION;
	efiRuntimeServices->Hdr.HeaderSize = sizeof(EFI_RUNTIME_SERVICES_64);
	efiRuntimeServices->Hdr.CRC32 = 0;
	efiRuntimeServices->Hdr.Reserved = 0;
	
	// There are a number of function pointers in the efiRuntimeServices table.
	// These are the Foundation (e.g. core) services and are expected to be present on
	// all EFI-compliant machines.	Some kernel extensions (notably AppleEFIRuntime)
	// will call these without checking to see if they are null.
	//
	// We don't really feel like doing an EFI implementation in the bootloader
	// but it is nice if we can at least prevent a complete crash by
	// at least providing some sort of implementation until one can be provided
	// nicely in a kext.
	
	void (*voidret_fp)() = (void*)fakeEfiPages->voidret_instructions;
	void (*unsupportedret_fp)() = (void*)fakeEfiPages->unsupportedret_instructions;
	efiRuntimeServices->GetTime = ptov64((EFI_PTR32)unsupportedret_fp);
	efiRuntimeServices->SetTime = ptov64((EFI_PTR32)unsupportedret_fp);
	efiRuntimeServices->GetWakeupTime = ptov64((EFI_PTR32)unsupportedret_fp);
	efiRuntimeServices->SetWakeupTime = ptov64((EFI_PTR32)unsupportedret_fp);
	efiRuntimeServices->SetVirtualAddressMap = ptov64((EFI_PTR32)unsupportedret_fp);
	efiRuntimeServices->ConvertPointer = ptov64((EFI_PTR32)unsupportedret_fp);
	efiRuntimeServices->GetVariable = ptov64((EFI_PTR32)unsupportedret_fp);
	efiRuntimeServices->GetNextVariableName = ptov64((EFI_PTR32)unsupportedret_fp);
	efiRuntimeServices->SetVariable = ptov64((EFI_PTR32)unsupportedret_fp);
	efiRuntimeServices->GetNextHighMonotonicCount = ptov64((EFI_PTR32)unsupportedret_fp);
	efiRuntimeServices->ResetSystem = ptov64((EFI_PTR32)voidret_fp);
	
	// We're done.	Now CRC32 the thing so the kernel will accept it
	efiRuntimeServices->Hdr.CRC32 = crc32(0L, efiRuntimeServices, efiRuntimeServices->Hdr.HeaderSize);
	
	// --------------------------------------------------------------------
	// Finish filling in the rest of the boot args that we need.
	bootArgs->efiSystemTable = (uint32_t)efiSystemTable;
	bootArgs->efiMode = kBootArgsEfiMode64;
	
	// The bootArgs structure as a whole is bzero'd so we don't need to fill in
	// things like efiRuntimeServices* and what not.
	//
	// In fact, the only code that seems to use that is the hibernate code so it
	// knows not to save the pages.	 It even checks to make sure its nonzero.
}
Beispiel #16
0
void
smbios_real_run (struct SMBEntryPoint * origsmbios,
				 struct SMBEntryPoint * newsmbios)
{
	char *smbiostables=0;
	char *tablesptr, *newtablesptr;
	int origsmbiosnum=0;
	// bitmask of used handles
	uint8_t handles[8192]; 
	uint16_t nexthandle=0;
	int i, j;
	int tablespresent[256];
	BOOL do_auto=1;
	
	getBoolForKey("SMBIOSdefaults",&do_auto,&bootInfo->bootConfig);
	
	for (i=0;i<256;i++)
		tablespresent[i]=0;
	
	memset (handles,0,8192);
	newsmbios->dmi.tableAddress=(uint32_t)AllocateKernelMemory(newsmbios->dmi.tableLength);
	if (origsmbios)
    {
		smbiostables=(char *) origsmbios->dmi.tableAddress;
		origsmbiosnum=origsmbios->dmi.structureCount;
    }
	tablesptr=smbiostables;
	newtablesptr=(char *) newsmbios->dmi.tableAddress;
	if (smbiostables)
		for (i=0;i<origsmbiosnum;i++)
		{
			struct smbios_table_header *oldcur
			=(struct smbios_table_header *) tablesptr,
			*newcur=(struct smbios_table_header *) newtablesptr;
			char *stringsptr;
			int nstrings=0;
			
			handles[(oldcur->handle)/8]|=1<<((oldcur->handle)%8);
			
			memcpy (newcur,oldcur, oldcur->length);
			
			tablesptr+=oldcur->length;
			stringsptr=tablesptr;
			newtablesptr+=oldcur->length;
			for (;tablesptr[0]!=0 || tablesptr[1]!=0;tablesptr++)
				if (tablesptr[0]==0)
					nstrings++;
			if (tablesptr!=stringsptr)
				nstrings++;
			tablesptr+=2;
			memcpy (newtablesptr,stringsptr,tablesptr-stringsptr);
			//point to next possible space for a string
			newtablesptr+=tablesptr-stringsptr-1;
			if (nstrings==0)
				newtablesptr--;
			for (j=0;j<sizeof (smbios_properties)/sizeof(smbios_properties[0]);
				 j++)
			{
				const char *str;
				int size;
				int num;
				char altname[40];
				sprintf (altname, "%s_%d",smbios_properties[j].name,
						 tablespresent[newcur->type]+1);				
				
				if (smbios_properties[j].table_type==newcur->type)
					switch (smbios_properties[j].value_type)
				{
					case SMSTRING:
						if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
							||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
						{
							memcpy (newtablesptr, str,size);
							newtablesptr[size]=0;
							newtablesptr+=size+1;
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
						}
						else if (do_auto && smbios_properties[j].auto_str)
						{
							str=smbios_properties[j].auto_str(smbios_properties[j].name,tablespresent[newcur->type]);
							size=strlen (str);
							memcpy (newtablesptr, str,size);
							newtablesptr[size]=0;
							newtablesptr+=size+1;
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
						}
						
						break;
						
					case SMOWORD:
						if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
							||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
						{
							int k=0, t=0, kk=0;
							const char *ptr=str;
							memset(((char*)newcur)+smbios_properties[j].offset, 0, 16);
							while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n'))
								ptr++;
							if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X'))
								ptr+=2;
							for (;ptr-str<size && *ptr && k<16;ptr++)
							{
								if (*ptr>='0' && *ptr<='9')
									(t=(t<<4)|(*ptr-'0')),kk++;
								if (*ptr>='a' && *ptr<='f')
									(t=(t<<4)|(*ptr-'a'+10)),kk++;
								if (*ptr>='A' && *ptr<='F')
									(t=(t<<4)|(*ptr-'A'+10)),kk++;
								if (kk==2)
								{
									*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset+k))=t;
									k++;
									kk=0;
									t=0;
								}
							}
						}
						break;
						
					case SMBYTE:
						if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
							||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
						else if (do_auto && smbios_properties[j].auto_int)
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))
							=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);							
						break;
						
					case SMWORD:
						if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
							||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
							*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
						else if (do_auto && smbios_properties[j].auto_int)
							*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))
							=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						break;
				}
			}
			if (nstrings==0)
			{
				newtablesptr[0]=0;
				newtablesptr++;
			}
			newtablesptr[0]=0;
			newtablesptr++;
			tablespresent[newcur->type]++;
		}
	for (i=0;i<sizeof (smbios_table_descriptions)
		 /sizeof(smbios_table_descriptions[0]);i++)
	{
		int numnec=-1;
		char buffer[40];
		sprintf (buffer, "SMtable%d", i);
		if (!getIntForKey(buffer,&numnec,&bootInfo->smbiosConfig))
			numnec=-1;
		if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc)
			numnec=smbios_table_descriptions[i].numfunc (smbios_table_descriptions[i].type);
		
		while (tablespresent[smbios_table_descriptions[i].type]<numnec)
		{
			struct smbios_table_header *newcur=(struct smbios_table_header *) newtablesptr;
			int nstrings=0;
			
			memset (newcur,0, smbios_table_descriptions[i].len);
			while (handles[(nexthandle)/8]&(1<<((nexthandle)%8)))
				nexthandle++;
			newcur->handle=nexthandle;
			handles[nexthandle/8]|=1<<(nexthandle%8);
			newcur->type=smbios_table_descriptions[i].type;
			newcur->length=smbios_table_descriptions[i].len;
			newtablesptr+=smbios_table_descriptions[i].len;
			for (j=0;j<sizeof (smbios_properties)/sizeof(smbios_properties[0]);
				 j++)
			{
				const char *str;
				int size;
				int num;
				char altname[40];
				sprintf (altname, "%s_%d",smbios_properties[j].name,
						 tablespresent[newcur->type]+1);				
				
				if (smbios_properties[j].table_type==newcur->type)
					switch (smbios_properties[j].value_type)
				{
					case SMSTRING:
						if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
							||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
						{
							memcpy (newtablesptr, str,size);
							newtablesptr[size]=0;
							newtablesptr+=size+1;
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
						}
						else if (do_auto && smbios_properties[j].auto_str)
						{
							str=smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
							size=strlen (str);
							memcpy (newtablesptr, str,size);
							newtablesptr[size]=0;
							newtablesptr+=size+1;
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
						}						
						break;
						
					case SMOWORD:
						if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
							||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
						{
							int k=0, t=0, kk=0;
							const char *ptr=str;
							memset(((char*)newcur)+smbios_properties[j].offset, 0, 16);
							while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n'))
								ptr++;
							if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X'))
								ptr+=2;
							for (;ptr-str<size && *ptr && k<16;ptr++)
							{
								if (*ptr>='0' && *ptr<='9')
									(t=(t<<4)|(*ptr-'0')),kk++;
								if (*ptr>='a' && *ptr<='f')
									(t=(t<<4)|(*ptr-'a'+10)),kk++;
								if (*ptr>='A' && *ptr<='F')
									(t=(t<<4)|(*ptr-'A'+10)),kk++;
								if (kk==2)
								{
									*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset+k))=t;
									k++;
									kk=0;
									t=0;
								}
							}
						}
						break;
						
					case SMBYTE:
						if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
							||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
						else if (do_auto && smbios_properties[j].auto_int)
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))
							=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						break;
						
					case SMWORD:
						if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
							||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
							*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
						else if (do_auto && smbios_properties[j].auto_int)
							*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))
							=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						break;
				}
			}
			if (nstrings==0)
			{
				newtablesptr[0]=0;
				newtablesptr++;
			}
			newtablesptr[0]=0;
			newtablesptr++;
			tablespresent[smbios_table_descriptions[i].type]++;
		}
	}
	newsmbios->dmi.checksum=0;
	newsmbios->dmi.checksum=256-checksum8 (&newsmbios->dmi,sizeof (newsmbios->dmi));
	newsmbios->checksum=0;
	newsmbios->checksum=256-checksum8 (newsmbios,sizeof (*newsmbios));
	verbose("Patched DMI Table.\n");
}
Beispiel #17
0
/* Compute necessary space requirements for new smbios */
struct SMBEntryPoint *
smbios_dry_run (struct SMBEntryPoint * origsmbios)
{
	struct SMBEntryPoint *ret;
	char *smbiostables=0;
	char *tablesptr;
	int origsmbiosnum=0;
	int i, j;
	int tablespresent[256];
	BOOL do_auto=1;

	getBoolForKey("SMBIOSdefaults",&do_auto,&bootInfo->bootConfig);

	for (i=0;i<256;i++)
		tablespresent[i]=0;
	ret=(struct SMBEntryPoint *)AllocateKernelMemory(sizeof (struct SMBEntryPoint));
	if (origsmbios)
	{
		smbiostables=(char *)origsmbios->dmi.tableAddress;
		origsmbiosnum=origsmbios->dmi.structureCount;
    }
	// _SM_
	ret->anchor[0]=0x5f;
	ret->anchor[1]=0x53;
	ret->anchor[2]=0x4d;
	ret->anchor[3]=0x5f; 
	ret->entryPointLength=sizeof (*ret);
	ret->majorVersion=2;
	ret->minorVersion=1;
	ret->maxStructureSize=0; 
	ret->entryPointRevision=0;
	for (i=0;i<5;i++)
		ret->formattedArea[i]=0;
	//_DMI_
	ret->dmi.anchor[0]=0x5f;
	ret->dmi.anchor[1]=0x44;
	ret->dmi.anchor[2]=0x4d;
	ret->dmi.anchor[3]=0x49;
	ret->dmi.anchor[4]=0x5f;
	ret->dmi.tableLength=0; 
	ret->dmi.tableAddress=0; 
	ret->dmi.structureCount=0; 
	ret->dmi.bcdRevision=0x21;
	tablesptr=smbiostables;
	if (smbiostables)
		for (i=0;i<origsmbiosnum;i++)
		{
			struct smbios_table_header *cur
			=(struct smbios_table_header *) tablesptr;
			char *stringsptr;
			int stringlen;
			tablesptr+=cur->length;
			stringsptr=tablesptr;
			for (;tablesptr[0]!=0 || tablesptr[1]!=0;tablesptr++);
			tablesptr+=2;
			stringlen=tablesptr-stringsptr-1;
			if (stringlen==1)
				stringlen=0;
			for (j=0;j<sizeof (smbios_properties)/sizeof(smbios_properties[0]);
				 j++)
			{
				const char *str;
				int size;
				char altname[40];
				sprintf (altname, "%s_%d",smbios_properties[j].name,
						 tablespresent[cur->type]+1);				
				if (smbios_properties[j].table_type==cur->type 
					&& smbios_properties[j].value_type==SMSTRING
					&& (getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)
					    || getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)))
					stringlen+=size+1;
				else if (smbios_properties[j].table_type==cur->type 
						 && smbios_properties[j].value_type==SMSTRING
						 && do_auto && smbios_properties[j].auto_str)
					stringlen+=strlen(smbios_properties[j].auto_str(smbios_properties[j].name,tablespresent[cur->type]))+1;
			}
			if (stringlen==0)
				stringlen=1;
			stringlen++;
			if (ret->maxStructureSize<cur->length+stringlen)
				ret->maxStructureSize=cur->length+stringlen;
			ret->dmi.tableLength+=cur->length+stringlen;
			ret->dmi.structureCount++;
			tablespresent[cur->type]++;
		}
	for (i=0;i<sizeof (smbios_table_descriptions)
		 /sizeof(smbios_table_descriptions[0]);i++)
	{
		int numnec=-1;
		char buffer[40];
		sprintf (buffer, "SMtable%d", i);
		if (!getIntForKey(buffer,&numnec,&bootInfo->smbiosConfig))
			numnec=-1;
		if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc)
			numnec=smbios_table_descriptions[i].numfunc (smbios_table_descriptions[i].type);
		
		while (tablespresent[smbios_table_descriptions[i].type]<numnec)
		{
			int stringlen=0;
			for (j=0;j<sizeof (smbios_properties)/sizeof(smbios_properties[0]);
				 j++)
			{
				const char *str;
				int size;
				char altname[40];
				sprintf (altname, "%s_%d",smbios_properties[j].name,
						 tablespresent[smbios_table_descriptions[i].type]+1);
				if (smbios_properties[j].table_type
					==smbios_table_descriptions[i].type 
					&& smbios_properties[j].value_type==SMSTRING
					&& (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
						|| getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig)))
					stringlen+=size+1; 
				else if (smbios_properties[j].table_type
						 ==smbios_table_descriptions[i].type 
						 && smbios_properties[j].value_type==SMSTRING
						 && do_auto && smbios_properties[j].auto_str)
					stringlen+=strlen(smbios_properties[j].auto_str
									  (smbios_properties[j].name,
									   tablespresent[smbios_table_descriptions[i].type]))+1;
			}
			if (stringlen==0)
				stringlen=1;
			stringlen++;
			if (ret->maxStructureSize<smbios_table_descriptions[i].len+stringlen)
				ret->maxStructureSize=smbios_table_descriptions[i].len+stringlen;
			ret->dmi.tableLength+=smbios_table_descriptions[i].len+stringlen;
			ret->dmi.structureCount++;
			tablespresent[smbios_table_descriptions[i].type]++;
		}
	}
	return ret;
}
Beispiel #18
0
long DecodeMachO(void *binary)
{
  struct mach_header *mH;
  long   ncmds, cmdBase, cmd, cmdsize, headerBase, headerAddr, headerSize;
  long   cnt, ret = 0;
  
  gPPCAddress = (unsigned long)binary;
  
  headerBase = gPPCAddress;
  cmdBase = headerBase + sizeof(struct mach_header);
  
  mH = (struct mach_header *)(headerBase);
  if (mH->magic != MH_MAGIC) return -1;
  
#if 0
  printf("magic:      %x\n", mH->magic);
  printf("cputype:    %x\n", mH->cputype);
  printf("cpusubtype: %x\n", mH->cpusubtype);
  printf("filetype:   %x\n", mH->filetype);
  printf("ncmds:      %x\n", mH->ncmds);
  printf("sizeofcmds: %x\n", mH->sizeofcmds);
  printf("flags:      %x\n", mH->flags);
#endif
  
  ncmds = mH->ncmds;
  
  for (cnt = 0; cnt < ncmds; cnt++) {
    cmd = ((long *)cmdBase)[0];
    cmdsize = ((long *)cmdBase)[1];
    
    switch (cmd) {
      
    case LC_SEGMENT:
      ret = DecodeSegment(cmdBase);
      break;
      
    case LC_UNIXTHREAD:
      ret = DecodeUnixThread(cmdBase);
      break;
      
    case LC_SYMTAB:
      ret = DecodeSymbolTable(cmdBase);
      break;
      
    default:
      printf("Ignoring cmd type %d.\n", cmd);
      break;
    }
    
    if (ret != 0) return -1;
    
    cmdBase += cmdsize;
  }
  
  // Save the mach-o header.
  headerSize = cmdBase - headerBase;
  headerAddr = AllocateKernelMemory(headerSize);
  bcopy((char *)headerBase, (char *)headerAddr, headerSize);
  
  // Add the Mach-o header to the memory-map.
  AllocateMemoryRange("Kernel-__HEADER", headerAddr, headerSize);
  
  return ret;
}
Beispiel #19
0
void
finalizeBootStruct(void)
{
    {
        int i;
        EfiMemoryRange *kMemoryMap = NULL;
        MemoryRange *range = NULL;

        uint64_t	sane_size = 0;  /* Memory size to use for defaults calculations */

        unsigned long memoryMapCount = (unsigned long)get_env(envMemoryMapCnt);

        if (memoryMapCount == 0) {

            // XXX could make a two-part map here
            stop("No memory map found\n");
            return;
        }



        // convert memory map to boot_args memory map
        kMemoryMap = (EfiMemoryRange *)AllocateKernelMemory(sizeof(EfiMemoryRange) * memoryMapCount);
        if (kMemoryMap == NULL) {

            stop("Unable to allocate kernel space for the memory map\n");
            return;
        }
        bootArgs->MemoryMap = (uint32_t)kMemoryMap;
        bootArgs->MemoryMapSize = sizeof(EfiMemoryRange) * memoryMapCount;
        bootArgs->MemoryMapDescriptorSize = sizeof(EfiMemoryRange);
        bootArgs->MemoryMapDescriptorVersion = 0;

        for (i=0; i<memoryMapCount; i++, kMemoryMap++) {
            range = &memoryMap[i];
            if (!range || !kMemoryMap) {
                stop("Error while computing kernel memory map\n");
                return;
            }
            switch(range->type) {
            case kMemoryRangeACPI:
                kMemoryMap->Type = kEfiACPIReclaimMemory;
                break;
            case kMemoryRangeNVS:
                kMemoryMap->Type = kEfiACPIMemoryNVS;
                break;
            case kMemoryRangeUsable:
                kMemoryMap->Type = kEfiConventionalMemory;
                break;
            case kMemoryRangeReserved:
            default:
                kMemoryMap->Type = kEfiReservedMemoryType;
                break;
            }
            kMemoryMap->PhysicalStart = range->base;
            kMemoryMap->VirtualStart = range->base;
            kMemoryMap->NumberOfPages = range->length >> I386_PGSHIFT;
            kMemoryMap->Attribute = 0;

            switch (kMemoryMap->Type) {
            case kEfiLoaderCode:
            case kEfiLoaderData:
            case kEfiBootServicesCode:
            case kEfiBootServicesData:
            case kEfiConventionalMemory:
                /*
                 * Consolidate usable memory types into one.
                 */
                sane_size += (uint64_t)(kMemoryMap->NumberOfPages << I386_PGSHIFT);
                break;

            case kEfiRuntimeServicesCode:
            case kEfiRuntimeServicesData:
            case kEfiACPIReclaimMemory:
            case kEfiACPIMemoryNVS:
            case kEfiPalCode:
                /*
                 * sane_size should reflect the total amount of physical ram
                 * in the system, not just the amount that is available for
                 * the OS to use
                 */
                sane_size += (uint64_t)(kMemoryMap->NumberOfPages << I386_PGSHIFT);
                break;
            default:
                break;

            }
        }

        if (sane_size == 0) {

            // I Guess that if sane_size == 0 we've got a big problem here,
            // and it means that the memory map was not converted properly
            stop("Unable to convert memory map into proper format\n");
            return;
        }

#define MEG		(1024*1024)

        /*
         * For user visible memory size, round up to 128 Mb - accounting for the various stolen memory
         * not reported by EFI.
         */

        sane_size = (sane_size + 128 * MEG - 1) & ~((uint64_t)(128 * MEG - 1));
        bootArgs->PhysicalMemorySize = sane_size;
        bootArgs->FSBFrequency = get_env(envFSBFreq);

    }


    {
        uint32_t size;
        void *addr;
        // Flatten device tree
        DT__FlattenDeviceTree(0, &size);
        addr = (void *)AllocateKernelMemory(size);
        if (addr == 0) {
            stop("Couldn't allocate device tree\n");
            return;
        }

        DT__FlattenDeviceTree((void **)&addr, &size);
        if (!size) {
            stop("Couldn't get flatten device tree\n");
            return;
        }
        bootArgs->deviceTreeP = (uint32_t)addr;
        bootArgs->deviceTreeLength = size;
    }

}
Beispiel #20
0
static int loadMultiKext(char * path)
{
	char fileName[] = "Extensions.mkext";
	long flags, time;

	strcat(path, "/");
	
	_DRIVERS_DEBUG_DUMP("\nloadMultiKext: %s%s\n", path, fileName);

	long ret = GetFileInfo(path, fileName, &flags, &time);
	
	// Pre-flight checks; Does the file exists, and is it something we can use?
	if ((ret == STATE_SUCCESS) && ((flags & kFileTypeMask) == kFileTypeFlat))
	{
		unsigned long    driversAddr, driversLength;
		char             segName[32];
		DriversPackage * package;

		char mkextSpec[80];
		sprintf(mkextSpec, "%s%s", path, fileName);

		// Load the MKext.
		long length = LoadThinFatFile(mkextSpec, (void **)&package);

		if (length < sizeof(DriversPackage))
		{
			_DRIVERS_DEBUG_DUMP("loadMultiKext(Load Failure : -2)\n");

			return -2;
		}

		// Handy little macro (_GET_PackageElement).
		#define _GET_PE(e)	OSSwapBigToHostInt32(package->e)

		#if DEBUG_DRIVERS
			printf("\nsignature1: 0x%x\n",	_GET_PE(signature1));
			printf("signature2: 0x%x\n",	_GET_PE(signature2));
			printf("length    : %ld\n",		_GET_PE(length));
			printf("adler32   : 0x%x\n",	_GET_PE(adler32));
			printf("numDrivers: %ld\n",		_GET_PE(numDrivers));
		#endif

		// Check the MKext header.
		if ((_GET_PE(signature1) != kDriverPackageSignature1)	||
			(_GET_PE(signature2) != kDriverPackageSignature2)	||
			(_GET_PE(length)      > kLoadSize)					||
			(_GET_PE(adler32)    !=
			 localAdler32((unsigned char *)&package->version, _GET_PE(length) - 0x10)))
		{
			_DRIVERS_DEBUG_DUMP("loadMultiKext(Verification Error : -3)\n");
	
			return -3;
		}

		// Make space for the MKext.
		driversLength = _GET_PE(length);
		driversAddr   = AllocateKernelMemory(driversLength);

		// Copy the MKext.
		memcpy((void *)driversAddr, (void *)package, driversLength);
		bzero((void *)package, driversLength);

		// Add the MKext to the memory map.
		sprintf(segName, "DriversPackage-%lx", driversAddr);
		AllocateMemoryRange(segName, driversAddr, driversLength, kBootDriverTypeMKEXT);

		_DRIVERS_DEBUG_DUMP("loadMultiKext(Success : 0) @ 0x%08x\n", driversAddr);

		return STATE_SUCCESS;
	}

	_DRIVERS_DEBUG_DUMP("loadMultiKext(File Not Found Error: -1)\n");

	return -1;
}
Beispiel #21
0
/** Compute necessary space requirements for new smbios */
static struct SMBEntryPoint *smbios_dry_run(struct SMBEntryPoint *origsmbios)
{
	struct SMBEntryPoint	*ret;
	char			*smbiostables;
	char			*tablesptr;
	int			origsmbiosnum;
	int			i, j;
	int			tablespresent[256];
	bool			do_auto=true;

	bzero(tablespresent, sizeof(tablespresent));

	getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);

	ret = (struct SMBEntryPoint *)AllocateKernelMemory(sizeof(struct SMBEntryPoint));
	if (origsmbios) {
		smbiostables = (char *)origsmbios->dmi.tableAddress;
		origsmbiosnum = origsmbios->dmi.structureCount;
	} else {
		smbiostables = NULL;
		origsmbiosnum = 0;
	}

	// _SM_
	ret->anchor[0] = 0x5f;
	ret->anchor[1] = 0x53;
	ret->anchor[2] = 0x4d;
	ret->anchor[3] = 0x5f; 
	ret->entryPointLength = sizeof(*ret);
	ret->majorVersion = 2;
	ret->minorVersion = 1;
	ret->maxStructureSize = 0; // will be calculated later in this function
	ret->entryPointRevision = 0;
	for (i=0;i<5;i++) {
		ret->formattedArea[i] = 0;
	}
	//_DMI_
	ret->dmi.anchor[0] = 0x5f;
	ret->dmi.anchor[1] = 0x44;
	ret->dmi.anchor[2] = 0x4d;
	ret->dmi.anchor[3] = 0x49;
	ret->dmi.anchor[4] = 0x5f;
	ret->dmi.tableLength = 0;  // will be calculated later in this function
	ret->dmi.tableAddress = 0; // will be initialized in smbios_real_run()
	ret->dmi.structureCount = 0; // will be calculated later in this function
	ret->dmi.bcdRevision = 0x21;
	tablesptr = smbiostables;

        // add stringlen of overrides to original stringlen, update maxStructure size adequately, 
        // update structure count and tablepresent[type] with count of type. 
	if (smbiostables) {
		for (i=0; i<origsmbiosnum; i++) {
			struct smbios_table_header	*cur = (struct smbios_table_header *)tablesptr;
			char				*stringsptr;
			int				stringlen;

			tablesptr += cur->length;
			stringsptr = tablesptr;
			for (; tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++);
			tablesptr += 2;
			stringlen = tablesptr - stringsptr - 1;
			if (stringlen == 1) {
				stringlen = 0;
			}
			for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
				const char	*str;
				int		size;
				char		altname[40];

				sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[cur->type] + 1);				
				if (smbios_properties[j].table_type == cur->type &&
				    smbios_properties[j].value_type == SMSTRING &&
				    (getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig) ||
				     getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)))
				{
					stringlen += size + 1;
				} else if (smbios_properties[j].table_type == cur->type &&
				           smbios_properties[j].value_type == SMSTRING &&
				           do_auto && smbios_properties[j].auto_str)
				{
					stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[cur->type])) + 1;
				}
			}
			if (stringlen == 0) {
				stringlen = 1;
			}
			stringlen++;
			if (ret->maxStructureSize < cur->length+stringlen) {
				ret->maxStructureSize=cur->length+stringlen;
			}
			ret->dmi.tableLength += cur->length+stringlen;
			ret->dmi.structureCount++;
			tablespresent[cur->type]++;
		}
	}
        // Add eventually table types whose detected count would be < required count, and update ret header with:
        // new stringlen addons, structure count, and tablepresent[type] count adequately
	for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
		int	numnec=-1;
		char	buffer[40];

		sprintf(buffer, "SMtable%d", i);
		if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {
			numnec = -1;
		}
		if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc) {
			numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);
		}
		while (tablespresent[smbios_table_descriptions[i].type] < numnec) {
			int	stringlen = 0;
			for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
				const char	*str;
				int		size;
				char		altname[40];

				sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type] + 1);
				if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&
				    smbios_properties[j].value_type == SMSTRING &&
				    (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
				     getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)))
				{
					stringlen += size + 1;
				} else if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&
				           smbios_properties[j].value_type==SMSTRING &&
				           do_auto && smbios_properties[j].auto_str)
				{
					stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type])) + 1;
				}
			}
			if (stringlen == 0) {
				stringlen = 1;
			}
			stringlen++;
			if (ret->maxStructureSize < smbios_table_descriptions[i].len+stringlen) {
				ret->maxStructureSize = smbios_table_descriptions[i].len + stringlen;
			}
			ret->dmi.tableLength += smbios_table_descriptions[i].len + stringlen;
			ret->dmi.structureCount++;
			tablespresent[smbios_table_descriptions[i].type]++;
		}
	}
	return ret;
}
Beispiel #22
0
/** From the origsmbios detected by getAddressOfSmbiosTable() to newsmbios whose entrypoint 
 * struct has been created by smbios_dry_run, update each table struct content of new smbios
 * int the new allocated table address of size newsmbios->tablelength.
 */
static void smbios_real_run(struct SMBEntryPoint * origsmbios, struct SMBEntryPoint * newsmbios)
{
	char *smbiostables;
	char *tablesptr, *newtablesptr;
	int origsmbiosnum;
	// bitmask of used handles
	uint8_t handles[8192]; 
	uint16_t nexthandle=0;
	int i, j;
	int tablespresent[256];
	bool do_auto=true;
        
        extern void dumpPhysAddr(const char * title, void * a, int len);

	bzero(tablespresent, sizeof(tablespresent));
	bzero(handles, sizeof(handles));

	getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);
	
	newsmbios->dmi.tableAddress = (uint32_t)AllocateKernelMemory(newsmbios->dmi.tableLength);
	if (origsmbios) {
		smbiostables = (char *)origsmbios->dmi.tableAddress;
		origsmbiosnum = origsmbios->dmi.structureCount;
	} else {
		smbiostables = NULL;
		origsmbiosnum = 0;
	}
	tablesptr = smbiostables;
	newtablesptr = (char *)newsmbios->dmi.tableAddress;

        // if old smbios exists then update new smbios  with old smbios original content first
	if (smbiostables) {
		for (i=0; i<origsmbiosnum; i++) {
			struct smbios_table_header	*oldcur = (struct smbios_table_header *) tablesptr;
			struct smbios_table_header	*newcur = (struct smbios_table_header *) newtablesptr;
			char				*stringsptr;
			int				nstrings = 0;

			handles[(oldcur->handle) / 8] |= 1 << ((oldcur->handle) % 8);

                        // copy table length from old table to new table but not the old strings
			memcpy(newcur,oldcur, oldcur->length);

			tablesptr += oldcur->length;
			stringsptr = tablesptr;
			newtablesptr += oldcur->length;

                        // calculate the number of strings in the old content
			for (;tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++) {
				if (tablesptr[0] == 0) {
					nstrings++;
				}
			}
			if (tablesptr != stringsptr) {
				nstrings++;
			}
			tablesptr += 2;

                        // copy the old strings to new table
			memcpy(newtablesptr, stringsptr, tablesptr-stringsptr);

 			// point to next possible space for a string (deducting the second 0 char at the end)
			newtablesptr += tablesptr - stringsptr - 1;
                            if (nstrings == 0) { // if no string was found rewind to the first 0 char of the 0,0 terminator
				newtablesptr--;
			}

                        // now for each property in the table update the overrides if any (auto or user)
			for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
				const char	*str;
				int		size;
				int		num;
				char		altname[40];

				sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
				if (smbios_properties[j].table_type == newcur->type) {
					switch (smbios_properties[j].value_type) {
					case SMSTRING:
						if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
						    getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
						{
							memcpy(newtablesptr, str, size);
							newtablesptr[size] = 0;
							newtablesptr += size + 1;
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
						} else if (do_auto && smbios_properties[j].auto_str) {
							str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
							size = strlen(str);
							memcpy(newtablesptr, str, size);
							newtablesptr[size] = 0;
							newtablesptr += size + 1;
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
						}
						break;

					case SMOWORD:
						if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
						    getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
						{
							int		k=0, t=0, kk=0;
							const char	*ptr = str;
							memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
							while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
								ptr++;
							}
							if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
								ptr += 2;
							}
							for (;ptr-str<size && *ptr && k<16;ptr++) {
								if (*ptr>='0' && *ptr<='9') {
									(t=(t<<4)|(*ptr-'0')),kk++;
								}
								if (*ptr>='a' && *ptr<='f') {
									(t=(t<<4)|(*ptr-'a'+10)),kk++;
								}
								if (*ptr>='A' && *ptr<='F') {
									(t=(t<<4)|(*ptr-'A'+10)),kk++;
								}
								if (kk == 2) {
									*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
									k++;
									kk = 0;
									t = 0;
								}
							}
						}
						break;

					case SMBYTE:
						if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
						    getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
						{
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
						} else if (do_auto && smbios_properties[j].auto_int) {
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);							
						}
						break;

					case SMWORD:
						if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
						    getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
						{
							*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
						} else if (do_auto && smbios_properties[j].auto_int) {
							*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						}
						break;
					}
				}
			}
			if (nstrings == 0) {
				newtablesptr[0] = 0;
				newtablesptr++;
			}
			newtablesptr[0] = 0;
			newtablesptr++;
			tablespresent[newcur->type]++;
		}
	}

        // for each eventual complementary table not present in the original smbios, do the overrides
	for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
		int	numnec = -1;
		char	buffer[40];

		sprintf(buffer, "SMtable%d", i);
		if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {
			numnec = -1;
		}
		if (numnec == -1 && do_auto && smbios_table_descriptions[i].numfunc) {
			numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);
		}
		while (tablespresent[smbios_table_descriptions[i].type] < numnec) {
			struct smbios_table_header	*newcur = (struct smbios_table_header *) newtablesptr;
			int				nstrings = 0;

			memset(newcur,0, smbios_table_descriptions[i].len);
			while (handles[(nexthandle)/8] & (1 << ((nexthandle) % 8))) {
				nexthandle++;
			}
			newcur->handle = nexthandle;
			handles[nexthandle / 8] |= 1 << (nexthandle % 8);
			newcur->type = smbios_table_descriptions[i].type;
			newcur->length = smbios_table_descriptions[i].len;
			newtablesptr += smbios_table_descriptions[i].len;
			for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
				const char	*str;
				int		size;
				int		num;
				char		altname[40];

				sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
				if (smbios_properties[j].table_type == newcur->type) {
					switch (smbios_properties[j].value_type) {
					case SMSTRING:
						if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
						    getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
						{
							memcpy(newtablesptr, str, size);
							newtablesptr[size] = 0;
							newtablesptr += size + 1;
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
						} else if (do_auto && smbios_properties[j].auto_str) {
							str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
							size = strlen(str);
							memcpy(newtablesptr, str, size);
							newtablesptr[size] = 0;
							newtablesptr += size + 1;
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
						}
						break;

					case SMOWORD:
						if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
						    getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
						{
							int		k=0, t=0, kk=0;
							const char	*ptr = str;

							memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
							while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
								ptr++;
							}
							if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
								ptr += 2;
							}
							for (;ptr-str<size && *ptr && k<16;ptr++) {
								if (*ptr>='0' && *ptr<='9') {
									(t=(t<<4)|(*ptr-'0')),kk++;
								}
								if (*ptr>='a' && *ptr<='f') {
									(t=(t<<4)|(*ptr-'a'+10)),kk++;
								}
								if (*ptr>='A' && *ptr<='F') {
									(t=(t<<4)|(*ptr-'A'+10)),kk++;
								}
								if (kk == 2) {
									*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
									k++;
									kk = 0;
									t = 0;
								}
							}
						}
						break;
						
					case SMBYTE:
						if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
						    getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
						{
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
						} else if (do_auto && smbios_properties[j].auto_int) {
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						}
						break;
						
					case SMWORD:
						if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
						    getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
						{
							*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
						} else if (do_auto && smbios_properties[j].auto_int) {
							*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						}
						break;
					}
				}
			}
			if (nstrings == 0) {
				newtablesptr[0] = 0;
				newtablesptr++;
			}
			newtablesptr[0] = 0;
			newtablesptr++;
			tablespresent[smbios_table_descriptions[i].type]++;
		}
	}

        // calculate new checksums
	newsmbios->dmi.checksum = 0;
	newsmbios->dmi.checksum = 256 - checksum8(&newsmbios->dmi, sizeof(newsmbios->dmi));
	newsmbios->checksum = 0;
	newsmbios->checksum = 256 - checksum8(newsmbios, sizeof(*newsmbios));
	verbose("Patched DMI Table\n");
}
Beispiel #23
0
// Notify OS X that a ramdisk has been setup. XNU with attach this to /dev/md0
void md0Ramdisk()
{
	RAMDiskParam ramdiskPtr;
	char filename[512];
	const char* override_filename = 0;
	int fh = -1;
	int len;
	
	if(getValueForKey(kMD0Image, &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/%s", override_filename);
			fh = open(filename, 0);

			if(fh < 0)
			{
				sprintf(filename, "/Extra/%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, "/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);

	}
}
Beispiel #24
0
void setupSMBIOS(void)
{
    _SMBIOS_DEBUG_DUMP("Entering setupSMBIOS(static)\n");

    // Allocate 1 page of kernel memory (sufficient for a stripped SMBIOS table).
    void * kernelMemory = (void *)AllocateKernelMemory(4096);

    // Setup a new Entry Point Structure at the beginning of the newly allocated memory page.
    struct SMBEntryPoint * newEPS = (struct SMBEntryPoint *) kernelMemory;

    // Include additional/conditional code snippet.
#include "smbios/static_data.h"

    newEPS->anchor[0]			= 0x5f;		// _
    newEPS->anchor[1]			= 0x53;		// S
    newEPS->anchor[2]			= 0x4d;		// M
    newEPS->anchor[3]			= 0x5f;		// _
    newEPS->checksum			= 0;
    newEPS->entryPointLength	= 0x1f;		// sizeof(* newEPS)
    newEPS->majorVersion		= 2;
    newEPS->minorVersion		= 4;
    newEPS->maxStructureSize	= STATIC_SMBIOS_SM_MAX_STRUCTURE_SIZE;	// Defined in RevoBoot/i386/config/SMBIOS/data-template.h
    newEPS->entryPointRevision	= 0;

    newEPS->formattedArea[0]	= 0;
    newEPS->formattedArea[1]	= 0;
    newEPS->formattedArea[2]	= 0;
    newEPS->formattedArea[3]	= 0;
    newEPS->formattedArea[4]	= 0;

    newEPS->dmi.anchor[0]		= 0x5f;		// _
    newEPS->dmi.anchor[1]		= 0x44;		// D
    newEPS->dmi.anchor[2]		= 0x4d;		// M
    newEPS->dmi.anchor[3]		= 0x49;		// I
    newEPS->dmi.anchor[4]		= 0x5f;		// _
    newEPS->dmi.checksum		= 0;
    newEPS->dmi.tableLength		= tableLength;
    newEPS->dmi.tableAddress	= (uint32_t) (kernelMemory + sizeof(struct SMBEntryPoint));
    newEPS->dmi.bcdRevision		= 0x24;
    newEPS->dmi.structureCount	= STATIC_SMBIOS_DMI_STRUCTURE_COUNT;	// Defined in RevoBoot/i386/config/SMBIOS/[data-template/MacModelNN].h

    // Safety measure to protect people from doing something that breaks the boot process.
    // #define FORCED_CHECK ((STATIC_SMBIOS_DMI_STRUCTURE_COUNT == 0) || (SET_MAX_STRUCTURE_LENGTH && (STATIC_SMBIOS_SM_MAX_STRUCTURE_SIZE == 0)))
#define FORCED_CHECK	((STATIC_SMBIOS_DMI_STRUCTURE_COUNT == 0) || SET_MAX_STRUCTURE_LENGTH)

#if (LOAD_MODEL_SPECIFIC_SMBIOS_DATA || FORCED_CHECK)
    /*
     * Get number of SMBIOS table structures from the loaded model specific SMBIOS data, or
     * when we have 0 values in: RevoBoot/i386/config/SMBIOS/[data-template/MacModelNN].bin
     */
    if ((fileSize > 0) || FORCED_CHECK)
    {
        UInt16 structureCount = 0;

        char * structurePtr = (char *)newEPS->dmi.tableAddress;
        char * structureEnd = (structurePtr + newEPS->dmi.tableLength);

        while (structureEnd > (structurePtr + sizeof(SMBStructHeader)))
        {
            struct SMBStructHeader * header = (struct SMBStructHeader *) structurePtr;

#if SET_MAX_STRUCTURE_LENGTH
            char * stringsPtr = structurePtr;
#if DEBUG_SMBIOS
            SMBByte currentStructureType = header->type;
#endif
#endif
            // Skip the formatted area of the structure.
            structurePtr += header->length;

            /*
             * Skip the unformatted structure area at the end (strings).
             * Using word comparison instead of checking two bytes (thanks to Kabyl).
             */
            for (; ((uint16_t *)structurePtr)[0] != 0; structurePtr++);

            // Adjust pointer after locating the double 0 terminator.
            structurePtr += 2;

            // Update structure counter.
            structureCount++;

            _SMBIOS_DEBUG_DUMP("structureCount: %d\n", structureCount);

#if SET_MAX_STRUCTURE_LENGTH
            UInt16 maxStructureSize = (structurePtr - stringsPtr);

            if (newEPS->maxStructureSize < maxStructureSize)
            {
                newEPS->maxStructureSize = maxStructureSize;
            }

            _SMBIOS_DEBUG_DUMP("Structure (%d) length: %3d bytes.\n", currentStructureType, maxStructureSize);
            _SMBIOS_DEBUG_SLEEP(1);
#endif	// #if SET_MAX_STRUCTURE_LENGTH
        }
        // Uodate number of structures (boot hang without the correct value).
        newEPS->dmi.structureCount = structureCount;
    }
#endif	// #if (LOAD_MODEL_SPECIFIC_SMBIOS_DATA || FORCED_CHECK)
    /*
     * newEPS->dmi.tableLength represents the length of the static data, or the size
     * of the model specific SMBIOS data file from: /Extra/SMBIOS/MacModelNN.bin
     */
    _SMBIOS_DEBUG_DUMP("newEPS->dmi.structureCount: %d\nnewEPS.dmi.tableLength: %d\n", newEPS->dmi.structureCount, newEPS->dmi.tableLength);

    // Take care of possible checksum errors
    newEPS->dmi.checksum		= 256 - checksum8(&newEPS->dmi, sizeof(newEPS->dmi));
    newEPS->checksum			= 256 - checksum8(newEPS, sizeof(* newEPS));

    // Used to update the EFI Configuration Table (in efi.c) which is
    // what AppleSMBIOS.kext reads to setup the SMBIOS table for OS X.
    gPlatform.SMBIOS.BaseAddress = (uint32_t) newEPS;

    _SMBIOS_DEBUG_DUMP("New SMBIOS replacement setup.\n");
    _SMBIOS_DEBUG_SLEEP(5);
}